Compare commits
223
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f8765cf3e | ||
|
|
7342385729 | ||
|
|
671911dc1d | ||
|
|
2ec55c6469 | ||
|
|
d678b3a304 | ||
|
|
bf3bd50624 | ||
|
|
a4f69daae7 | ||
|
|
127ee5508a | ||
|
|
d71fbf8c06 | ||
|
|
aa3e72ec6d | ||
|
|
9d7f4929ad | ||
|
|
319f667028 | ||
|
|
bcab1a0a4d | ||
|
|
11ea7dcb3b | ||
|
|
1bff81c6bb | ||
|
|
2016a208f2 | ||
|
|
dfc1b65e4b | ||
|
|
f7629eb1be | ||
|
|
72fc28c1fa | ||
|
|
da70d07051 | ||
|
|
c6db7e6479 | ||
|
|
82ad40ac82 | ||
|
|
4fd9b2ecf5 | ||
|
|
2dccf73050 | ||
|
|
d6532c60a6 | ||
|
|
99be8651aa | ||
|
|
8ca53bd765 | ||
|
|
26e49f6161 | ||
|
|
cca027b5eb | ||
|
|
51f9c09132 | ||
|
|
897204ead3 | ||
|
|
25735df0c6 | ||
|
|
e3b6183e00 | ||
|
|
b2741ad567 | ||
|
|
7905e97a84 | ||
|
|
b7d719132d | ||
|
|
210e03cea0 | ||
|
|
995fc59299 | ||
|
|
cbd8236cb4 | ||
|
|
095086cdfd | ||
|
|
59846a041f | ||
|
|
7d91d9e28b | ||
|
|
752f59b09b | ||
|
|
262c4eee93 | ||
|
|
031a6fdf3c | ||
|
|
ff208710d7 | ||
|
|
29f1041cc3 | ||
|
|
a613bfb45a | ||
|
|
ed49fd41db | ||
|
|
625f9b588e | ||
|
|
6fa73dce49 | ||
|
|
e8892af8ba | ||
|
|
e413991e63 | ||
|
|
e909ddd78b | ||
|
|
2ed5015aee | ||
|
|
6e89be2ac5 | ||
|
|
50fb4f47fd | ||
|
|
22f1d035b7 | ||
|
|
f654310c4d | ||
|
|
d44f7497a5 | ||
|
|
dbccce445b | ||
|
|
6ed0818bad | ||
|
|
f2e3640e28 | ||
|
|
8bfffd540d | ||
|
|
559288fceb | ||
|
|
8886566a8f | ||
|
|
28cb2aeacd | ||
|
|
cbd82e29af | ||
|
|
50876e57b9 | ||
|
|
b70916de20 | ||
|
|
3202a4276d | ||
|
|
7a8caec159 | ||
|
|
7e7f1bb6ca | ||
|
|
5f12459bfd | ||
|
|
27e866ba08 | ||
|
|
f7a2b2af54 | ||
|
|
3f35176651 | ||
|
|
62c7e20726 | ||
|
|
ff08645087 | ||
|
|
3e947ca2df | ||
|
|
cc32206547 | ||
|
|
984a611d19 | ||
|
|
39011e2e33 | ||
|
|
4998fe4c94 | ||
|
|
247308b636 | ||
|
|
33110cf6c8 | ||
|
|
15c3fcb9b9 | ||
|
|
d5295f4f6c | ||
|
|
886e04710f | ||
|
|
d0e79ea99c | ||
|
|
a0568a44a6 | ||
|
|
4435a66255 | ||
|
|
dbc592b86b | ||
|
|
47a78edba8 | ||
|
|
f4fd836137 | ||
|
|
6c6823cf76 | ||
|
|
59187cc114 | ||
|
|
0ad9ef15af | ||
|
|
e23a185eaf | ||
|
|
36cbe4096d | ||
|
|
ab692f8033 | ||
|
|
15542154f4 | ||
|
|
7eb7fa1629 | ||
|
|
7906fce77f | ||
|
|
c57614e8df | ||
|
|
d5d6797f91 | ||
|
|
77545e9cf7 | ||
|
|
29ea54419c | ||
|
|
9042cb917a | ||
|
|
a65e1071a5 | ||
|
|
4493cca871 | ||
|
|
999dfb13b9 | ||
|
|
97f4008f4c | ||
|
|
6152144807 | ||
|
|
b376fe9ab0 | ||
|
|
aa3e097e16 | ||
|
|
d77aeeb46c | ||
|
|
82b7ab83dd | ||
|
|
88bc4e080d | ||
|
|
fa6aef1e86 | ||
|
|
57ed0e1e7d | ||
|
|
26077151ef | ||
|
|
55b05a2100 | ||
|
|
9210259511 | ||
|
|
e9a0914fad | ||
|
|
f392bee287 | ||
|
|
4281e87642 | ||
|
|
d40b766c83 | ||
|
|
d139db7697 | ||
|
|
7547d1db2e | ||
|
|
24d7ead1d1 | ||
|
|
e60dbb9f74 | ||
|
|
f12a96ce58 | ||
|
|
5920b92869 | ||
|
|
8f55d966f9 | ||
|
|
c7ef412d7a | ||
|
|
14f76ec10b | ||
|
|
d532d13371 | ||
|
|
58532d1ff6 | ||
|
|
b5fe314dde | ||
|
|
0d163e7100 | ||
|
|
5dda0b51c3 | ||
|
|
273aa7d01a | ||
|
|
cc1b6df8f2 | ||
|
|
97353bc7d2 | ||
|
|
10a703d657 | ||
|
|
b3077f6239 | ||
|
|
80ae5a1977 | ||
|
|
8579708f05 | ||
|
|
675ec40836 | ||
|
|
7b164e4df5 | ||
|
|
2be1b48995 | ||
|
|
be3b7c2e86 | ||
|
|
69bec42a66 | ||
|
|
12b879ced5 | ||
|
|
9e24cc655c | ||
|
|
95db80db5d | ||
|
|
ab7f2c42f5 | ||
|
|
be462811ac | ||
|
|
564b356115 | ||
|
|
bcacd42162 | ||
|
|
6f7fba5ae5 | ||
|
|
61d753b119 | ||
|
|
b482e871a3 | ||
|
|
bca602f4b0 | ||
|
|
f6222014b7 | ||
|
|
360e8ad2a0 | ||
|
|
e8bcfdd21d | ||
|
|
fd8dce8abe | ||
|
|
b9c14c76c9 | ||
|
|
bf60c52692 | ||
|
|
a8339c0169 | ||
|
|
d74f1bb6a8 | ||
|
|
9bb7224fc4 | ||
|
|
403290db32 | ||
|
|
98ae6b1105 | ||
|
|
2014825618 | ||
|
|
4a61bc88d3 | ||
|
|
fa4c0632ae | ||
|
|
ece16158ef | ||
|
|
bd27721685 | ||
|
|
7c8549d092 | ||
|
|
1e8c9d0187 | ||
|
|
faa59ab694 | ||
|
|
de4de0f5db | ||
|
|
48c1e326c8 | ||
|
|
22f54391d0 | ||
|
|
0bb3320010 | ||
|
|
7998bae87d | ||
|
|
ec929aef45 | ||
|
|
77e72bc3bf | ||
|
|
e1b00ce735 | ||
|
|
0fcb38f7e6 | ||
|
|
b3930b31f2 | ||
|
|
6222635eef | ||
|
|
dc7688bc13 | ||
|
|
c287cf16d1 | ||
|
|
ff114b3ab2 | ||
|
|
233966b73d | ||
|
|
45d4779b45 | ||
|
|
d608b5ea24 | ||
|
|
1ad750e2ef | ||
|
|
4d1af5e2b4 | ||
|
|
b515d688f4 | ||
|
|
ff92b307bb | ||
|
|
e4ffe0e267 | ||
|
|
2b121355c8 | ||
|
|
e7db938baa | ||
|
|
1b746d0f0a | ||
|
|
6886fc75de | ||
|
|
5c5f84a5b2 | ||
|
|
a12154523f | ||
|
|
6c8adf8594 | ||
|
|
a0f73e4e8d | ||
|
|
63efef65c7 | ||
|
|
dca09daf35 | ||
|
|
db833b441a | ||
|
|
bb55f3b3eb | ||
|
|
88e0660762 | ||
|
|
a8c172c77f | ||
|
|
b355da4aed | ||
|
|
77a4bf9c36 | ||
|
|
6a0f4372c6 |
No files matched your search
@@ -0,0 +1,2 @@
|
||||
* text=auto
|
||||
* text eol=lf
|
||||
@@ -1,27 +1,28 @@
|
||||
**(Please remove this line only before submitting your PR. Ensure that all relevant items are checked before submission.)**
|
||||
**(Please remove this line only before submitting your PR. Ensure that all relevant items are checked before submission.)**
|
||||
|
||||
## Describe your changes
|
||||
|
||||
Briefly describe the changes you made and their purpose.
|
||||
Briefly describe the changes you made and their purpose.
|
||||
|
||||
## Write your issue number after "Fixes "
|
||||
|
||||
Fixes #123
|
||||
Fixes #123
|
||||
|
||||
## Please ensure all items are checked off before requesting a review. "Checked off" means you need to add an "x" character between brackets so they turn into checkmarks.
|
||||
|
||||
- [ ] (Do not skip this or your PR will be closed) I deployed the application locally.
|
||||
- [ ] (Do not skip this or your PR will be closed) I have performed a self-review and testing of my code.
|
||||
- [ ] (Do not skip this or your PR will be closed) I have performed a self-reviewing and testing of my code.
|
||||
- [ ] I have included the issue # in the PR.
|
||||
- [ ] I have added i18n support to visible strings (instead of `<div>Add</div>`, use):
|
||||
- [ ] I have added i18n support to visible strings (instead of `<div>Add</div>`, use):
|
||||
|
||||
```Javascript
|
||||
const { t } = useTranslation();
|
||||
<div>{t('add')}</div>
|
||||
```
|
||||
|
||||
- [ ] I have **not** included any files that are not related to my pull request, including package-lock and package-json if dependencies have not changed
|
||||
- [ ] I didn't use any hardcoded values (otherwise it will not scale, and will make it difficult to maintain consistency across the application).
|
||||
- [ ] I made sure font sizes, color choices etc are all referenced from the theme. I don't have any hardcoded dimensions.
|
||||
- [ ] My PR is granular and targeted to one specific feature.
|
||||
- [ ] I ran `npm run format` in server and client directories, which automatically formats your code.
|
||||
- [ ] I took a screenshot or a video and attached to this PR if there is a UI change.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
name: Test Check (Server)
|
||||
on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test-server:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Install server dependencies
|
||||
working-directory: server
|
||||
run: npm install
|
||||
|
||||
- name: Run server tests
|
||||
working-directory: server
|
||||
run: npm test
|
||||
@@ -1,4 +1,22 @@
|
||||
# name: POEditor Translation Synchronization
|
||||
name: POEditor Translation Synchronization (disabled)
|
||||
|
||||
# This workflow is intentionally disabled — kept for reference only.
|
||||
# The full definition is preserved commented-out below. To re-enable,
|
||||
# delete the stub job and uncomment the section starting at `on:`.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
disabled:
|
||||
if: false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "This workflow is disabled. See comments below for the original definition."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Original (disabled) workflow below. Do not uncomment if you don't know what you're doing.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# on:
|
||||
# # For manual triggering
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Demo deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["demo"]
|
||||
branches: [ "demo" ]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
docker-build-and-push-client:
|
||||
@@ -84,7 +84,8 @@ jobs:
|
||||
script: |
|
||||
cd checkmate
|
||||
git pull
|
||||
cd docker/prod
|
||||
cd docker/unified
|
||||
docker compose down
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
docker system prune -af
|
||||
@@ -2,7 +2,7 @@ name: Staging deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["develop"]
|
||||
branches: [ "develop" ]
|
||||
|
||||
jobs:
|
||||
docker-build-and-push-client:
|
||||
@@ -78,13 +78,13 @@ jobs:
|
||||
- name: SSH into server and restart container using Docker Compose
|
||||
uses: appleboy/ssh-action@v1.2.2
|
||||
with:
|
||||
host: ${{ secrets.STAGING_SERVER_HOST }}
|
||||
username: ${{ secrets.STAGING_SERVER_USER }}
|
||||
key: ${{ secrets.STAGING_SERVER_SSH_KEY }}
|
||||
host: ${{ secrets.DEMO_SERVER_HOST }}
|
||||
username: ${{ secrets.DEMO_SERVER_USER }}
|
||||
key: ${{ secrets.DEMO_SERVER_SSH_KEY }}
|
||||
script: |
|
||||
cd checkmate
|
||||
git pull
|
||||
cd docker/staging
|
||||
cd docker/unified
|
||||
docker compose down
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
|
||||
+1
-3
@@ -3,10 +3,8 @@
|
||||
.VSCodeCounter
|
||||
*.sh
|
||||
mongo
|
||||
timescaledb
|
||||
node_modules/
|
||||
docs/architecture
|
||||
docs/reviews
|
||||
docs/todo
|
||||
docs/frontend
|
||||
docs/timescale
|
||||
docs/frontend
|
||||
@@ -105,6 +105,56 @@ client/src/
|
||||
- **Queue/Cache**: Redis + BullMQ + Pulse (cron scheduling)
|
||||
- **i18n**: i18next + react-i18next (translations via PoEditor)
|
||||
|
||||
---
|
||||
|
||||
## Backend Architecture Patterns
|
||||
|
||||
### Repository Pattern & Separation of Concerns
|
||||
|
||||
The backend enforces a strict three-layer separation between HTTP handling, business logic, and data access:
|
||||
|
||||
```
|
||||
Request → Controller → Service → Repository → MongoDB (Mongoose)
|
||||
```
|
||||
|
||||
- **Controllers** (`/controllers`) handle HTTP concerns only: parsing request params, calling the appropriate service, and returning a response via the `responseHandler` middleware. They contain no business logic.
|
||||
- **Services** (`/service/business`) contain all business logic: deciding whether an incident should be created, whether a notification should fire, what state a monitor is in, etc.
|
||||
- **Repositories** (`/repositories`) are the sole layer that talks to MongoDB through Mongoose. They expose clean, reusable query methods (e.g. `findByMonitorId`, `createCheck`) so that services never construct raw DB queries directly.
|
||||
|
||||
This separation makes each layer independently testable and keeps Mongoose-specific code out of business logic. When adding a new feature, the pattern to follow is: add a repository method for any new DB query, call it from a service, and expose it via a controller route.
|
||||
|
||||
### Monitoring Flow: From Check to Notification
|
||||
|
||||
Background monitoring runs on a scheduled queue, not on the HTTP request cycle. The high-level flow for uptime monitoring is:
|
||||
|
||||
```
|
||||
Pulse (cron) → BullMQ Job → StatusService
|
||||
├── performs HTTP/port/ping check
|
||||
├── saves Check via CheckRepository
|
||||
├── evaluates monitor state change
|
||||
│ └── calls IncidentService (create / resolve incident)
|
||||
└── calls NotificationService (email, Slack, Discord, webhook)
|
||||
```
|
||||
|
||||
1. **Pulse** (cron scheduler) enqueues a job into a **BullMQ** queue for each active monitor at its configured interval.
|
||||
2. A **BullMQ worker** picks up the job and calls `StatusService`, which performs the actual check (HTTP request, TCP port probe, ping, etc.).
|
||||
3. The result is persisted as a `Check` document via the repository layer.
|
||||
4. `StatusService` compares the new result against the monitor's previous state. If the monitor transitions from up → down (or down → up), it delegates to `IncidentService` to open or resolve an `Incident` document.
|
||||
5. On a state change, `NotificationService` reads the monitor's configured `Notification` documents and dispatches alerts to all enabled channels (email, Discord, Slack, webhooks).
|
||||
|
||||
### Queue System (BullMQ + Redis)
|
||||
|
||||
Redis serves two roles: job queue storage for BullMQ and ephemeral caching. BullMQ manages concurrency, retries, and backpressure for monitoring jobs, ensuring checks are processed reliably even under load.
|
||||
|
||||
- Each monitor type (HTTP, port, ping, infrastructure) maps to its own queue worker so failures in one type don't block others.
|
||||
- Job scheduling interval is driven by the `interval` field on the `Monitor` model.
|
||||
- Failed jobs are retried with configurable backoff before being moved to a dead-letter state.
|
||||
- Redis is also used to cache frequently read data (e.g. aggregated stats) to reduce MongoDB query pressure.
|
||||
|
||||
When working on anything related to check scheduling, incident lifecycle, or notifications, trace the flow starting from the relevant BullMQ worker rather than from the controller layer.
|
||||
|
||||
---
|
||||
|
||||
## Code Conventions
|
||||
|
||||
### Internationalization
|
||||
@@ -142,4 +192,4 @@ Key Mongoose models in `/server/src/db/models/`:
|
||||
- **StatusPage** - Public status pages
|
||||
- **Notification** - Alert configuration (email, Discord, Slack, webhooks)
|
||||
- **MaintenanceWindow** - Scheduled maintenance periods
|
||||
- **AppSettings** - Global application settings
|
||||
- **AppSettings** - Global application settings
|
||||
+69
-69
@@ -1,69 +1,69 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in the **bluewave-uptime** project and community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community, especially during Hacktoberfest, where we encourage new contributors to join and feel supported.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct, especially during Hacktoberfest to ensure a positive experience for all contributors.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when an individual is officially representing the project or its community in public spaces. Examples of representing our project include using an official project email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@bluewavelabs.ca. All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All project team members are obligated to respect the privacy and security of the reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Project maintainers will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
|
||||
**Consequence**: A private, written warning from project maintainers, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
**Community Impact**: A violation through a single incident or series of actions.
|
||||
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
|
||||
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
---
|
||||
|
||||
By following this Code of Conduct, we can ensure a welcoming and inclusive environment, encouraging new contributors to engage with the project and the community. Thank you for helping make **bluewave-uptime** a positive space for all!
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in the **checkmate** project and community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community, especially during Hacktoberfest, where we encourage new contributors to join and feel supported.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned with this Code of Conduct, especially during Hacktoberfest to ensure a positive experience for all contributors.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when an individual is officially representing the project or its community in public spaces. Examples of representing our project include using an official project email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@bluewavelabs.ca. All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All project team members are obligated to respect the privacy and security of the reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Project maintainers will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
|
||||
**Consequence**: A private, written warning from project maintainers, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
**Community Impact**: A violation through a single incident or series of actions.
|
||||
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
|
||||
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
---
|
||||
|
||||
By following this Code of Conduct, we can ensure a welcoming and inclusive environment, encouraging new contributors to engage with the project and the community. Thank you for helping make **checkmate** a positive space for all!
|
||||
+9
-3
@@ -16,7 +16,7 @@ PS: **We work closely with contributors on our [Discord channel](https://discord
|
||||
Before you dive in, make sure you have these installed:
|
||||
|
||||
```bash
|
||||
# Check Node.js (v16+ required)
|
||||
# Check Node.js (v20+ required)
|
||||
node --version
|
||||
|
||||
# Check npm
|
||||
@@ -96,10 +96,16 @@ cd docker/dev
|
||||
|
||||
Build the Docker images:
|
||||
|
||||
Linux:
|
||||
```bash
|
||||
./build_images.sh
|
||||
```
|
||||
|
||||
Windows:
|
||||
```bash
|
||||
./build_images.bat
|
||||
```
|
||||
|
||||
Run MongoDB container:
|
||||
|
||||
```bash
|
||||
@@ -234,7 +240,7 @@ docker rm uptime_database_mongo
|
||||
|
||||
**Need more help?**
|
||||
|
||||
- Check the [full documentation](https://docs.checkmate.so)
|
||||
- Check the [full documentation](https://checkmate.so/docs)
|
||||
- Ask on [Discord](https://discord.com/invite/NAb6H3UTjK)
|
||||
|
||||
### Start contributing code?
|
||||
@@ -310,7 +316,7 @@ If one or more of these are missing, we may ask you to update your pull request
|
||||
- `master` is used for stable releases.
|
||||
- Use descriptive branch names, like `fix/login-error` or `feat/add-alerts`.
|
||||
- Make sure that you are using the latest version.
|
||||
- Make sure you run the code locally. The Checkmate [documentation](https://docs.checkmate.so) covers it.
|
||||
- Make sure you run the code locally. The Checkmate [documentation](https://checkmate.so/docs) covers it.
|
||||
- Find out if the functionality is already covered, maybe by an individual configuration.
|
||||
- Perform a [search](/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
|
||||
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
|
||||
|
||||
+1
-1
@@ -33,4 +33,4 @@ Ensure you execute `npm run format` before submitting your pull requests in both
|
||||
|
||||
### Keep PRs focused
|
||||
|
||||
It may be tempting to address a bug you suddenly remembered or make some tiny adjustments in some component that bothers you, but don’t! Keep all commits in your pull request fully focused on the specific feature you are working on. Open up another PR if you want to fix a big or work on another feature.
|
||||
It may be tempting to address a bug you suddenly remembered or make some tiny adjustments in some component that bothers you, but don’t! Keep all commits in your pull request fully focused on the specific feature you are working on. Open up another PR if you want to fix a bug or work on another feature.
|
||||
+4
-4
@@ -49,11 +49,11 @@ Puedes ver la última versión de [Checkmate](https://checkmate-demo.bluewavelab
|
||||
|
||||
## Guía del usuario
|
||||
|
||||
Las instrucciones de uso se pueden encontrar [aquí](https://docs.checkmate.so/checkmate-2.1). Todavía está en desarrollo y parte de la información puede estar desactualizada ya que continuamente añadimos funciones cada semana. ¡Ten por seguro que estamos haciendo lo mejor posible! :)
|
||||
Las instrucciones de uso se pueden encontrar [aquí](https://checkmate.so/docs). Todavía está en desarrollo y parte de la información puede estar desactualizada ya que continuamente añadimos funciones cada semana. ¡Ten por seguro que estamos haciendo lo mejor posible! :)
|
||||
|
||||
## Instalación
|
||||
|
||||
Consulta las instrucciones de instalación en el [portal de documentación de Checkmate](https://docs.checkmate.so/checkmate-2.1/users-guide/quickstart).
|
||||
Consulta las instrucciones de instalación en el [portal de documentación de Checkmate](https://checkmate.so/docs/getting-started/installation).
|
||||
|
||||
Alternativamente, también puedes usar [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md) o [Pikapods](https://www.pikapods.com/) para desplegar rápidamente una instancia de Checkmate. Si deseas monitorear tu infraestructura de servidores, necesitarás el agente [Capture](https://github.com/bluewave-labs/capture). El repositorio de Capture también contiene las instrucciones de instalación.
|
||||
|
||||
@@ -76,7 +76,7 @@ También puedes ver el consumo de memoria de MongoDB y Redis en el mismo servido
|
||||
Si tienes alguna pregunta, sugerencia o comentario, tienes varias opciones:
|
||||
|
||||
- [Canal de Discord](https://discord.gg/NAb6H3UTjK)
|
||||
- [Discusiones en GitHub](https://github.com/bluewave-labs/bluewave-uptime/discussions)
|
||||
- [Discusiones en GitHub](https://github.com/bluewave-labs/checkmate/discussions)
|
||||
- [Grupo en Reddit](https://www.reddit.com/r/CheckmateMonitoring/)
|
||||
|
||||
¡No dudes en hacer preguntas o compartir tus ideas, nos encantaría saber de ti!
|
||||
@@ -147,7 +147,7 @@ Cómo contribuir:
|
||||
|
||||
0. Dale una estrella al repositorio :)
|
||||
1. Revisa la [guía para contribuidores](https://github.com/bluewave-labs/Checkmate/blob/develop/CONTRIBUTING.md). Se anima a los nuevos a revisar las etiquetas `good-first-issue`.
|
||||
2. Consulta la [estructura del proyecto](https://docs.checkmate.so/checkmate-2.1/developers-guide/general-project-structure) y la [visión general](https://bluewavelabs.gitbook.io/checkmate/developers-guide/high-level-overview).
|
||||
2. Consulta la [estructura del proyecto](https://deepwiki.com/bluewave-labs/Checkmate#system-architecture) y la [visión general](https://deepwiki.com/bluewave-labs/Checkmate#overview).
|
||||
3. Lee una estructura detallada de [Checkmate](https://deepwiki.com/bluewave-labs/Checkmate) si deseas profundizar en la arquitectura.
|
||||
4. Abre un issue si crees que has encontrado un error.
|
||||
5. Revisa los issues con la etiqueta `good-first-issue` si eres nuevo.
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
<p align="center"><strong>An open source uptime and infrastructure monitoring application</strong></p>
|
||||
|
||||
[](https://www.pikapods.com/pods?run=checkmate)
|
||||
|
||||
<img width="1660" alt="image" src="https://github.com/user-attachments/assets/b748f36d-a271-4965-ad0a-18bf153bbee7" />
|
||||
|
||||
This repository contains both the frontend and the backend of Checkmate, an open-source, self-hosted monitoring tool for tracking server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. Checkmate regularly checks whether a server/website is accessible and performs optimally, providing real-time alerts and reports on the monitored services' availability, downtime, and response time.
|
||||
@@ -41,7 +43,9 @@ Checkmate has been stress-tested with 1000+ active monitors without any particul
|
||||
|
||||
## Demo
|
||||
|
||||
You can see the latest build of [Checkmate](https://checkmate-demo.bluewavelabs.ca/) in action. The username is demouser@demo.com and the password is Demouser1! (just a note that we update the demo server from time to time, so if it doesn't work for you, please ping us on the Discussions channel).
|
||||
You can see the latest build of [Checkmate](https://demo.checkmate.so/) in action.
|
||||
|
||||
The username is demouser@demo.com and the password is Demouser1! (just a note that we update the demo server from time to time, so if it doesn't work for you, please ping us on the Discussions channel).
|
||||
|
||||
## User's guide
|
||||
|
||||
@@ -110,6 +114,15 @@ Feel free to ask questions or share your ideas - we'd love to hear from you!
|
||||
|
||||
If you would like to sponsor an additional feature, [see this page](https://checkmate.so/sponsored-features).
|
||||
|
||||
## Monitor Lifecycle
|
||||
|
||||
1. A monitor executes a check (HTTP / ping / port / hardware via Capture agent)
|
||||
2. The result is stored (success/failure + response time)
|
||||
3. Recent check results are evaluated against the monitor's configured status change threshold
|
||||
4. If the monitor's status change threshold is met and the current status is not equal to the previous status, the monitor's state changes (e.g. `initializing`, `up`, `down`, `breached`)
|
||||
5. Upon a state change: an incident is either created or resolved, depending on the monitor's current status
|
||||
6. Notifications are triggered based on configuration
|
||||
|
||||
## Screenshots
|
||||
|
||||
<p>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
Checkmate
|
||||
Copyright (c) BlueWave Labs
|
||||
|
||||
This product includes assets developed by third parties.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
King chess-piece silhouette used in the Checkmate logo
|
||||
(client/src/assets/icons/checkmate-icon.svg and
|
||||
client/public/checkmate_favicon.svg)
|
||||
is adapted from "Chess klt45.svg" by Cburnett, available at:
|
||||
https://commons.wikimedia.org/wiki/File:Chess_klt45.svg
|
||||
Licensed under Creative Commons Attribution-ShareAlike 3.0 Unported
|
||||
(CC BY-SA 3.0): https://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
The original artwork has been recolored from the white-with-black-stroke
|
||||
chess piece to the Checkmate brand green (#13715B) for use as a logo.
|
||||
Modifications: stroke color change only; geometry unchanged.
|
||||
Generated
+2
-7
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "client",
|
||||
"version": "0.0.0",
|
||||
"version": "3.6.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "client",
|
||||
"version": "0.0.0",
|
||||
"version": "3.6.1",
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.13.3",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
@@ -20,7 +20,6 @@
|
||||
"@types/maplibre-gl": "^1.13.2",
|
||||
"axios": "^1.7.4",
|
||||
"dayjs": "1.11.13",
|
||||
"flag-icons": "7.3.2",
|
||||
"html2canvas": "^1.4.1",
|
||||
"human-interval": "2.0.1",
|
||||
"i18next": "25.4.2",
|
||||
@@ -3891,10 +3890,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/flag-icons": {
|
||||
"version": "7.3.2",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/flat-cache": {
|
||||
"version": "3.2.0",
|
||||
"dev": true,
|
||||
|
||||
+1
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "client",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "3.6.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -28,7 +28,6 @@
|
||||
"@types/maplibre-gl": "^1.13.2",
|
||||
"axios": "^1.7.4",
|
||||
"dayjs": "1.11.13",
|
||||
"flag-icons": "7.3.2",
|
||||
"html2canvas": "^1.4.1",
|
||||
"human-interval": "2.0.1",
|
||||
"i18next": "25.4.2",
|
||||
|
||||
@@ -1,49 +1,11 @@
|
||||
<svg width="32" height="32" viewBox="0 0 600 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M218.252 79.2667L218.045 78.4143C218.712 77.617 219.642 77.5282 220.615 77.4361C224.829 77.0374 243.307 76.7077 246.676 77.418C248.299 77.76 249.661 78.5248 250.932 79.5734C254.845 82.8003 259.018 88.0302 262.403 91.9284C263.57 93.2734 264.805 95.1623 266.183 96.2584C268.203 99.7185 274.532 101.602 278.167 102.623C278.397 102.688 278.631 102.741 278.863 102.797C274.983 106.185 272.016 110.321 268.272 113.745C272.574 124.188 286.689 184.953 289.397 187.986C290.165 188.212 290.291 188.048 291.045 187.739C290.627 188.446 290.337 189.3 289.588 189.656L288.963 188.533C286.703 188.347 273.044 195.497 269.836 196.808C267.39 197.808 264.851 198.458 262.414 199.405C261.197 196.797 260.413 193.923 259.329 191.244C254.43 179.142 250.091 166.843 245.71 154.552C240.241 139.206 234.226 124.026 228.882 108.642C226.389 101.466 223.549 94.5009 220.953 87.3749C220.026 84.8301 219.72 81.4795 218.252 79.2667Z" fill="#3158B7"/>
|
||||
<path d="M218.252 79.2667L218.045 78.4143C218.712 77.617 219.642 77.5282 220.615 77.4361C224.829 77.0374 243.307 76.7077 246.676 77.418C248.299 77.76 249.661 78.5248 250.932 79.5734C254.845 82.8003 259.018 88.0302 262.403 91.9284C263.57 93.2734 264.805 95.1623 266.183 96.2584C268.203 99.7185 274.532 101.602 278.167 102.623C278.397 102.688 278.631 102.741 278.863 102.797C274.983 106.185 272.016 110.321 268.272 113.745C266.08 111.774 263.588 110.159 261.208 108.427C256.477 104.982 251.692 101.649 246.906 98.282L233.54 88.9767C228.729 85.5908 223.823 81.3267 218.252 79.2667Z" fill="#73E4FA"/>
|
||||
<path d="M299.595 19.4005C302.177 17.8183 305.226 16.8946 307.955 15.5556C310.387 14.3626 312.673 12.8604 315.15 11.7619C315.624 11.5519 315.886 11.4697 316.398 11.4844C315.732 13.7848 316.431 26.6622 316.441 30.2652C316.474 42.2192 316.084 54.2432 316.385 66.1867C316.416 67.4343 316.377 68.6301 316.847 69.8026C316.457 79.0631 316.718 88.4086 316.651 97.6808L316.423 172.062C316.376 177.75 316.385 183.438 316.448 189.125C316.469 192.585 316.902 196.888 316.126 200.243C316.055 199.033 315.728 197.334 316.025 196.183C315.86 197.435 315.463 198.762 315.391 200.002C315.283 201.847 315.798 203.719 315.391 205.559C314.431 204.554 313.43 203.906 312.592 202.729C308.228 196.602 310.556 194.07 301.963 190.683C299.704 189.793 293.054 186.88 291.045 187.739C290.291 188.048 290.165 188.212 289.397 187.986C286.689 184.953 272.574 124.188 268.272 113.745C272.016 110.321 274.983 106.185 278.863 102.797C278.631 102.741 278.397 102.688 278.167 102.623C274.532 101.602 268.203 99.7184 266.183 96.2583C269.435 97.3504 272.901 97.5882 276.304 97.6583C280.306 97.7408 283.403 97.3026 286.383 94.3544C288.086 92.669 289.516 90.6569 291.136 88.8839C293.303 86.512 296.041 84.1801 297.633 81.3777C300.012 77.1924 299.115 62.4967 299.219 57.0841C296.538 56.7086 293.912 56.806 291.218 56.6995C288.184 56.5796 285.396 56.0507 283.294 53.6585C280.886 50.9188 280.696 47.3466 281.035 43.8756C282.423 29.6657 295.122 37.239 298.804 33.8184C299.712 32.9739 299.469 21.618 299.595 19.4005Z" fill="#3D7ECD"/>
|
||||
<path d="M362.288 269.421L362.773 270.062C364.332 274.37 365.193 279.073 366.359 283.516C368.419 291.371 370.61 299.194 372.793 307.015L395.769 388.039L411.304 442.863L415.766 458.213C416.528 460.836 417.569 463.467 417.96 466.175C417.89 466.842 418.03 466.869 417.485 467.324C413.349 466.406 409.11 465.92 404.942 465.147C396.892 463.653 388.881 461.984 380.817 460.552C380.516 459.221 380.489 457.712 380.305 456.347C379.896 453.327 379.359 450.33 378.694 447.356C376.712 438.738 374.16 430.227 372.075 421.626L351.327 334.35C349.071 324.725 347.019 314.981 344.607 305.405C342.561 297.284 340.078 289.201 338.622 280.946C339.912 280.649 340.991 280.35 342.142 279.684C345.072 278.136 348.264 277.064 351.221 275.536C354.9 273.636 358.345 270.649 362.288 269.421Z" fill="#73E4FA"/>
|
||||
<path d="M316.398 11.4845C316.949 11.6168 317.496 11.7682 318.021 11.982C320.527 13.0022 322.595 14.8975 325.025 16.0401C326.641 16.7993 328.506 17.0278 330.066 17.9189C330.615 18.2326 331.175 18.6401 331.516 19.1833C333.638 22.5617 329.941 33.143 334.144 34.5595C335.071 34.872 336.309 34.7269 337.278 34.6636C342.517 34.3216 346.04 34.3235 349.065 39.1827C350.891 42.117 351.841 45.3207 350.982 48.7564C350.164 52.0314 347.831 55.4635 344.902 57.2399C344.309 57.5993 343.657 57.8308 343.003 58.0488C342.382 58.2541 341.729 58.4831 341.176 58.8402C339.34 60.0257 337.705 61.6472 335.85 62.8819C335.083 63.3916 333.536 63.9343 333.114 64.7163C333.015 64.8989 332.938 65.0921 332.849 65.2797C331.994 71.778 330.942 74.7954 335.242 80.4525C338.105 84.2196 345.676 93.407 349.248 96.0711C350.329 96.8768 351.548 97.3899 352.858 97.674C354.638 97.679 356.567 97.8353 358.319 97.4932C366.986 95.8002 372.945 85.6789 379.155 80.1412C380.557 78.8916 382.117 77.8947 383.974 77.4926C387.385 76.754 391.296 77.2429 394.773 77.2627C400.744 77.2966 406.631 77.1509 412.603 77.4939C413.066 77.8038 413.08 77.6663 413.16 78.1487C413.385 79.5036 412.832 81.0938 412.41 82.377C409.805 90.2864 406.49 98.1119 403.607 105.936L387.525 150.29C383.617 161.269 379.569 172.195 375.381 183.07C373.017 189.241 370.826 195.663 367.756 201.518C366.906 200.846 366.105 200.384 365.115 199.946C357.118 196.547 349.468 191.947 341.757 187.926C341.211 187.423 341.102 187.207 340.301 187.318C338.422 187.579 336.346 188.419 334.502 188.929C330.434 190.055 321.796 191.764 319.469 195.652C318.572 197.151 317.692 200.22 316.337 201.245C316.225 200.886 316.145 200.621 316.126 200.243C316.902 196.888 316.469 192.585 316.448 189.125C316.385 183.438 316.377 177.75 316.423 172.062L316.651 97.6809C316.718 88.4087 316.457 79.0632 316.847 69.8027C316.377 68.6302 316.416 67.4344 316.385 66.1868C316.084 54.2433 316.474 42.2193 316.441 30.2653C316.431 26.6623 315.732 13.7849 316.398 11.4845Z" fill="#73E4FA"/>
|
||||
<path d="M332.127 57.4141C335.751 57.5106 339.378 57.8905 343.003 58.0488C342.382 58.2541 341.729 58.4831 341.176 58.8402C339.34 60.0257 337.705 61.6472 335.85 62.8819C335.083 63.3916 333.536 63.9343 333.114 64.7163C333.015 64.8989 332.938 65.0921 332.849 65.2797C332.684 62.6459 332.422 60.0356 332.127 57.4141Z" fill="black"/>
|
||||
<path d="M352.858 97.674C354.638 97.679 356.567 97.8353 358.319 97.4932C366.986 95.8002 372.945 85.6789 379.155 80.1412C380.557 78.8916 382.117 77.8947 383.974 77.4926C387.385 76.754 391.296 77.2429 394.773 77.2627C400.744 77.2966 406.631 77.1509 412.603 77.4939C412.123 77.5931 411.776 77.6589 411.35 77.9133C409.284 79.1482 407.188 81.3404 405.081 82.7802C394.559 89.9716 384.283 97.4873 373.787 104.715C371.042 106.605 368.398 108.696 365.587 110.481C363.016 106.042 360.879 102.667 356.684 99.576C355.908 99.004 354.963 98.1848 354.042 97.8844C353.777 97.7979 353.467 97.7915 353.199 97.7482C353.084 97.7297 352.972 97.6988 352.858 97.674Z" fill="#4F91E0"/>
|
||||
<path d="M316.847 69.8027C321.242 72.4105 326.84 79.7356 330.518 83.5726C335.063 88.3145 340.305 92.4625 345.078 96.9857C348.754 100.47 359.102 112.197 362.531 113.979C362.884 116.416 347.596 173.131 345.411 179.979C344.657 182.345 343.764 185.35 342.254 187.338C342.099 187.543 341.927 187.734 341.757 187.926C341.211 187.423 341.102 187.207 340.301 187.318C338.422 187.579 336.346 188.419 334.502 188.929C330.434 190.055 321.796 191.764 319.469 195.652C318.572 197.151 317.692 200.22 316.337 201.245C316.225 200.886 316.145 200.621 316.126 200.243C316.902 196.888 316.469 192.585 316.448 189.125C316.385 183.438 316.376 177.75 316.423 172.062L316.651 97.6809C316.718 88.4087 316.457 79.0632 316.847 69.8027Z" fill="#5BBFFC"/>
|
||||
<path d="M316.126 200.243C316.145 200.621 316.225 200.886 316.337 201.245C317.692 200.22 318.572 197.151 319.469 195.652C321.796 191.764 330.434 190.055 334.502 188.929C336.346 188.419 338.422 187.579 340.301 187.318C341.102 187.207 341.211 187.423 341.757 187.926C349.468 191.947 357.118 196.547 365.115 199.946C366.105 200.384 366.906 200.846 367.756 201.518C367.27 202.637 366.763 203.747 366.234 204.848C365.063 207.595 364.344 210.137 363.459 212.952C367.613 213.364 371.797 213.297 375.966 213.194C386.171 213.341 399.134 211.56 407.006 219.438C408.262 220.694 409.583 222.077 410.315 223.707C411.447 228.7 410.939 234.09 410.692 239.173C410.661 239.285 410.628 239.397 410.599 239.511C410.317 240.612 410.264 241.816 409.76 242.846C408.269 245.89 403.918 248.67 401.099 250.509L397.101 250.535C392.229 251.156 386.936 250.764 382.02 250.742C380.258 252.242 379.572 253.4 379.015 255.621C375.623 257.067 372.349 258.186 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663L305.359 267.78C304.526 268.174 303.726 268.445 302.836 268.679L302.422 268.516C302.97 267.994 303.581 267.707 304.249 267.371C303.346 267.089 302.592 267.405 301.795 267.828C300.798 268.358 299.724 269.109 298.638 269.418C296.45 270.04 293.748 268.782 292.771 271.723C291.539 275.429 292.836 276.598 289.342 279.245L289.264 279.106L289.746 279.665C289.922 279.642 290.098 279.617 290.274 279.596C290.788 279.534 291.072 279.562 291.552 279.784C283.761 280.886 276.08 271.943 269.481 268.727C269.532 267.685 269.414 267.036 268.848 266.155C266.793 262.951 261.551 259.21 258.011 257.869C256.773 257.4 255.382 257.17 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742C234.444 250.731 231.884 250.523 229.351 250.403C226.903 249.086 224.175 246.485 222.644 244.15C220.166 240.368 220.112 229.455 221.195 225.05C221.962 221.93 223.946 219.508 226.648 217.845C227.525 217.021 228.391 216.267 229.547 215.874C232.606 214.832 236.233 214.827 239.433 214.547C243.327 214.206 247.238 213.733 251.141 213.538C256.502 213.269 261.883 213.36 267.25 213.257C267.293 213.167 267.345 213.08 267.378 212.986C268.103 210.948 263.421 201.839 262.414 199.405C264.851 198.458 267.39 197.808 269.836 196.808C273.044 195.497 286.703 188.347 288.963 188.533L289.588 189.656C290.337 189.3 290.627 188.446 291.045 187.739C293.054 186.88 299.704 189.793 301.963 190.683C310.556 194.07 308.228 196.602 312.592 202.729C313.43 203.906 314.431 204.554 315.391 205.559C315.798 203.719 315.283 201.847 315.391 200.002C315.463 198.762 315.86 197.435 316.025 196.183C315.728 197.334 316.055 199.033 316.126 200.243Z" fill="#73E4FA"/>
|
||||
<path d="M226.648 217.845C227.525 217.021 228.391 216.267 229.547 215.874C232.606 214.832 236.233 214.827 239.433 214.547C243.327 214.206 247.238 213.733 251.141 213.538C256.502 213.269 261.883 213.36 267.25 213.257C273.5 213.971 279.834 213.445 286.108 213.605C286.028 213.626 285.948 213.648 285.867 213.666C283.762 214.153 281.367 213.997 279.208 214.037C272.251 214.165 265.326 213.83 258.375 213.88C253.031 213.919 247.886 214.67 242.578 215.017C240.895 215.127 236.024 214.805 235.01 216.105C234.814 216.356 234.778 216.499 234.672 216.773C235.26 217.358 235.736 217.319 236.534 217.341C240.179 217.439 243.921 217.212 247.585 217.238C254.057 217.283 260.516 217.54 266.99 217.551C270.978 217.557 278.548 217.235 282.283 217.919C273.611 218.558 264.721 217.948 256.023 218.03C249.71 217.873 243.396 217.847 237.081 217.954C233.732 217.991 229.946 218.398 226.648 217.845Z" fill="#4F91E0"/>
|
||||
<path d="M321 196.5C321.019 196.878 320.86 194.141 320.972 194.5C322.327 193.475 318.572 197.151 319.469 195.652C321.796 191.764 330.434 190.055 334.502 188.929C336.346 188.419 338.422 187.579 340.301 187.318C341.102 187.207 341.211 187.423 341.757 187.926C349.468 191.947 357.118 196.547 365.115 199.946C366.105 200.384 366.906 200.846 367.756 201.518C367.27 202.637 366.763 203.747 366.234 204.848C365.063 207.595 364.344 210.137 363.459 212.952L361.76 212.951C346.809 213.807 331.759 213.014 316.787 213.074L315.391 205.559C315.798 203.719 315.283 201.847 315.391 200.002C315.463 198.762 315.835 196.752 316 195.5C315.5 195 323.374 191.757 321 196.5Z" fill="#3158B7"/>
|
||||
<path d="M291.045 187.739C293.054 186.88 299.704 189.793 301.963 190.683C310.556 194.07 305.5 191.5 312.5 194.5C314 195 315.54 193.995 316.5 195L316.787 213.074C306.586 212.996 296.304 213.296 286.108 213.605C279.834 213.445 273.5 213.971 267.25 213.257C267.293 213.167 267.345 213.08 267.378 212.986C268.103 210.948 263.421 201.839 262.414 199.405C264.851 198.458 267.39 197.808 269.836 196.808C273.044 195.497 286.703 188.347 288.963 188.533L289.5 188.5C290.249 188.144 290.627 188.446 291.045 187.739Z" fill="#15337C"/>
|
||||
<path d="M316.158 217.961C333.626 218.066 351.372 216.648 368.745 218.663C369.093 229.235 368.662 239.88 368.76 250.467L387.46 250.44C390.609 250.437 393.982 250.193 397.101 250.535C392.229 251.156 386.936 250.764 382.02 250.742L316.217 250.777C316.034 247.101 316.2 243.334 316.205 239.649C316.23 232.42 316.215 225.19 316.158 217.961Z" fill="#5BBFFC"/>
|
||||
<path d="M229.351 250.403C226.903 249.086 224.175 246.485 222.644 244.15C220.166 240.368 220.112 229.455 221.195 225.05C221.962 221.93 223.946 219.508 226.648 217.845C229.946 218.398 233.732 217.991 237.081 217.954C243.396 217.847 249.71 217.873 256.023 218.03C264.721 217.948 273.611 218.558 282.283 217.919L316.158 217.961C316.215 225.19 316.23 232.42 316.205 239.649C316.2 243.334 316.034 247.101 316.217 250.777L382.02 250.742C380.258 252.242 379.572 253.4 379.015 255.621C375.623 257.067 372.349 258.186 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663L305.359 267.78C304.526 268.174 303.726 268.445 302.836 268.679L302.422 268.516C302.97 267.994 303.581 267.707 304.249 267.371C303.346 267.089 302.592 267.405 301.795 267.828C300.798 268.358 299.724 269.109 298.638 269.418C296.45 270.04 293.748 268.782 292.771 271.723C291.539 275.429 292.836 276.598 289.342 279.245L289.264 279.106L289.746 279.665C289.922 279.642 290.098 279.617 290.274 279.596C290.788 279.534 291.072 279.562 291.552 279.784C283.761 280.886 276.08 271.943 269.481 268.727C269.532 267.685 269.414 267.036 268.848 266.155C266.793 262.951 261.551 259.21 258.011 257.869C256.773 257.4 255.382 257.17 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742C234.444 250.731 231.884 250.523 229.351 250.403Z" fill="#3D7ECD"/>
|
||||
<path d="M229.5 250.5C227.052 249.183 224.175 246.485 222.644 244.15C220.166 240.368 220.112 229.455 221.195 225.05C221.962 221.93 223.946 219.508 226.648 217.845C229.946 218.398 233.732 217.991 237.081 217.954C243.396 217.847 249.71 217.873 256.023 218.03C258.057 218.243 260.081 218.239 262.124 218.245C262.036 228.982 261.779 239.713 261.935 250.452C267.117 250.445 282.096 249.873 286.095 250.724C281.121 250.989 276.017 250.759 271.029 250.75C261.584 250.723 252.14 250.748 242.696 250.824C240.816 250.676 238.867 250.759 236.978 250.742C234.444 250.731 232.033 250.62 229.5 250.5Z" fill="#3158B7"/>
|
||||
<path d="M242.696 250.824C252.14 250.748 261.584 250.723 271.029 250.75C276.017 250.759 281.121 250.989 286.095 250.724C296.126 250.796 306.188 250.976 316.217 250.777L382.02 250.742C380.258 252.242 379.572 253.4 379.015 255.621C375.623 257.067 372.349 258.186 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663L305.359 267.78C304.526 268.174 303.726 268.445 302.836 268.679L302.422 268.516C302.97 267.994 303.581 267.707 304.249 267.371C303.346 267.089 302.592 267.405 301.795 267.828C300.798 268.358 299.724 269.109 298.638 269.418C296.45 270.04 293.748 268.782 292.771 271.723C291.539 275.429 292.836 276.598 289.342 279.245L289.264 279.106L289.746 279.665C289.922 279.642 290.098 279.617 290.274 279.596C290.788 279.534 291.072 279.562 291.552 279.784C283.761 280.886 276.08 271.943 269.481 268.727C269.532 267.685 269.414 267.036 268.848 266.155C266.793 262.951 261.551 259.21 258.011 257.869C256.773 257.4 255.382 257.17 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742C238.867 250.759 240.816 250.676 242.696 250.824Z" fill="url(#paint0_linear_4222_6997)"/>
|
||||
<path d="M236.978 250.742C238.867 250.759 240.816 250.676 242.696 250.824C242.881 250.874 243.066 250.928 243.252 250.974C245.298 251.479 247.92 251.212 250.051 251.224C248.443 251.53 247.073 251.291 245.943 252.702C245.85 253.55 245.913 253.633 246.31 254.399C248.336 255.702 252.778 255.161 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742Z" fill="#15337C"/>
|
||||
<path d="M315.839 263.948C315.537 262.501 315.708 261.013 315.229 259.629C314.46 258.966 313.976 259.049 312.984 258.933C313.102 258.884 313.213 258.814 313.338 258.787C315.769 258.246 325.519 258.983 328.801 258.983L357.499 259.017C359.803 259.006 366.156 258.505 368.097 258.96C368.485 259.051 368.546 259.119 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663C307.941 265.704 312.848 264.583 315.839 263.948Z" fill="url(#paint1_linear_4222_6997)"/>
|
||||
<path d="M334.406 268.36C340.718 267.927 347.148 267.514 353.456 268.191C355.699 268.431 360.368 269.793 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965C338.013 279.917 337.843 278.75 337.605 277.665C336.155 274.684 336.233 271.392 334.406 268.36Z" fill="#4F91E0"/>
|
||||
<path d="M337.605 277.665C338.101 277.244 338.105 277.263 338.759 277.253C340.026 277.925 341.077 278.732 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965C338.013 279.917 337.843 278.75 337.605 277.665Z" fill="#5BBFFC"/>
|
||||
<path d="M162.994 506.672C163.51 506.136 164.063 505.686 164.643 505.225C167.325 506.032 178.659 505.485 182.142 505.49L221.176 505.555C226.755 505.582 232.376 505.443 237.949 505.628C269.102 506.183 300.329 505.731 331.491 505.742L372.011 505.764C380.199 505.77 388.457 505.962 396.635 505.618C396.442 517.711 396.022 529.884 396.433 541.975C409.395 542.082 422.357 542.091 435.32 542.002C441.062 542.005 447.41 541.469 453.076 542.23C457.801 542.254 462.724 542.135 467.419 542.679C465.179 543.78 463.234 548.572 462.043 550.796V551.298L462.794 551.648C454.827 551.784 446.872 552.172 438.929 552.813C436.511 552.995 434.06 552.553 431.644 552.413C428.22 552.214 424.779 552.237 421.352 552.25C402.933 552.322 384.531 552.526 366.11 552.346L227.563 552.274C215.642 552.277 203.672 552.344 191.757 552.13C182.178 551.958 172.491 551.389 162.923 551.866C164.053 549.046 163.345 544.905 162.658 542.024C162.018 536.512 162.277 530.737 162.288 525.186C162.299 519.081 161.931 512.699 162.994 506.672Z" fill="#15337C"/>
|
||||
<path d="M162.994 506.672C163.51 506.136 164.063 505.686 164.643 505.225C167.325 506.032 178.659 505.485 182.142 505.49L221.176 505.555C226.755 505.582 232.376 505.443 237.949 505.628C237.694 517.722 237.219 529.932 237.571 542.021L396.433 541.975C409.395 542.082 422.357 542.091 435.32 542.002C441.062 542.005 447.41 541.469 453.076 542.23C445.432 542.447 437.752 542.287 430.104 542.288L384.066 542.238L236.646 542.27L181.968 542.237C175.536 542.231 169.083 541.914 162.658 542.024C162.018 536.512 162.277 530.737 162.288 525.186C162.299 519.081 161.931 512.699 162.994 506.672Z" fill="#3158B7"/>
|
||||
<path d="M237.949 505.628C269.102 506.183 300.329 505.731 331.491 505.742L372.011 505.764C380.199 505.77 388.457 505.962 396.635 505.618C396.442 517.711 396.022 529.884 396.433 541.975L237.571 542.021C237.219 529.932 237.694 517.722 237.949 505.628Z" fill="#3D7ECD"/>
|
||||
<path d="M316.173 450.214L316.356 450.171C327.599 451.012 338.68 453.515 349.747 455.526C360.085 457.318 370.442 458.993 380.817 460.552C388.881 461.984 396.892 463.653 404.942 465.147C409.11 465.92 413.349 466.406 417.485 467.324C418.03 466.869 417.89 466.842 417.96 466.175C418.868 471.139 419.01 474.417 418.882 479.505C424.212 480.991 428.904 484.71 433.752 487.295L467.07 504.914C467.988 505.502 468.749 505.944 468.955 507.111C469.514 510.282 469.469 539.486 468.739 541.824C468.292 542.267 468.021 542.487 467.419 542.679C462.724 542.135 457.801 542.254 453.076 542.23C447.41 541.469 441.062 542.005 435.32 542.002C422.357 542.091 409.395 542.082 396.433 541.975C396.022 529.884 396.442 517.711 396.635 505.618C388.457 505.962 380.199 505.77 372.011 505.764L331.491 505.742C300.329 505.731 269.102 506.183 237.949 505.628C232.376 505.443 226.755 505.582 221.176 505.555L182.142 505.49C178.659 505.485 167.325 506.032 164.643 505.225C166.684 503.613 169.31 502.543 171.632 501.378C176.276 499.048 181.007 496.831 185.604 494.419C192.121 490.999 198.566 487.372 204.999 483.795C207.005 482.679 208.919 481.328 210.961 480.297C211.664 479.943 212.437 479.729 213.192 479.519C213.447 477.939 213.28 476.121 213.292 474.511C213.314 471.755 213.495 469.182 213.961 466.462C214.147 466.81 214.01 466.597 214.452 467.044C227.245 465.759 239.827 462.451 252.483 460.143C260.461 458.819 268.511 457.946 276.475 456.519L300.283 452.407C305.401 451.522 310.98 450.069 316.173 450.214Z" fill="#73E4FA"/>
|
||||
<path d="M316.173 450.214L316.356 450.171C327.599 451.012 338.68 453.515 349.747 455.526C360.085 457.318 370.442 458.993 380.817 460.552C388.881 461.984 396.892 463.653 404.942 465.147C409.11 465.92 413.349 466.406 417.485 467.324C418.03 466.869 417.89 466.842 417.96 466.175C418.868 471.139 419.01 474.417 418.882 479.505C407.542 478.716 395.89 479.365 384.514 479.436C370.443 479.525 356.374 479.202 342.302 479.225L326.141 479.166C322.94 479.164 319.619 479.396 316.441 479.069C316.286 469.43 316.022 459.862 316.173 450.214Z" fill="#3D7ECD"/>
|
||||
<path d="M467.07 504.914C467.988 505.502 468.749 505.944 468.955 507.111C469.514 510.282 469.469 539.486 468.739 541.824C468.292 542.267 468.021 542.487 467.419 542.679C462.724 542.135 457.801 542.254 453.076 542.23C447.41 541.469 441.062 542.005 435.32 542.002C422.357 542.091 409.395 542.082 396.433 541.975C396.022 529.884 396.442 517.711 396.635 505.618C399.774 505.933 403.063 505.785 406.221 505.786L422.299 505.784C435.31 505.785 448.476 506.228 461.464 505.68C463.339 505.6 465.314 505.634 467.07 504.914Z" fill="#5BBFFC"/>
|
||||
<path d="M252.483 460.143C260.461 458.819 268.511 457.946 276.475 456.519L300.283 452.407C305.401 451.522 310.98 450.069 316.173 450.214C316.022 459.862 316.286 469.43 316.441 479.069C313.41 479.108 310.372 479.425 307.371 479.847C292.468 483.6 277.556 488.899 263.025 493.906C257.708 495.738 251.924 497.128 246.801 499.408C243.673 500.8 240.545 502.657 238.239 505.216L351.838 505.253L382.181 505.431C386.77 505.429 392.191 504.724 396.635 505.618C388.457 505.962 380.199 505.77 372.011 505.764L331.491 505.742C300.329 505.731 269.102 506.183 237.949 505.628C232.376 505.443 226.755 505.582 221.176 505.555L182.142 505.49C178.659 505.485 167.325 506.032 164.643 505.225C166.684 503.613 169.31 502.543 171.632 501.378C176.276 499.048 181.007 496.831 185.604 494.419C192.121 490.999 198.566 487.372 204.999 483.795C207.005 482.679 208.919 481.328 210.961 480.297C211.664 479.943 212.437 479.729 213.192 479.519C213.447 477.939 213.28 476.121 213.292 474.511C213.314 471.755 213.495 469.182 213.961 466.462C214.147 466.81 214.01 466.597 214.452 467.044C227.245 465.759 239.827 462.451 252.483 460.143Z" fill="url(#paint2_linear_4222_6997)"/>
|
||||
<path d="M252.483 460.143C260.461 458.819 268.511 457.946 276.475 456.519L300.283 452.407C305.401 451.522 310.98 450.069 316.173 450.214C316.022 459.862 316.286 469.43 316.441 479.069C313.41 479.108 310.372 479.425 307.371 479.847C280.73 478.905 253.933 479.206 227.271 479.298C222.578 479.314 217.879 479.538 213.192 479.519C213.447 477.939 213.28 476.121 213.292 474.511C213.314 471.755 213.495 469.182 213.961 466.462C214.147 466.81 214.01 466.597 214.452 467.044C227.245 465.759 239.827 462.451 252.483 460.143Z" fill="#15337C"/>
|
||||
<path d="M305.601 267.663C308.244 267.144 310.643 265.828 313.234 265.15C314 264.949 314.562 264.951 315.272 265.334C316.559 267.352 315.076 269.916 315.579 272.213C316.083 270.149 314.993 265.535 316.192 264.037L316.638 264.129C322.458 264.909 327.237 267.42 330.826 272.131C332.112 273.818 335.013 279.586 335.64 280.22C336.122 280.707 336.996 280.978 337.631 281.175L338.374 280.965L338.622 280.946C340.078 289.201 342.561 297.284 344.607 305.405C347.019 314.981 349.071 324.725 351.327 334.35L372.075 421.626C374.16 430.227 376.712 438.738 378.694 447.356C379.359 450.33 379.896 453.327 380.305 456.347C380.489 457.712 380.516 459.221 380.817 460.552C370.442 458.993 360.085 457.318 349.747 455.526C338.68 453.515 327.599 451.012 316.356 450.171L316.173 450.214C310.98 450.069 305.401 451.522 300.283 452.407L276.475 456.519C268.511 457.946 260.461 458.819 252.483 460.143C239.827 462.451 227.245 465.759 214.452 467.044C214.01 466.597 214.147 466.81 213.961 466.462C217.335 455.731 219.76 444.734 222.73 433.889L237.945 379.405L269.481 268.727C276.08 271.943 283.761 280.886 291.552 279.784C291.072 279.562 290.788 279.534 290.274 279.596C290.098 279.617 289.922 279.642 289.746 279.665L289.264 279.106L289.342 279.245C292.836 276.598 291.539 275.429 292.771 271.723C293.748 268.782 296.45 270.04 298.638 269.418C299.724 269.109 300.798 268.358 301.795 267.828C302.592 267.405 303.346 267.089 304.249 267.371C303.581 267.707 302.97 267.994 302.422 268.516L302.836 268.679C303.726 268.445 304.526 268.174 305.359 267.78L305.601 267.663Z" fill="#3D7ECD"/>
|
||||
<path d="M213.961 466.462C217.335 455.731 219.76 444.734 222.73 433.889L237.945 379.405L269.481 268.727C276.08 271.943 283.761 280.886 291.552 279.784C294.318 279.786 297.526 280.103 300.239 279.671C302.32 279.34 293.35 281.165 295.5 281C292.765 282.129 294.815 282.321 291.94 282.461C291.8 282.468 291.66 282.481 291.519 282.489C291.435 282.494 291.35 282.496 291.266 282.5C290.329 287.67 289.473 292.882 288.349 298.015L265.21 399.097L256.243 437.602C255.364 441.302 250.844 457.078 251.4 459.744C251.766 459.902 252.097 460.037 252.483 460.143C239.827 462.451 227.245 465.759 214.452 467.044C214.01 466.597 214.147 466.81 213.961 466.462Z" fill="#3158B7"/>
|
||||
<path d="M316.638 264.129C322.458 264.909 327.237 267.42 330.826 272.131C332.112 273.818 335.013 279.586 335.64 280.22C336.122 280.707 336.996 280.978 337.631 281.175L338.374 280.965L338.622 280.946C340.078 289.201 342.561 297.284 344.607 305.405C347.019 314.981 349.071 324.725 351.327 334.35L372.075 421.626C374.16 430.227 376.712 438.738 378.694 447.356C379.359 450.33 379.896 453.327 380.305 456.347C380.489 457.712 380.516 459.221 380.817 460.552C370.442 458.993 360.085 457.318 349.747 455.526C338.68 453.515 327.599 451.012 316.356 450.171L316.124 267.318C316.132 266.225 316.016 265.039 316.638 264.129Z" fill="#5BBFFC"/>
|
||||
<path d="M162.602 542.012C222.681 542.667 282.903 542.133 343 542.146L421.144 542.172C436.934 542.179 452.86 542.406 468.631 542C468.259 556.284 468.631 576.5 466.168 585H164.5C162.602 574 162.11 556.297 162.602 542.012Z" fill="#2E57AB"/>
|
||||
<path d="M263.193 261.724L235.532 253.517L232.5 252.5L229.5 250.5L402 250L377.5 261.724L364 275.5L339.134 284H289.345L269.731 271.69L263.193 261.724Z" fill="#2950B6"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4222_6997" x1="313.33" y1="251.065" x2="313.326" y2="279.202" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#122869"/>
|
||||
<stop offset="1" stop-color="#2950B6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4222_6997" x1="342.025" y1="256.698" x2="339.592" y2="280.614" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#3052A7"/>
|
||||
<stop offset="1" stop-color="#2671CE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_4222_6997" x1="233.914" y1="479.018" x2="235.081" y2="504.885" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#486DC9"/>
|
||||
<stop offset="1" stop-color="#599BEA"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 45" width="45" height="45">
|
||||
<title>Checkmate</title>
|
||||
<desc>King silhouette adapted from Cburnett's chess set (Wikimedia Commons, CC BY-SA 3.0).</desc>
|
||||
<g fill="none" stroke="#13715B" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
||||
<path stroke-linejoin="miter" d="M22.5 11.63V6M20 8h5"/>
|
||||
<path fill="#fff" stroke-linecap="butt" stroke-linejoin="miter" d="M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5"/>
|
||||
<path fill="#fff" d="M12.5 37c5.5 3.5 14.5 3.5 20 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-2.5-7.5-12-10.5-16-4-3 6 6 10.5 6 10.5v7"/>
|
||||
<path d="M12.5 30c5.5-3 14.5-3 20 0m-20 3.5c5.5-3 14.5-3 20 0m-20 3.5c5.5-3 14.5-3 20 0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 819 B |
+21
-2
@@ -33,6 +33,14 @@ function App() {
|
||||
body: {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
},
|
||||
".Toastify__progress-bar": {
|
||||
height: 2,
|
||||
bottom: 0,
|
||||
top: "auto",
|
||||
},
|
||||
".Toastify__progress-bar--bg": {
|
||||
display: "none",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<AppLayout>
|
||||
@@ -41,12 +49,23 @@ function App() {
|
||||
<ToastContainer
|
||||
newestOnTop={true}
|
||||
theme={mode}
|
||||
icon={false}
|
||||
style={
|
||||
{
|
||||
"--toastify-color-progress-light": "#7C8BA1",
|
||||
"--toastify-color-progress-dark": "#7C8BA1",
|
||||
"--toastify-color-progress-light": theme.palette.primary.main,
|
||||
"--toastify-color-progress-dark": theme.palette.primary.main,
|
||||
"--toastify-toast-min-height": "40px",
|
||||
"--toastify-toast-padding": "8px 12px",
|
||||
"--toastify-toast-width": "auto",
|
||||
} as CSSProperties
|
||||
}
|
||||
toastStyle={{
|
||||
minHeight: 40,
|
||||
padding: "8px 12px",
|
||||
width: "auto",
|
||||
maxWidth: "min(560px, calc(100vw - 32px))",
|
||||
}}
|
||||
progressStyle={{ height: 2 }}
|
||||
/>
|
||||
</ThemeProvider>
|
||||
</SWRConfig>
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { ResponsiveStyleValue } from "@mui/system";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
|
||||
type BaseChartProps = React.PropsWithChildren<{
|
||||
icon: React.ReactNode;
|
||||
icon?: React.ReactNode;
|
||||
title: string;
|
||||
width?: number | string;
|
||||
maxWidth?: number | string;
|
||||
@@ -17,7 +17,6 @@ type BaseChartProps = React.PropsWithChildren<{
|
||||
|
||||
export const BaseChart = ({
|
||||
children,
|
||||
icon,
|
||||
title,
|
||||
width = "100%",
|
||||
maxWidth = "100%",
|
||||
@@ -38,34 +37,12 @@ export const BaseChart = ({
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
flex={1}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems={"center"}
|
||||
gap={theme.spacing(LAYOUT.XS)}
|
||||
<Typography
|
||||
variant="eyebrow"
|
||||
color="text.secondary"
|
||||
>
|
||||
{icon && (
|
||||
<BaseBox
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: 34,
|
||||
height: 34,
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
"& svg": {
|
||||
width: 20,
|
||||
height: 20,
|
||||
"& path": {
|
||||
stroke: theme.palette.text.secondary,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
</BaseBox>
|
||||
)}
|
||||
<Typography variant="h2">{title}</Typography>
|
||||
</Stack>
|
||||
{title}
|
||||
</Typography>
|
||||
<Box flex={1}>{children}</Box>
|
||||
</Stack>
|
||||
</BaseBox>
|
||||
|
||||
@@ -1,52 +1,84 @@
|
||||
import Logo from "@/assets/icons/checkmate-icon.svg?react";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Box from "@mui/material/Box";
|
||||
import Alert from "@mui/material/Alert";
|
||||
import Link from "@mui/material/Link";
|
||||
import { LAYOUT, SPACING } from "@/Utils/Theme/constants";
|
||||
import { LAYOUT } from "@/Utils/Theme/constants";
|
||||
import {
|
||||
ErrorFallback,
|
||||
EmptyFallback,
|
||||
EmptyMonitorFallback,
|
||||
BaseFallback,
|
||||
} from "@/Components/design-elements/Fallback";
|
||||
import { EmptyState } from "@/Components/design-elements/EmptyState";
|
||||
import { Breadcrumb } from "@/Components/design-elements/Breadcrumb";
|
||||
import { PageHeader } from "@/Components/design-elements/PageHeader";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
import { HeaderAuthControls } from "@/Pages/Auth/components/HeaderAuthControls";
|
||||
import { LanguageSelector, SwitchTheme } from "@/Components/inputs";
|
||||
|
||||
import type { StackProps } from "@mui/material/Stack";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { useTheme, alpha } from "@mui/material/styles";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { Typography } from "@mui/material";
|
||||
|
||||
export const PageSpeedKeyPriorityFallback = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const alertBg = alpha(theme.palette.warning.main, 0.08);
|
||||
const alertBorder = alpha(theme.palette.warning.main, 0.45);
|
||||
const alertIcon = theme.palette.warning.main;
|
||||
return (
|
||||
<BaseFallback>
|
||||
<Alert
|
||||
severity="warning"
|
||||
sx={{
|
||||
width: "100%",
|
||||
maxWidth: 600,
|
||||
}}
|
||||
>
|
||||
<Typography>
|
||||
<Trans
|
||||
i18nKey="common.alerts.pageSpeedApiKey.content"
|
||||
components={{
|
||||
settingsLink: (
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to="/settings"
|
||||
color="inherit"
|
||||
fontWeight="inherit"
|
||||
/>
|
||||
),
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={t("pages.pageSpeed.fallback.title")}
|
||||
description={t("pages.pageSpeed.fallback.description")}
|
||||
alert={
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="flex-start"
|
||||
gap={theme.spacing(LAYOUT.SM)}
|
||||
sx={{
|
||||
width: "100%",
|
||||
p: theme.spacing(LAYOUT.MD),
|
||||
borderRadius: 1,
|
||||
border: `1px solid ${alertBorder}`,
|
||||
backgroundColor: alertBg,
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="span"
|
||||
sx={{
|
||||
color: alertIcon,
|
||||
fontSize: 18,
|
||||
lineHeight: 1,
|
||||
mt: "2px",
|
||||
}}
|
||||
/>
|
||||
</Typography>
|
||||
</Alert>
|
||||
</BaseFallback>
|
||||
>
|
||||
⚠
|
||||
</Box>
|
||||
<Typography
|
||||
sx={{ color: theme.palette.text.primary, lineHeight: 1.55, fontSize: 13 }}
|
||||
>
|
||||
<Trans
|
||||
i18nKey="common.alerts.pageSpeedApiKey.content"
|
||||
components={{
|
||||
settingsLink: (
|
||||
<Link
|
||||
component={RouterLink}
|
||||
to="/settings"
|
||||
sx={{
|
||||
color: theme.palette.primary.main,
|
||||
fontWeight: 600,
|
||||
textDecoration: "underline",
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Typography>
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -55,6 +87,9 @@ interface BasePageProps extends StackProps {
|
||||
error?: boolean;
|
||||
children: React.ReactNode;
|
||||
breadcrumbOverride?: string[];
|
||||
headerKey?: string;
|
||||
backTo?: string;
|
||||
backLabel?: string;
|
||||
}
|
||||
|
||||
export const BasePage = ({
|
||||
@@ -62,9 +97,13 @@ export const BasePage = ({
|
||||
error,
|
||||
children,
|
||||
breadcrumbOverride,
|
||||
headerKey,
|
||||
backTo,
|
||||
backLabel,
|
||||
...props
|
||||
}: BasePageProps) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
@@ -95,7 +134,16 @@ export const BasePage = ({
|
||||
spacing={theme.spacing(LAYOUT.LG)}
|
||||
{...props}
|
||||
>
|
||||
<Breadcrumb breadcrumbOverride={breadcrumbOverride} />
|
||||
{headerKey ? (
|
||||
<PageHeader
|
||||
title={t(`pages.${headerKey}.header.title`)}
|
||||
description={t(`pages.${headerKey}.header.description`)}
|
||||
backTo={backTo}
|
||||
backLabel={backLabel}
|
||||
/>
|
||||
) : (
|
||||
<Breadcrumb breadcrumbOverride={breadcrumbOverride} />
|
||||
)}
|
||||
{children}
|
||||
</Stack>
|
||||
);
|
||||
@@ -105,11 +153,12 @@ interface BasePageWithStatesProps extends StackProps {
|
||||
loading: boolean;
|
||||
error: any;
|
||||
totalCount: number;
|
||||
bullets: string[] | unknown;
|
||||
description?: string;
|
||||
page: string;
|
||||
actionButtonText: string;
|
||||
actionLink: string;
|
||||
children: React.ReactNode;
|
||||
headerKey?: string;
|
||||
}
|
||||
|
||||
export const BasePageWithStates = ({
|
||||
@@ -117,10 +166,11 @@ export const BasePageWithStates = ({
|
||||
error,
|
||||
totalCount,
|
||||
page,
|
||||
bullets,
|
||||
description,
|
||||
actionButtonText,
|
||||
actionLink,
|
||||
children,
|
||||
headerKey,
|
||||
...props
|
||||
}: BasePageWithStatesProps) => {
|
||||
const showLoading = loading && totalCount === 0;
|
||||
@@ -128,7 +178,7 @@ export const BasePageWithStates = ({
|
||||
if (!loading && totalCount === 0) {
|
||||
return (
|
||||
<EmptyFallback
|
||||
bullets={bullets}
|
||||
description={description}
|
||||
title={page}
|
||||
actionButtonText={actionButtonText}
|
||||
actionLink={actionLink}
|
||||
@@ -140,6 +190,7 @@ export const BasePageWithStates = ({
|
||||
<BasePage
|
||||
loading={showLoading}
|
||||
error={error}
|
||||
headerKey={headerKey}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
@@ -155,6 +206,7 @@ interface MonitorBasePageWithStatesProps extends StackProps {
|
||||
actionLink?: string;
|
||||
children: React.ReactNode;
|
||||
priorityFallback?: React.ReactNode;
|
||||
headerKey?: string;
|
||||
}
|
||||
|
||||
export const MonitorBasePageWithStates = ({
|
||||
@@ -165,6 +217,7 @@ export const MonitorBasePageWithStates = ({
|
||||
actionLink,
|
||||
children,
|
||||
priorityFallback,
|
||||
headerKey,
|
||||
...props
|
||||
}: MonitorBasePageWithStatesProps) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -172,15 +225,7 @@ export const MonitorBasePageWithStates = ({
|
||||
const showLoading = loading && totalCount === 0;
|
||||
|
||||
if (priorityFallback) {
|
||||
return (
|
||||
<BasePage
|
||||
loading={loading}
|
||||
error={error}
|
||||
{...props}
|
||||
>
|
||||
<Stack height={"100%"}>{priorityFallback}</Stack>
|
||||
</BasePage>
|
||||
);
|
||||
return <>{priorityFallback}</>;
|
||||
}
|
||||
|
||||
if (!loading && totalCount === 0) {
|
||||
@@ -188,7 +233,7 @@ export const MonitorBasePageWithStates = ({
|
||||
<EmptyMonitorFallback
|
||||
page={page}
|
||||
title={t(`pages.${page}.fallback.title`)}
|
||||
bullets={t(`pages.${page}.fallback.checks`, { returnObjects: true })}
|
||||
description={t(`pages.${page}.fallback.description`)}
|
||||
actionButtonText={t(`pages.${page}.fallback.actionButton`)}
|
||||
actionLink={actionLink || ""}
|
||||
/>
|
||||
@@ -199,6 +244,7 @@ export const MonitorBasePageWithStates = ({
|
||||
<BasePage
|
||||
loading={showLoading}
|
||||
error={error}
|
||||
headerKey={headerKey}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
@@ -215,51 +261,163 @@ export const BaseAuthPage = ({
|
||||
title,
|
||||
subtitle,
|
||||
children,
|
||||
...props
|
||||
component,
|
||||
onSubmit,
|
||||
}: BaseAuthPageProps) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<BasePage
|
||||
breadcrumbOverride={[]}
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
alignItems={"center"}
|
||||
justifyContent={"center"}
|
||||
<Stack
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
minHeight="100vh"
|
||||
position={"relative"}
|
||||
{...props}
|
||||
width="100%"
|
||||
position="relative"
|
||||
sx={{ backgroundColor: theme.palette.background.default }}
|
||||
>
|
||||
<HeaderAuthControls
|
||||
hideLogo
|
||||
py={theme.spacing(LAYOUT.XS)}
|
||||
position={"absolute"}
|
||||
top={0}
|
||||
left={0}
|
||||
/>
|
||||
<Box width={{ xs: 60, sm: 70, md: 80 }}>
|
||||
<Logo
|
||||
width={"100%"}
|
||||
height={"100%"}
|
||||
/>
|
||||
</Box>
|
||||
<Stack alignItems={"center"}>
|
||||
<Typography
|
||||
variant="h1"
|
||||
mb={theme.spacing(SPACING.LG)}
|
||||
<Stack
|
||||
flex={1}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
position="relative"
|
||||
px={theme.spacing(LAYOUT.MD)}
|
||||
py={{ xs: theme.spacing(20), md: theme.spacing(12) }}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={theme.spacing(2)}
|
||||
alignItems="center"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: theme.spacing(LAYOUT.MD),
|
||||
right: theme.spacing(LAYOUT.MD),
|
||||
zIndex: 3,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography variant="h2">{subtitle}</Typography>
|
||||
<LanguageSelector />
|
||||
<SwitchTheme />
|
||||
</Stack>
|
||||
<Box
|
||||
component={component as React.ElementType}
|
||||
onSubmit={onSubmit}
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: theme.spacing(LAYOUT.MD),
|
||||
width: "100%",
|
||||
maxWidth: 360,
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
gap={theme.spacing(3)}
|
||||
mb={theme.spacing(2)}
|
||||
>
|
||||
<Box width={28}>
|
||||
<Logo width="100%" />
|
||||
</Box>
|
||||
<Typography sx={{ fontWeight: 500, letterSpacing: "-0.01em", fontSize: 16 }}>
|
||||
{t("common.appName")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack gap={theme.spacing(2)}>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 26,
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.15,
|
||||
letterSpacing: "-0.02em",
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
{subtitle}
|
||||
</Typography>
|
||||
</Stack>
|
||||
{children}
|
||||
</Box>
|
||||
</Stack>
|
||||
<Stack
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
width={{
|
||||
xs: "80%",
|
||||
md: "25%",
|
||||
lg: "15%",
|
||||
flex={1}
|
||||
justifyContent="space-between"
|
||||
display={{ xs: "none", md: "flex" }}
|
||||
sx={{
|
||||
background: "linear-gradient(135deg, #0c4d3d 0%, #155a48 60%, #0f5d4a 100%)",
|
||||
color: "#fff",
|
||||
p: theme.spacing(28),
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
"&::after": {
|
||||
content: '""',
|
||||
position: "absolute",
|
||||
inset: 0,
|
||||
backgroundImage: `
|
||||
linear-gradient(45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
|
||||
linear-gradient(-45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
|
||||
linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.04) 75%),
|
||||
linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.04) 75%)
|
||||
`,
|
||||
backgroundSize: "80px 80px",
|
||||
backgroundPosition: "0 0, 0 40px, 40px -40px, -40px 0px",
|
||||
maskImage: "linear-gradient(135deg, transparent 0%, black 70%)",
|
||||
WebkitMaskImage: "linear-gradient(135deg, transparent 0%, black 70%)",
|
||||
pointerEvents: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
<div />
|
||||
<Stack sx={{ position: "relative", zIndex: 1, gap: theme.spacing(4) }}>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 13,
|
||||
fontWeight: 600,
|
||||
textTransform: "uppercase",
|
||||
letterSpacing: "0.12em",
|
||||
color: "rgba(255,255,255,0.75)",
|
||||
}}
|
||||
>
|
||||
{t("pages.auth.brandPanel.eyebrow")}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 44,
|
||||
fontWeight: 400,
|
||||
lineHeight: 1.1,
|
||||
letterSpacing: "-0.02em",
|
||||
maxWidth: 460,
|
||||
}}
|
||||
>
|
||||
{t("pages.auth.brandPanel.tagline")}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 17,
|
||||
lineHeight: 1.5,
|
||||
color: "rgba(255,255,255,0.75)",
|
||||
maxWidth: 460,
|
||||
}}
|
||||
>
|
||||
{t("pages.auth.brandPanel.description")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Typography
|
||||
sx={{
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
color: "rgba(255,255,255,0.5)",
|
||||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
v{__APP_VERSION__}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</BasePage>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,158 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { Button } from "@/Components/inputs";
|
||||
import { LAYOUT } from "@/Utils/Theme/constants";
|
||||
import { EmptyStateIllustration } from "./EmptyStateIllustration";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
interface EmptyStateProps {
|
||||
title: string;
|
||||
description?: ReactNode;
|
||||
actionText?: string;
|
||||
actionTo?: string;
|
||||
onAction?: () => void;
|
||||
secondaryText?: string;
|
||||
secondaryHref?: string;
|
||||
compact?: boolean;
|
||||
fullscreen?: boolean;
|
||||
alert?: ReactNode;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const EmptyState = ({
|
||||
title,
|
||||
description,
|
||||
actionText,
|
||||
actionTo,
|
||||
onAction,
|
||||
secondaryText,
|
||||
secondaryHref,
|
||||
compact = false,
|
||||
fullscreen = false,
|
||||
alert,
|
||||
children,
|
||||
}: EmptyStateProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
if (compact) {
|
||||
return (
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
sx={{ py: theme.spacing(LAYOUT.MD), px: theme.spacing(LAYOUT.SM) }}
|
||||
>
|
||||
<EmptyStateIllustration
|
||||
width={80}
|
||||
height={60}
|
||||
/>
|
||||
<Stack sx={{ flex: 1 }}>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{description && (
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 13,
|
||||
color: theme.palette.text.secondary,
|
||||
lineHeight: 1.55,
|
||||
}}
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
sx={{
|
||||
...(fullscreen && { minHeight: "65vh" }),
|
||||
py: theme.spacing(LAYOUT.XXL),
|
||||
px: theme.spacing(LAYOUT.MD),
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
<EmptyStateIllustration />
|
||||
<Typography
|
||||
sx={{
|
||||
mt: theme.spacing(LAYOUT.MD),
|
||||
mb: theme.spacing(LAYOUT.XS),
|
||||
fontSize: 14,
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{description && (
|
||||
<Typography
|
||||
sx={{
|
||||
maxWidth: 360,
|
||||
fontSize: 13,
|
||||
color: theme.palette.text.secondary,
|
||||
lineHeight: 1.55,
|
||||
mb: theme.spacing(LAYOUT.LG),
|
||||
}}
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
{alert && (
|
||||
<Stack sx={{ width: "100%", maxWidth: 520, mb: theme.spacing(LAYOUT.MD) }}>
|
||||
{alert}
|
||||
</Stack>
|
||||
)}
|
||||
{(actionText || secondaryText) && (
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
>
|
||||
{actionText && (actionTo || onAction) && (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
{...(actionTo
|
||||
? { component: RouterLink, to: actionTo }
|
||||
: { onClick: onAction })}
|
||||
>
|
||||
{actionText}
|
||||
</Button>
|
||||
)}
|
||||
{secondaryText && secondaryHref && (
|
||||
<Typography
|
||||
component="a"
|
||||
href={secondaryHref}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
sx={{
|
||||
fontSize: 13,
|
||||
fontWeight: 500,
|
||||
color: theme.palette.primary.main,
|
||||
textDecoration: "none",
|
||||
"&:hover": { textDecoration: "underline" },
|
||||
}}
|
||||
>
|
||||
{secondaryText} →
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
{children}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,197 @@
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
|
||||
interface EmptyStateIllustrationProps {
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
}
|
||||
|
||||
const PALETTE = {
|
||||
light: {
|
||||
grid: "#CBD5E1",
|
||||
backFill: "#F5F7FA",
|
||||
backStroke: "#D5DBE3",
|
||||
backInner: "#B6C2CF",
|
||||
frontFill: "#EAF5F0",
|
||||
frontStroke: "#7DBFAA",
|
||||
frontInner: "#4DAF94",
|
||||
},
|
||||
dark: {
|
||||
grid: "#3A4452",
|
||||
backFill: "#475569",
|
||||
backStroke: "#64748B",
|
||||
backInner: "#CBD5E1",
|
||||
frontFill: "#0F5D4A",
|
||||
frontStroke: "#4DAF94",
|
||||
frontInner: "#B5E2D2",
|
||||
},
|
||||
};
|
||||
|
||||
export const EmptyStateIllustration = ({
|
||||
width = 160,
|
||||
height = 120,
|
||||
}: EmptyStateIllustrationProps) => {
|
||||
const theme = useTheme();
|
||||
const p = theme.palette.mode === "dark" ? PALETTE.dark : PALETTE.light;
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 160 120"
|
||||
width={width}
|
||||
height={height}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<g
|
||||
stroke={p.grid}
|
||||
strokeWidth="0.75"
|
||||
>
|
||||
<line
|
||||
x1="16"
|
||||
y1="0"
|
||||
x2="16"
|
||||
y2="120"
|
||||
/>
|
||||
<line
|
||||
x1="56"
|
||||
y1="0"
|
||||
x2="56"
|
||||
y2="120"
|
||||
strokeDasharray="3 3"
|
||||
/>
|
||||
<line
|
||||
x1="104"
|
||||
y1="0"
|
||||
x2="104"
|
||||
y2="120"
|
||||
strokeDasharray="3 3"
|
||||
/>
|
||||
<line
|
||||
x1="144"
|
||||
y1="0"
|
||||
x2="144"
|
||||
y2="120"
|
||||
/>
|
||||
<line
|
||||
x1="0"
|
||||
y1="12"
|
||||
x2="160"
|
||||
y2="12"
|
||||
/>
|
||||
<line
|
||||
x1="0"
|
||||
y1="44"
|
||||
x2="160"
|
||||
y2="44"
|
||||
strokeDasharray="3 3"
|
||||
/>
|
||||
<line
|
||||
x1="0"
|
||||
y1="76"
|
||||
x2="160"
|
||||
y2="76"
|
||||
strokeDasharray="3 3"
|
||||
/>
|
||||
<line
|
||||
x1="0"
|
||||
y1="108"
|
||||
x2="160"
|
||||
y2="108"
|
||||
/>
|
||||
</g>
|
||||
|
||||
<g>
|
||||
<rect
|
||||
x="38"
|
||||
y="22"
|
||||
width="92"
|
||||
height="42"
|
||||
rx="6"
|
||||
fill={p.backFill}
|
||||
stroke={p.backStroke}
|
||||
strokeWidth="0.5"
|
||||
/>
|
||||
<rect
|
||||
x="48"
|
||||
y="32"
|
||||
width="14"
|
||||
height="22"
|
||||
rx="2"
|
||||
fill={p.backInner}
|
||||
opacity="0.5"
|
||||
/>
|
||||
<rect
|
||||
x="68"
|
||||
y="34"
|
||||
width="50"
|
||||
height="2.5"
|
||||
rx="1.25"
|
||||
fill={p.backInner}
|
||||
opacity="0.7"
|
||||
/>
|
||||
<rect
|
||||
x="68"
|
||||
y="42"
|
||||
width="38"
|
||||
height="2.5"
|
||||
rx="1.25"
|
||||
fill={p.backInner}
|
||||
opacity="0.55"
|
||||
/>
|
||||
<rect
|
||||
x="68"
|
||||
y="50"
|
||||
width="44"
|
||||
height="2.5"
|
||||
rx="1.25"
|
||||
fill={p.backInner}
|
||||
opacity="0.55"
|
||||
/>
|
||||
<rect
|
||||
x="22"
|
||||
y="50"
|
||||
width="92"
|
||||
height="42"
|
||||
rx="6"
|
||||
fill={p.frontFill}
|
||||
stroke={p.frontStroke}
|
||||
strokeWidth="0.5"
|
||||
strokeOpacity="0.4"
|
||||
/>
|
||||
<rect
|
||||
x="32"
|
||||
y="60"
|
||||
width="14"
|
||||
height="22"
|
||||
rx="2"
|
||||
fill={p.frontInner}
|
||||
opacity="0.35"
|
||||
/>
|
||||
<rect
|
||||
x="52"
|
||||
y="62"
|
||||
width="50"
|
||||
height="2.5"
|
||||
rx="1.25"
|
||||
fill={p.frontInner}
|
||||
opacity="0.55"
|
||||
/>
|
||||
<rect
|
||||
x="52"
|
||||
y="70"
|
||||
width="38"
|
||||
height="2.5"
|
||||
rx="1.25"
|
||||
fill={p.frontInner}
|
||||
opacity="0.4"
|
||||
/>
|
||||
<rect
|
||||
x="52"
|
||||
y="78"
|
||||
width="44"
|
||||
height="2.5"
|
||||
rx="1.25"
|
||||
fill={p.frontInner}
|
||||
opacity="0.4"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -1,12 +1,8 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { BulletPointCheck, SkeletonCard } from "@/Components/design-elements";
|
||||
import { Button } from "@/Components/inputs";
|
||||
import { SPACING, LAYOUT } from "@/Utils/Theme/constants";
|
||||
|
||||
import { useNavigate } from "react-router";
|
||||
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { LAYOUT } from "@/Utils/Theme/constants";
|
||||
import { EmptyState } from "./EmptyState";
|
||||
|
||||
import type { StackProps } from "@mui/material/Stack";
|
||||
|
||||
interface BaseFallbackProps extends StackProps {
|
||||
@@ -15,30 +11,13 @@ interface BaseFallbackProps extends StackProps {
|
||||
|
||||
export const BaseFallback = ({ children, ...props }: BaseFallbackProps) => {
|
||||
const theme = useTheme();
|
||||
const isSmall = useMediaQuery(theme.breakpoints.down("md"));
|
||||
|
||||
return (
|
||||
<Stack
|
||||
alignItems={"center"}
|
||||
margin={isSmall ? "inherit" : "auto"}
|
||||
marginTop={isSmall ? "33%" : "10%"}
|
||||
width={{
|
||||
sm: "90%",
|
||||
md: "70%",
|
||||
lg: "50%",
|
||||
xl: "40%",
|
||||
}}
|
||||
padding={{ xs: theme.spacing(LAYOUT.MD), md: theme.spacing(LAYOUT.XXL) }}
|
||||
bgcolor={theme.palette.background.paper}
|
||||
border={1}
|
||||
borderColor={theme.palette.divider}
|
||||
borderRadius={theme.shape.borderRadius}
|
||||
sx={{
|
||||
borderStyle: "dashed",
|
||||
}}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
sx={{ width: "100%", py: theme.spacing(LAYOUT.LG) }}
|
||||
{...props}
|
||||
>
|
||||
<SkeletonCard showHalo={true} />
|
||||
{children}
|
||||
</Stack>
|
||||
);
|
||||
@@ -51,126 +30,56 @@ export const ErrorFallback = ({
|
||||
title: string;
|
||||
subtitle: string;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<BaseFallback>
|
||||
<Typography
|
||||
variant="h1"
|
||||
marginY={theme.spacing(LAYOUT.XS)}
|
||||
color={theme.palette.text.secondary}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography>{subtitle}</Typography>
|
||||
</BaseFallback>
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={title}
|
||||
description={subtitle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const EmptyFallback = ({
|
||||
title,
|
||||
bullets,
|
||||
description,
|
||||
actionButtonText,
|
||||
actionLink,
|
||||
}: {
|
||||
title: string;
|
||||
bullets: any;
|
||||
description?: string;
|
||||
actionButtonText: string;
|
||||
actionLink: string;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<BaseFallback>
|
||||
<Stack
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
zIndex={1}
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography component="h1">{title}</Typography>
|
||||
<Stack
|
||||
sx={{
|
||||
flexWrap: "wrap",
|
||||
gap: theme.spacing(SPACING.MD),
|
||||
maxWidth: "1100px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{Array.isArray(bullets) &&
|
||||
bullets?.map((bullet: string) => (
|
||||
<BulletPointCheck
|
||||
text={bullet}
|
||||
key={`${bullet}-${Math.random()}`}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
<Stack>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => navigate(actionLink)}
|
||||
>
|
||||
{actionButtonText}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</BaseFallback>
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={title}
|
||||
description={description}
|
||||
actionText={actionButtonText}
|
||||
actionTo={actionLink}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const EmptyMonitorFallback = ({
|
||||
page,
|
||||
title,
|
||||
bullets,
|
||||
description,
|
||||
actionButtonText,
|
||||
actionLink,
|
||||
}: {
|
||||
page: string;
|
||||
title: string;
|
||||
bullets: any;
|
||||
description?: string;
|
||||
actionButtonText: string;
|
||||
actionLink: string;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<BaseFallback>
|
||||
<Stack
|
||||
gap={theme.spacing(LAYOUT.MD)}
|
||||
zIndex={1}
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography
|
||||
component="h1"
|
||||
color={theme.palette.primary.contrastText}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<Stack
|
||||
sx={{
|
||||
flexWrap: "wrap",
|
||||
gap: theme.spacing(SPACING.MD),
|
||||
maxWidth: "1100px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{Array.isArray(bullets) &&
|
||||
bullets?.map((bullet: string, index: number) => (
|
||||
<BulletPointCheck
|
||||
text={bullet}
|
||||
key={`${(page + "Monitors").trim().split(" ")[0]}-${index}`}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
<Stack>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => navigate(actionLink)}
|
||||
>
|
||||
{actionButtonText}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</BaseFallback>
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={title}
|
||||
description={description}
|
||||
actionText={actionButtonText}
|
||||
actionTo={actionLink}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -114,6 +114,7 @@ export const DetailGauge = ({
|
||||
upperValue,
|
||||
lowerLabel,
|
||||
lowerValue,
|
||||
maxWidth = 225,
|
||||
}: {
|
||||
title: string;
|
||||
progress: number;
|
||||
@@ -121,13 +122,14 @@ export const DetailGauge = ({
|
||||
upperValue?: string | number;
|
||||
lowerLabel?: string;
|
||||
lowerValue?: string | number;
|
||||
maxWidth?: number;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<BaseChart
|
||||
icon={null}
|
||||
title={title}
|
||||
maxWidth={225}
|
||||
maxWidth={maxWidth}
|
||||
>
|
||||
<Stack
|
||||
alignItems={"center"}
|
||||
|
||||
@@ -34,7 +34,7 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => {
|
||||
<Typography
|
||||
fontSize={typographyLevels.l}
|
||||
fontWeight={"bolder"}
|
||||
fontFamily={"monospace"}
|
||||
fontFamily={theme.typography.fontFamilyMonospace}
|
||||
overflow={"hidden"}
|
||||
textOverflow={"ellipsis"}
|
||||
whiteSpace={"nowrap"}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Box from "@mui/material/Box";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import { Link as RouterLink } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { ChevronLeft, HelpCircle, FileText, Code } from "lucide-react";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
const EXTERNAL_LINKS = {
|
||||
support: "https://discord.com/invite/NAb6H3UTjK",
|
||||
docs: "https://checkmate.so/docs",
|
||||
changelog: "https://github.com/bluewave-labs/checkmate/releases",
|
||||
};
|
||||
|
||||
interface PageHeaderProps {
|
||||
title: string;
|
||||
description?: ReactNode;
|
||||
backTo?: string;
|
||||
backLabel?: string;
|
||||
}
|
||||
|
||||
export const PageHeader = ({
|
||||
title,
|
||||
description,
|
||||
backTo,
|
||||
backLabel,
|
||||
}: PageHeaderProps) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const linkItems: { key: keyof typeof EXTERNAL_LINKS; icon: ReactNode }[] = [
|
||||
{
|
||||
key: "support",
|
||||
icon: (
|
||||
<HelpCircle
|
||||
size={16}
|
||||
strokeWidth={1.6}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "docs",
|
||||
icon: (
|
||||
<FileText
|
||||
size={16}
|
||||
strokeWidth={1.6}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "changelog",
|
||||
icon: (
|
||||
<Code
|
||||
size={16}
|
||||
strokeWidth={1.6}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="flex-start"
|
||||
justifyContent="space-between"
|
||||
gap={6}
|
||||
sx={{ mb: theme.spacing(8) }}
|
||||
>
|
||||
<Stack gap={theme.spacing(1)}>
|
||||
{backTo && backLabel && (
|
||||
<Box
|
||||
component={RouterLink}
|
||||
to={backTo}
|
||||
sx={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: 0.5,
|
||||
textDecoration: "none",
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: 13,
|
||||
mb: theme.spacing(1),
|
||||
"&:hover": { color: theme.palette.text.primary },
|
||||
}}
|
||||
>
|
||||
<ChevronLeft
|
||||
size={14}
|
||||
strokeWidth={1.8}
|
||||
/>
|
||||
{backLabel}
|
||||
</Box>
|
||||
)}
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 26,
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
lineHeight: 1.15,
|
||||
letterSpacing: "-0.02em",
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{description && (
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
color: theme.palette.text.secondary,
|
||||
lineHeight: 1.55,
|
||||
maxWidth: 640,
|
||||
}}
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
</Stack>
|
||||
<Box
|
||||
sx={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: 1,
|
||||
overflow: "hidden",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
{linkItems.map((item, idx) => (
|
||||
<Tooltip
|
||||
key={item.key}
|
||||
title={t(`components.pageHeader.links.${item.key}`)}
|
||||
>
|
||||
<Box
|
||||
component="a"
|
||||
href={EXTERNAL_LINKS[item.key]}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
width: 36,
|
||||
height: 32,
|
||||
color: theme.palette.text.secondary,
|
||||
borderRight:
|
||||
idx < linkItems.length - 1
|
||||
? `1px solid ${theme.palette.divider}`
|
||||
: "none",
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{item.icon}
|
||||
</Box>
|
||||
</Tooltip>
|
||||
))}
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -63,9 +63,9 @@ export const ConfigBox = ({
|
||||
left={
|
||||
<Stack spacing={theme.spacing(LAYOUT.XS)}>
|
||||
<Typography
|
||||
textTransform={"capitalize"}
|
||||
component="h2"
|
||||
variant="h2"
|
||||
variant="eyebrow"
|
||||
color="text.secondary"
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
|
||||
@@ -69,7 +69,12 @@ export const StatBox = ({
|
||||
>
|
||||
<Stack onClick={onClick}>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: theme.spacing(2) }}>
|
||||
<Typography color={textColor}>{title}</Typography>
|
||||
<Typography
|
||||
variant="eyebrow"
|
||||
color={palette ? textColor : "text.secondary"}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{tooltip && (
|
||||
<TooltipWithInfo
|
||||
title={tooltip}
|
||||
|
||||
@@ -21,7 +21,7 @@ export const BGBox = ({ children, sx }: StatusBoxProps) => {
|
||||
overflow: "hidden",
|
||||
position: "relative",
|
||||
flex: 1,
|
||||
padding: theme.spacing(4),
|
||||
padding: theme.spacing(6),
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
@@ -65,9 +65,13 @@ const StatusBox = ({
|
||||
<BGBox sx={sx}>
|
||||
<Stack spacing={theme.spacing(4)}>
|
||||
<Typography
|
||||
variant={"h2"}
|
||||
textTransform="uppercase"
|
||||
color={theme.palette.text.secondary}
|
||||
sx={{
|
||||
fontSize: 11,
|
||||
fontWeight: 500,
|
||||
letterSpacing: "0.08em",
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
|
||||
@@ -18,10 +18,9 @@ import {
|
||||
ChevronsRight,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
Coffee,
|
||||
Ellipsis,
|
||||
PartyPopper,
|
||||
} from "lucide-react";
|
||||
import { EmptyState } from "./EmptyState";
|
||||
|
||||
import TablePagination from "@mui/material/TablePagination";
|
||||
import type { TablePaginationOwnProps } from "@mui/material/TablePagination";
|
||||
@@ -163,14 +162,19 @@ export function DataTable<
|
||||
},
|
||||
"& .MuiTableHead-root .MuiTableRow-root": {
|
||||
height: "28px",
|
||||
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"& .MuiTableHead-root .MuiTableCell-root": {
|
||||
borderBottom: "none",
|
||||
},
|
||||
"& :is(th)": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
color: theme.palette.text.secondary,
|
||||
fontWeight: 500,
|
||||
textTransform: "uppercase",
|
||||
letterSpacing: "0.08em",
|
||||
padding: `${theme.spacing(SPACING.LG)} ${theme.spacing(LAYOUT.MD)}`,
|
||||
fontSize: theme.typography.fontSize,
|
||||
fontSize: 11,
|
||||
},
|
||||
"& :is(td)": {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
@@ -548,49 +552,18 @@ export const Pagination = ({ ...props }: PaginationProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const EmptyView = ({ text, positive }: { text?: string; positive?: boolean }) => {
|
||||
const theme = useTheme();
|
||||
const EmptyView = ({ text }: { text?: string; positive?: boolean }) => {
|
||||
const { t } = useTranslation();
|
||||
const Icon = positive ? PartyPopper : Coffee;
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Stack
|
||||
alignItems={"center"}
|
||||
justifyContent={"center"}
|
||||
<Box
|
||||
sx={{
|
||||
py: theme.spacing(LAYOUT.XL),
|
||||
px: theme.spacing(LAYOUT.XS),
|
||||
borderWidth: 1,
|
||||
borderStyle: "solid",
|
||||
borderColor: theme.palette.divider,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
textAlign: "center",
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: 1,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: "50%",
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
mb: theme.spacing(SPACING.LG),
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
size={28}
|
||||
strokeWidth={1}
|
||||
color={theme.palette.text.secondary}
|
||||
/>
|
||||
</Box>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color={theme.palette.text.primary}
|
||||
sx={{ fontWeight: 500 }}
|
||||
>
|
||||
{text ?? t("common.table.empty")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<EmptyState title={text ?? t("common.table.empty")} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -16,16 +16,15 @@ export const Tooltip = ({ placement = "top", ...props }: StyledTooltipProps) =>
|
||||
slotProps={{
|
||||
tooltip: {
|
||||
sx: {
|
||||
background:
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark"
|
||||
? "linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)"
|
||||
: "linear-gradient(135deg, #2c3e50 0%, #1a252f 100%)",
|
||||
backgroundColor: "transparent",
|
||||
color: "#ffffff",
|
||||
? theme.palette.grey[900]
|
||||
: theme.palette.grey[800],
|
||||
color: theme.palette.common.white,
|
||||
fontSize: "13px",
|
||||
padding: `${theme.spacing(4)} ${theme.spacing(5)}`,
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
boxShadow: "0 8px 24px rgba(0, 0, 0, 0.4)",
|
||||
boxShadow: theme.shadows[6],
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
export * from "./Breadcrumb";
|
||||
export * from "./PageHeader";
|
||||
export * from "./BasePage";
|
||||
export * from "./EmptyState";
|
||||
export * from "./EmptyStateIllustration";
|
||||
export * from "./Fallback";
|
||||
export * from "./SkeletonCard";
|
||||
export * from "./BulletPointCheck";
|
||||
|
||||
@@ -46,6 +46,9 @@ export const DialogInput = ({
|
||||
open={open}
|
||||
maxWidth={maxWidth}
|
||||
fullWidth={fullWidth}
|
||||
onClose={(_event, reason) => {
|
||||
if (reason !== "backdropClick" && onCancel) onCancel(undefined);
|
||||
}}
|
||||
>
|
||||
{title && <DialogTitle sx={{ fontSize: typographyLevels.l }}>{title}</DialogTitle>}
|
||||
<DialogContent>
|
||||
|
||||
@@ -126,7 +126,12 @@ export const ImageUpload = ({
|
||||
onChange={(e) => handleFile(e.target.files?.[0])}
|
||||
style={{ position: "absolute", inset: 0, opacity: 0, cursor: "pointer" }}
|
||||
/>
|
||||
<Upload size={24} />
|
||||
<Upload
|
||||
size={20}
|
||||
strokeWidth={1.5}
|
||||
color="currentColor"
|
||||
style={{ opacity: 0.7 }}
|
||||
/>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="text.secondary"
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Box from "@mui/material/Box";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import { Select } from "@/Components/inputs";
|
||||
import "flag-icons/css/flag-icons.min.css";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTheme } from "@mui/material";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { setLanguage } from "@/Features/UI/uiSlice";
|
||||
import type { RootState } from "@/Types/state";
|
||||
|
||||
const langMap: Record<string, string> = {
|
||||
cs: "cz",
|
||||
ja: "jp",
|
||||
uk: "ua",
|
||||
vi: "vn",
|
||||
export const languageNames: Record<string, string> = {
|
||||
en: "English",
|
||||
de: "Deutsch",
|
||||
es: "Español",
|
||||
fr: "Français",
|
||||
"pt-BR": "Português (BR)",
|
||||
cs: "Čeština",
|
||||
fi: "Suomi",
|
||||
tr: "Türkçe",
|
||||
ru: "Русский",
|
||||
uk: "Українська",
|
||||
ar: "العربية",
|
||||
th: "ไทย",
|
||||
vi: "Tiếng Việt",
|
||||
ja: "日本語",
|
||||
"zh-CN": "简体中文",
|
||||
"zh-TW": "繁體中文",
|
||||
};
|
||||
|
||||
export const LanguageSelector = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const { language = "en" } = useSelector((state: RootState) => state.ui);
|
||||
const dispatch = useDispatch();
|
||||
const handleChange = (event: any) => {
|
||||
@@ -35,64 +42,15 @@ export const LanguageSelector = () => {
|
||||
value={language}
|
||||
onChange={handleChange}
|
||||
size="small"
|
||||
// sx={{
|
||||
// minWidth: 80,
|
||||
// "& .MuiSelect-select": {
|
||||
// display: "flex",
|
||||
// alignItems: "center",
|
||||
// justifyContent: "center",
|
||||
// },
|
||||
// "& .MuiSelect-icon": {
|
||||
// alignSelf: "center",
|
||||
// },
|
||||
// }}
|
||||
>
|
||||
{languages.map((lang) => {
|
||||
let parsedLang = lang === "en" ? "gb" : lang;
|
||||
|
||||
if (parsedLang.includes("-")) {
|
||||
parsedLang = parsedLang.split("-")[1].toLowerCase();
|
||||
}
|
||||
|
||||
parsedLang = langMap[parsedLang] || parsedLang;
|
||||
|
||||
const flag = parsedLang ? `fi fi-${parsedLang}` : null;
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
key={lang}
|
||||
value={lang}
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={theme.spacing(2)}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Box
|
||||
component="span"
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{flag && <span className={flag} />}
|
||||
</Box>
|
||||
<Box
|
||||
component="span"
|
||||
sx={{ textTransform: "uppercase" }}
|
||||
>
|
||||
{lang}
|
||||
</Box>
|
||||
</Stack>
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
{languages.map((lang) => (
|
||||
<MenuItem
|
||||
key={lang}
|
||||
value={lang}
|
||||
>
|
||||
{languageNames[lang] ?? lang}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,52 +1,13 @@
|
||||
import Radio from "@mui/material/Radio";
|
||||
import type { RadioProps } from "@mui/material/Radio";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { Circle, CircleDot } from "lucide-react";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
interface RadioInputProps extends RadioProps {}
|
||||
|
||||
export const RadioInput = ({ ...props }: RadioInputProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Radio
|
||||
{...props}
|
||||
icon={
|
||||
<Circle
|
||||
size={16}
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
}
|
||||
checkedIcon={
|
||||
<CircleDot
|
||||
size={14}
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
}
|
||||
sx={{
|
||||
padding: 0,
|
||||
mt: theme.spacing(0.5),
|
||||
color: theme.palette.text.secondary,
|
||||
"&.Mui-checked": {
|
||||
color: theme.palette.primary.main,
|
||||
"& svg circle": {
|
||||
fill: theme.palette.primary.main,
|
||||
},
|
||||
},
|
||||
"& .MuiSvgIcon-root": {
|
||||
fontSize: 16,
|
||||
},
|
||||
"& svg": {
|
||||
stroke: "currentColor",
|
||||
},
|
||||
"& svg path, & svg line, & svg polyline, & svg rect, & svg circle": {
|
||||
stroke: "currentColor",
|
||||
fill: "none",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
return <Radio {...props} />;
|
||||
};
|
||||
|
||||
export const RadioWithDescription = ({
|
||||
@@ -79,7 +40,6 @@ export const RadioWithDescription = ({
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
},
|
||||
"& .MuiButtonBase-root": {
|
||||
p: 0,
|
||||
mr: theme.spacing(6),
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -11,15 +11,14 @@ interface SelectInputProps<T> extends Omit<SelectProps<T>, "label"> {
|
||||
fieldLabel?: string;
|
||||
required?: boolean;
|
||||
placeholder?: string;
|
||||
placeholderColor?: string;
|
||||
}
|
||||
|
||||
const SelectInputInner = <T,>(
|
||||
{ fieldLabel, required, placeholder, placeholderColor, ...props }: SelectInputProps<T>,
|
||||
{ fieldLabel, required, placeholder, ...props }: SelectInputProps<T>,
|
||||
ref: React.ForwardedRef<HTMLDivElement>
|
||||
) => {
|
||||
const theme = useTheme();
|
||||
const emptyPlaceholderColor = placeholderColor || theme.palette.text.disabled;
|
||||
const emptyPlaceholderColor = theme.palette.text.secondary;
|
||||
|
||||
const renderValue = (selected: unknown) => {
|
||||
const isMultiple = Boolean((props as { multiple?: boolean }).multiple);
|
||||
|
||||
@@ -21,24 +21,16 @@ export const SwitchComponent = forwardRef<HTMLInputElement, SwitchComponentProps
|
||||
},
|
||||
}}
|
||||
sx={[
|
||||
{
|
||||
"& .MuiSwitch-switchBase": {
|
||||
"&.Mui-checked": {
|
||||
color: "#E0E0E0",
|
||||
"& + .MuiSwitch-track": {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
opacity: 1,
|
||||
border: 0,
|
||||
...(dualOption
|
||||
? [
|
||||
{
|
||||
"& .MuiSwitch-track": {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
...(dualOption && {
|
||||
"& .MuiSwitch-track": {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
opacity: 1,
|
||||
},
|
||||
}),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...additionalSx,
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -26,6 +26,7 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(function T
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
height: 34,
|
||||
fontSize: typographyLevels.base,
|
||||
overflow: "hidden",
|
||||
},
|
||||
"& .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: theme.palette.divider,
|
||||
@@ -38,6 +39,13 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(function T
|
||||
marginRight: 0,
|
||||
marginTop: theme.spacing(1),
|
||||
},
|
||||
"& input:-webkit-autofill, & input:-webkit-autofill:hover, & input:-webkit-autofill:focus, & input:-webkit-autofill:active":
|
||||
{
|
||||
WebkitBoxShadow: `0 0 0 100px ${theme.palette.background.default} inset !important`,
|
||||
WebkitTextFillColor: `${theme.palette.text.primary} !important`,
|
||||
caretColor: theme.palette.text.primary,
|
||||
transition: "background-color 5000s ease-in-out 0s",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -3,8 +3,17 @@ import ToggleButtonGroup from "@mui/material/ToggleButtonGroup";
|
||||
import type { ToggleButtonProps } from "@mui/material/ToggleButton";
|
||||
import type { ToggleButtonGroupProps } from "@mui/material/ToggleButtonGroup";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { alpha } from "@mui/material/styles";
|
||||
|
||||
export const ToggleButtonInput = ({ sx, ...props }: ToggleButtonProps) => {
|
||||
const theme = useTheme();
|
||||
const isDark = theme.palette.mode === "dark";
|
||||
const selectedBg = isDark
|
||||
? alpha(theme.palette.primary.main, 0.22)
|
||||
: alpha(theme.palette.primary.main, 0.06);
|
||||
const selectedHoverBg = isDark
|
||||
? alpha(theme.palette.primary.main, 0.3)
|
||||
: alpha(theme.palette.primary.main, 0.1);
|
||||
return (
|
||||
<ToggleButton
|
||||
{...props}
|
||||
@@ -17,8 +26,18 @@ export const ToggleButtonInput = ({ sx, ...props }: ToggleButtonProps) => {
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
boxShadow: "none",
|
||||
color: theme.palette.text.secondary,
|
||||
"&:hover": {
|
||||
boxShadow: "none",
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
},
|
||||
"&.Mui-selected": {
|
||||
backgroundColor: selectedBg,
|
||||
color: theme.palette.text.primary,
|
||||
fontWeight: 500,
|
||||
"&:hover": {
|
||||
backgroundColor: selectedHoverBg,
|
||||
},
|
||||
},
|
||||
...sx,
|
||||
}}
|
||||
@@ -34,7 +53,6 @@ export const ToggleButtonGroupInput = ({ sx, ...props }: ToggleButtonGroupProps)
|
||||
sx={{
|
||||
"& .MuiToggleButtonGroup-grouped": {
|
||||
borderColor: theme.palette.divider,
|
||||
|
||||
borderRadius: 0,
|
||||
"&:first-of-type": {
|
||||
borderTopLeftRadius: 2,
|
||||
|
||||
@@ -25,10 +25,7 @@ export const MonitorStatBoxes = ({
|
||||
}
|
||||
|
||||
const timeOfLastFailure = monitorStats?.timeOfLastFailure || 0;
|
||||
const timeSinceLastFailure =
|
||||
timeOfLastFailure > 0
|
||||
? Date.now() - timeOfLastFailure
|
||||
: Date.now() - new Date(monitorStats?.createdAt || 0).getTime();
|
||||
const timeSinceLastFailure = timeOfLastFailure > 0 ? Date.now() - timeOfLastFailure : 0;
|
||||
|
||||
// Determine time since last check
|
||||
const timeOfLastCheck = monitorStats?.lastCheckTimestamp || 0;
|
||||
@@ -42,6 +39,12 @@ export const MonitorStatBoxes = ({
|
||||
const streakTime = prettyMilliseconds(timeSinceLastFailure, options);
|
||||
|
||||
const lastCheckTime = prettyMilliseconds(timeSinceLastCheck, options);
|
||||
const isActive =
|
||||
monitor?.status === "up" ||
|
||||
monitor?.status === "paused" ||
|
||||
monitor?.status === "maintenance" ||
|
||||
monitor?.status === "initializing" ||
|
||||
monitor?.status === "breached";
|
||||
const palette = getStatusPalette(monitor?.status);
|
||||
|
||||
return (
|
||||
@@ -51,8 +54,12 @@ export const MonitorStatBoxes = ({
|
||||
>
|
||||
<StatBox
|
||||
palette={palette}
|
||||
title={t("pages.common.monitors.statBoxes.activeFor")}
|
||||
subtitle={streakTime}
|
||||
title={
|
||||
isActive
|
||||
? t("pages.common.monitors.statBoxes.activeFor")
|
||||
: t("pages.common.monitors.statBoxes.serviceIsDown")
|
||||
}
|
||||
subtitle={isActive ? streakTime : ""}
|
||||
/>
|
||||
<StatBox
|
||||
title={t("pages.common.monitors.statBoxes.lastCheck")}
|
||||
|
||||
@@ -52,7 +52,7 @@ export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) =>
|
||||
>
|
||||
<RadialBar
|
||||
dataKey="value"
|
||||
background={{ fill: theme.palette[palette].light }}
|
||||
background={{ fill: theme.palette.action.disabledBackground }}
|
||||
>
|
||||
<Cell visibility={"hidden"} />
|
||||
<Cell fill={theme.palette[palette].main} />
|
||||
@@ -75,13 +75,14 @@ export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) =>
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="h6"
|
||||
variant="eyebrow"
|
||||
color={theme.palette[palette].main}
|
||||
textAlign={"center"}
|
||||
>
|
||||
{msg[palette]}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="h6"
|
||||
variant="h1"
|
||||
textAlign={"center"}
|
||||
>{`${avg?.toFixed()}ms`}</Typography>
|
||||
</Stack>
|
||||
|
||||
@@ -68,7 +68,12 @@ export const AuthFooter = ({ collapsed, accountMenuItems }: AuthFooterProps) =>
|
||||
gap: theme.spacing(LAYOUT.MD),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
pl: theme.spacing(LAYOUT.XS),
|
||||
"& svg": { stroke: theme.palette.text.secondary },
|
||||
"& svg": {
|
||||
height: 16,
|
||||
width: 16,
|
||||
opacity: 0.81,
|
||||
stroke: theme.palette.text.secondary,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -6,6 +6,7 @@ import { toggleSidebar } from "@/Features/UI/uiSlice.js";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useSidebar from "@/Hooks/useSidebar";
|
||||
import KingIcon from "@/assets/icons/checkmate-icon.svg?react";
|
||||
|
||||
export const Logo = (props: StackProps) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -23,19 +24,21 @@ export const Logo = (props: StackProps) => {
|
||||
sx={{ cursor: "pointer" }}
|
||||
{...props}
|
||||
>
|
||||
<Typography
|
||||
minWidth={theme.spacing(16)}
|
||||
minHeight={theme.spacing(16)}
|
||||
display={"flex"}
|
||||
justifyContent={"center"}
|
||||
alignItems={"center"}
|
||||
bgcolor={theme.palette.primary.main}
|
||||
borderRadius={theme.shape.borderRadius}
|
||||
color={theme.palette.primary.contrastText}
|
||||
fontSize={18}
|
||||
<Box
|
||||
sx={{
|
||||
width: theme.spacing(16),
|
||||
height: theme.spacing(16),
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
"& svg": {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
},
|
||||
}}
|
||||
>
|
||||
C
|
||||
</Typography>
|
||||
<KingIcon />
|
||||
</Box>
|
||||
<Box
|
||||
overflow={"hidden"}
|
||||
sx={{
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
AlertTriangle,
|
||||
Wifi,
|
||||
Wrench,
|
||||
Database,
|
||||
ScrollText,
|
||||
Settings,
|
||||
HelpCircle,
|
||||
MessageCircle,
|
||||
@@ -64,7 +64,7 @@ export const getMenu = (t: Function) => {
|
||||
{
|
||||
name: t("components.sidebar.menu.logs"),
|
||||
path: "logs",
|
||||
icon: <Icon icon={Database} />,
|
||||
icon: <Icon icon={ScrollText} />,
|
||||
},
|
||||
{
|
||||
name: t("components.sidebar.menu.settings"),
|
||||
|
||||
@@ -22,7 +22,9 @@ export const NavItem = ({
|
||||
}) => {
|
||||
const { collapsed } = useSidebar();
|
||||
const theme = useTheme();
|
||||
const iconStroke = selected ? theme.palette.primary.main : theme.palette.text.secondary;
|
||||
const iconStroke = selected
|
||||
? theme.palette.sidebar.accent
|
||||
: theme.palette.text.secondary;
|
||||
|
||||
const buttonBgColor = selected ? theme.palette.action.selected : "transparent";
|
||||
const buttonBgHoverColor = selected
|
||||
@@ -79,7 +81,7 @@ export const NavItem = ({
|
||||
},
|
||||
".MuiListItemButton-root:hover &": {
|
||||
"& svg path, & svg line, & svg polyline, & svg rect, & svg circle": {
|
||||
stroke: theme.palette.primary.main,
|
||||
stroke: theme.palette.sidebar.accent,
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -6,7 +6,7 @@ import Divider from "@mui/material/Divider";
|
||||
import { LAYOUT } from "@/Utils/Theme/constants";
|
||||
import { useSidebar } from "@/Hooks/useSidebar.js";
|
||||
import { Logo } from "@/Components/sidebar/Logo";
|
||||
import { getMenu, getBottomMenu, getAccountMenu } from "@/Components/sidebar/Menu";
|
||||
import { getMenu, getAccountMenu } from "@/Components/sidebar/Menu";
|
||||
import { NavItem } from "@/Components/sidebar/NavItem";
|
||||
import { StarPrompt } from "@/Components/sidebar/StarPrompt";
|
||||
import { AuthFooter } from "@/Components/sidebar/Authfooter";
|
||||
@@ -20,7 +20,7 @@ import { setCollapsed } from "@/Features/UI/uiSlice";
|
||||
const URL_MAP: Record<string, string> = {
|
||||
support: "https://discord.com/invite/NAb6H3UTjK",
|
||||
discussions: "https://github.com/bluewave-labs/checkmate/discussions",
|
||||
docs: "https://bluewavelabs.gitbook.io/checkmate",
|
||||
docs: "https://checkmate.so/docs",
|
||||
changelog: "https://github.com/bluewave-labs/checkmate/releases",
|
||||
};
|
||||
|
||||
@@ -33,7 +33,6 @@ export const Sidebar = () => {
|
||||
const theme = useTheme();
|
||||
const isSmall = useMediaQuery(theme.breakpoints.down("md"));
|
||||
const menu = getMenu(t);
|
||||
const bottomMenu = getBottomMenu(t);
|
||||
const accountMenu = getAccountMenu(t);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -103,23 +102,6 @@ export const Sidebar = () => {
|
||||
})}
|
||||
</List>
|
||||
<StarPrompt />
|
||||
<List
|
||||
component="nav"
|
||||
disablePadding
|
||||
sx={{ px: theme.spacing(LAYOUT.SM) }}
|
||||
>
|
||||
{bottomMenu.map((item) => {
|
||||
const selected = location.pathname.startsWith(`/${item.path}`);
|
||||
return (
|
||||
<NavItem
|
||||
key={item.path}
|
||||
item={item}
|
||||
selected={selected}
|
||||
onClick={() => handleNavClick(item.path)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
<Divider sx={{ borderColor: theme.palette.divider }} />
|
||||
|
||||
<AuthFooter
|
||||
|
||||
@@ -57,7 +57,11 @@ export const usePost = <B = any, R = any>() => {
|
||||
...config?.headers,
|
||||
},
|
||||
});
|
||||
toastSuccess(res.data?.msg || "Operation successful");
|
||||
if (res.data?.success === false) {
|
||||
toastError(res.data?.msg || "Operation failed");
|
||||
} else {
|
||||
toastSuccess(res.data?.msg || "Operation successful");
|
||||
}
|
||||
|
||||
return res.data;
|
||||
} catch (err: any) {
|
||||
|
||||
@@ -4,8 +4,9 @@ export const useToast = () => {
|
||||
const showToast = (message: string, options?: ToastOptions) => {
|
||||
toast.dismiss();
|
||||
const baseStyle: React.CSSProperties = {
|
||||
whiteSpace: "pre-line",
|
||||
wordBreak: "break-word",
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
};
|
||||
toast(message, {
|
||||
...options,
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { useState } from "react";
|
||||
|
||||
export const useClientPagination = <T>(rows: T[], initialRowsPerPage = 10) => {
|
||||
const [page, setPage] = useState(0);
|
||||
const [rowsPerPage, setRowsPerPage] = useState(initialRowsPerPage);
|
||||
|
||||
const handlePageChange = (
|
||||
_e: React.MouseEvent<HTMLButtonElement> | null,
|
||||
newPage: number
|
||||
) => {
|
||||
setPage(newPage);
|
||||
};
|
||||
|
||||
const handleRowsPerPageChange = (
|
||||
e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
|
||||
) => {
|
||||
setPage(0);
|
||||
setRowsPerPage(Number(e.target.value));
|
||||
};
|
||||
|
||||
const pagedRows = rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
|
||||
|
||||
return {
|
||||
page,
|
||||
rowsPerPage,
|
||||
pagedRows,
|
||||
paginationProps: {
|
||||
component: "div" as const,
|
||||
count: rows.length,
|
||||
page,
|
||||
rowsPerPage,
|
||||
onPageChange: handlePageChange,
|
||||
onRowsPerPageChange: handleRowsPerPageChange,
|
||||
itemsOnPage: pagedRows.length,
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -60,6 +60,24 @@ function buildDefaults(data: Notification | null): NotificationFormData {
|
||||
address: data.address || "",
|
||||
};
|
||||
}
|
||||
if (data?.type === "twilio") {
|
||||
return {
|
||||
type: "twilio",
|
||||
notificationName: data.notificationName || "",
|
||||
accountSid: data.accountSid || "",
|
||||
accessToken: data.accessToken || "",
|
||||
phone: data.phone || "",
|
||||
twilioPhoneNumber: data.twilioPhoneNumber || "",
|
||||
};
|
||||
}
|
||||
if (data?.type === "pushover") {
|
||||
return {
|
||||
type: "pushover",
|
||||
notificationName: data.notificationName || "",
|
||||
address: data.address || "",
|
||||
accessToken: data.accessToken || "",
|
||||
};
|
||||
}
|
||||
// Default: email (covers both data === null and data.type === "email")
|
||||
return {
|
||||
type: "email",
|
||||
|
||||
@@ -28,7 +28,7 @@ export const useStatusPageForm = ({
|
||||
url: data?.url || generateDefaultUrl(),
|
||||
timezone: data?.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
type: data?.type || ["uptime"],
|
||||
color: data?.color || "#4169E1",
|
||||
color: data?.color || "#13715B",
|
||||
monitors: data?.monitors || [],
|
||||
isPublished: data?.isPublished ?? false,
|
||||
showCharts: data?.showCharts ?? true,
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import { Stack } from "@mui/material";
|
||||
import { useTheme } from "@mui/material";
|
||||
import { useState, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HeaderTeamControls } from "./components/HeaderTeamControls";
|
||||
import { TeamTable } from "./components/TeamTable";
|
||||
import { InviteTeamMemberDialog } from "./components/InviteTeamMemberDialog";
|
||||
import { AddTeamMemberDialog } from "./components/AddTeamMemberDialog";
|
||||
import { EmptyState } from "@/Components/design-elements";
|
||||
import { useGet } from "@/Hooks/UseApi";
|
||||
import type { User, UserRole } from "@/Types/User";
|
||||
|
||||
export const TabTeam = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const [filter, setFilter] = useState<UserRole | "">("");
|
||||
const [inviteDialogOpen, setInviteDialogOpen] = useState(false);
|
||||
const [addMemberDialogOpen, setAddMemberDialogOpen] = useState(false);
|
||||
@@ -33,6 +36,9 @@ export const TabTeam = () => {
|
||||
refetch();
|
||||
};
|
||||
|
||||
const totalUsers = users?.length ?? 0;
|
||||
const noUsers = users !== undefined && totalUsers === 0;
|
||||
|
||||
return (
|
||||
<Stack gap={theme.spacing(8)}>
|
||||
<HeaderTeamControls
|
||||
@@ -41,7 +47,15 @@ export const TabTeam = () => {
|
||||
onInviteClick={handleOpenInviteDialog}
|
||||
onAddMemberClick={handleOpenAddMemberDialog}
|
||||
/>
|
||||
<TeamTable users={filteredUsers} />
|
||||
{noUsers ? (
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={t("pages.account.team.fallback.title")}
|
||||
description={t("pages.account.team.fallback.description")}
|
||||
/>
|
||||
) : (
|
||||
<TeamTable users={filteredUsers} />
|
||||
)}
|
||||
<InviteTeamMemberDialog
|
||||
open={inviteDialogOpen}
|
||||
onClose={handleCloseInviteDialog}
|
||||
|
||||
@@ -43,6 +43,7 @@ export const AddTeamMemberDialog = ({
|
||||
const roleOptions: { value: UserRole; label: string }[] = [
|
||||
{ value: "admin", label: t("common.auth.roles.admin") },
|
||||
{ value: "user", label: t("common.auth.roles.user") },
|
||||
{ value: "demo", label: t("common.auth.roles.demo") },
|
||||
];
|
||||
|
||||
const handleClose = () => {
|
||||
|
||||
@@ -48,6 +48,7 @@ export const InviteTeamMemberDialog = ({
|
||||
const roleOptions: { value: UserRole; label: string }[] = [
|
||||
{ value: "admin", label: t("common.auth.roles.admin") },
|
||||
{ value: "user", label: t("common.auth.roles.user") },
|
||||
{ value: "demo", label: t("common.auth.roles.demo") },
|
||||
];
|
||||
|
||||
const handleGenerateToken = async (data: InviteFormData) => {
|
||||
|
||||
@@ -2,8 +2,10 @@ import Typography from "@mui/material/Typography";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Table } from "@/Components/design-elements";
|
||||
import { Pagination } from "@/Components/design-elements/Table";
|
||||
import type { Header } from "@/Components/design-elements/Table";
|
||||
import { useIsAdmin } from "@/Hooks/useIsAdmin";
|
||||
import { useClientPagination } from "@/Hooks/useClientPagination";
|
||||
import type { User } from "@/Types/User";
|
||||
|
||||
interface TeamTableProps {
|
||||
@@ -14,6 +16,7 @@ export const TeamTable = ({ users }: TeamTableProps) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const isAdmin = useIsAdmin();
|
||||
const { pagedRows, paginationProps } = useClientPagination(users);
|
||||
|
||||
const headers: Header<User>[] = [
|
||||
{
|
||||
@@ -51,10 +54,13 @@ export const TeamTable = ({ users }: TeamTableProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Table
|
||||
headers={headers}
|
||||
data={users}
|
||||
onRowClick={isAdmin ? handleRowClick : undefined}
|
||||
/>
|
||||
<>
|
||||
<Table
|
||||
headers={headers}
|
||||
data={pagedRows}
|
||||
onRowClick={isAdmin ? handleRowClick : undefined}
|
||||
/>
|
||||
{users.length > 0 && <Pagination {...paginationProps} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -25,7 +25,7 @@ const Account = ({ open = "profile" }: AccountProps) => {
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<BasePage>
|
||||
<BasePage headerKey="account">
|
||||
<Tabs
|
||||
value={activeTab}
|
||||
onChange={(_, newValue: number) => setActiveTab(newValue)}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BaseAuthPage, TextLink } from "@/Components/design-elements";
|
||||
import { Button, TextField } from "@/Components/inputs";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod/dist/zod.js";
|
||||
@@ -9,7 +10,7 @@ import type { LoginFormData } from "@/Validation/login";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { setAuthState } from "@/Features/Auth/authSlice";
|
||||
import { usePost } from "@/Hooks/UseApi";
|
||||
import { useLazyGet, usePost } from "@/Hooks/UseApi";
|
||||
|
||||
const LoginPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -17,6 +18,17 @@ const LoginPage = () => {
|
||||
const navigate = useNavigate();
|
||||
const { post, loading } = usePost();
|
||||
|
||||
const [isCheckingAdmin, setIsCheckingAdmin] = useState(true);
|
||||
const { get } = useLazyGet<boolean>();
|
||||
|
||||
useEffect(() => {
|
||||
get("/auth/users/superadmin").then((res) => {
|
||||
if (res?.data === false) navigate("/register", { replace: true });
|
||||
else setIsCheckingAdmin(false);
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const { schema, defaults } = useLoginForm();
|
||||
|
||||
const { control, handleSubmit } = useForm<LoginFormData>({
|
||||
@@ -24,6 +36,8 @@ const LoginPage = () => {
|
||||
defaultValues: defaults,
|
||||
});
|
||||
|
||||
if (isCheckingAdmin) return null;
|
||||
|
||||
const onSubmit = async (data: LoginFormData) => {
|
||||
if (loading) return;
|
||||
|
||||
@@ -82,12 +96,6 @@ const LoginPage = () => {
|
||||
linkText={t("pages.auth.login.links.forgotPassword.linkText")}
|
||||
href="/forgot-password"
|
||||
/>
|
||||
<TextLink
|
||||
alignSelf={"center"}
|
||||
text={t("pages.auth.login.links.register.text")}
|
||||
linkText={t("pages.auth.login.links.register.linkText")}
|
||||
href="/register"
|
||||
/>
|
||||
</BaseAuthPage>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { BaseAuthPage } from "@/Components/design-elements";
|
||||
import { Button, TextField } from "@/Components/inputs";
|
||||
import Alert from "@mui/material/Alert";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod/dist/zod.js";
|
||||
import { useRegisterForm } from "@/Hooks/useRegisterForm";
|
||||
import type { RegisterFormData } from "@/Validation/register";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { usePost, useGet } from "@/Hooks/UseApi";
|
||||
import { useLazyGet, usePost } from "@/Hooks/UseApi";
|
||||
import { setAuthState } from "@/Features/Auth/authSlice";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import type { AuthResponse } from "@/Types/User";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
interface RegisterPayload {
|
||||
user: Omit<RegisterFormData, "confirm">;
|
||||
@@ -32,21 +33,23 @@ const RegisterPage = () => {
|
||||
const { post: verifyToken } = usePost<{ token: string }, InviteVerifyResponse>();
|
||||
const hasVerified = useRef(false);
|
||||
|
||||
const { data: superAdminExists, isLoading: isCheckingAdmin } = useGet<boolean>(
|
||||
token ? null : "/auth/users/superadmin"
|
||||
);
|
||||
const [isCheckingAdmin, setIsCheckingAdmin] = useState(!token);
|
||||
const { get } = useLazyGet<boolean>();
|
||||
|
||||
useEffect(() => {
|
||||
if (token) return;
|
||||
get("/auth/users/superadmin").then((res) => {
|
||||
if (res?.data === true) navigate("/login", { replace: true });
|
||||
else setIsCheckingAdmin(false);
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const { control, handleSubmit, setError, reset } = useForm<RegisterFormData>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: defaults,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (superAdminExists === true) {
|
||||
navigate("/login", { replace: true });
|
||||
}
|
||||
}, [superAdminExists, navigate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!token || hasVerified.current) return;
|
||||
hasVerified.current = true;
|
||||
@@ -92,6 +95,23 @@ const RegisterPage = () => {
|
||||
title={t("pages.auth.register.title")}
|
||||
subtitle={t("pages.auth.register.subtitle")}
|
||||
>
|
||||
{!token && (
|
||||
<Alert
|
||||
severity="info"
|
||||
icon={false}
|
||||
sx={(theme) => ({
|
||||
fontSize: 13,
|
||||
lineHeight: 1.55,
|
||||
color: theme.palette.text.secondary,
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: 1,
|
||||
"& .MuiAlert-message": { padding: 0 },
|
||||
})}
|
||||
>
|
||||
{t("pages.auth.register.setupNotice")}
|
||||
</Alert>
|
||||
)}
|
||||
<Controller
|
||||
name="firstName"
|
||||
control={control}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import {
|
||||
BasePage,
|
||||
EmptyState,
|
||||
TotalChecksBox,
|
||||
UpChecksBox,
|
||||
DownChecksBox,
|
||||
@@ -102,8 +103,19 @@ const Checks = () => {
|
||||
const downChecks = summaryResponse?.downChecks || 0;
|
||||
const upChecks = totalChecks - (summaryResponse?.downChecks || 0);
|
||||
|
||||
const noMonitors = !isLoadingMonitors && (monitorsResponse?.length ?? 0) === 0;
|
||||
if (noMonitors) {
|
||||
return (
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={t("pages.checks.fallback.title")}
|
||||
description={t("pages.checks.fallback.description")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BasePage>
|
||||
<BasePage headerKey="checks">
|
||||
<Stack
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
gap={4}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BasePage } from "@/Components/design-elements";
|
||||
import { BasePage, EmptyState } from "@/Components/design-elements";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Divider from "@mui/material/Divider";
|
||||
@@ -153,8 +153,20 @@ const IncidentsPage = () => {
|
||||
refetchSummary();
|
||||
};
|
||||
|
||||
const trulyEmpty = summaryData !== undefined && (summaryData?.total ?? 0) === 0;
|
||||
|
||||
if (trulyEmpty) {
|
||||
return (
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={t("pages.incidents.fallback.title")}
|
||||
description={t("pages.incidents.fallback.description")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BasePage>
|
||||
<BasePage headerKey="incidents">
|
||||
<Stack
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
gap={theme.spacing(8)}
|
||||
@@ -171,7 +183,7 @@ const IncidentsPage = () => {
|
||||
setSelectedResolutionType={setFilter}
|
||||
onClearFilters={handleClearFilters}
|
||||
/>
|
||||
{activeIncidentsCount > 0 ? (
|
||||
{activeIncidentsCount > 0 && (
|
||||
<>
|
||||
<Typography
|
||||
variant="h6"
|
||||
@@ -193,13 +205,6 @@ const IncidentsPage = () => {
|
||||
/>
|
||||
<Divider />
|
||||
</>
|
||||
) : (
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{ mb: theme.spacing(4), color: theme.palette.success.main }}
|
||||
>
|
||||
{t("pages.incidents.summaryCard.activeIncidents.active_zero")}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Typography
|
||||
|
||||
@@ -80,14 +80,6 @@ export const InfraMonitorsTable = ({
|
||||
|
||||
const getActions = (monitor: Monitor): ActionMenuItem[] => {
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
label: t("pages.common.monitors.actions.openSite"),
|
||||
action: () => {
|
||||
window.open(monitor.url, "_blank", "noreferrer");
|
||||
},
|
||||
closeMenu: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: t("pages.common.monitors.actions.details"),
|
||||
|
||||
@@ -122,6 +122,7 @@ const InfrastructureMonitors = () => {
|
||||
|
||||
return (
|
||||
<MonitorBasePageWithStates
|
||||
headerKey="infrastructure"
|
||||
loading={isLoading}
|
||||
error={monitorsWithChecksError}
|
||||
totalCount={effectiveTotalCount}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { Stats } from "@/Pages/Logs/components/Stats";
|
||||
import { StatGauges } from "@/Pages/Logs/components/StatGauges";
|
||||
|
||||
import { useTheme } from "@mui/material";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useGet } from "@/Hooks/UseApi";
|
||||
import type { Diagnostics } from "@/Types/Diagnostics";
|
||||
|
||||
export const TabDiagnostics = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
data: diagnostics,
|
||||
isLoading: _isLoading,
|
||||
@@ -16,9 +19,35 @@ export const TabDiagnostics = () => {
|
||||
} = useGet<Diagnostics>("/diagnostic/system", {}, { refreshInterval: 5000 });
|
||||
|
||||
return (
|
||||
<Stack gap={theme.spacing(8)}>
|
||||
<Stats diagnostics={diagnostics} />
|
||||
<StatGauges diagnostics={diagnostics} />
|
||||
<Stack gap={theme.spacing(12)}>
|
||||
<Stack gap={theme.spacing(4)}>
|
||||
<Stack gap={theme.spacing(1)}>
|
||||
<Typography
|
||||
variant="eyebrow"
|
||||
color="text.secondary"
|
||||
>
|
||||
{t("pages.logs.diagnostics.sections.runtimeStats.title")}
|
||||
</Typography>
|
||||
<Typography color={theme.palette.text.secondary}>
|
||||
{t("pages.logs.diagnostics.sections.runtimeStats.description")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stats diagnostics={diagnostics} />
|
||||
</Stack>
|
||||
<Stack gap={theme.spacing(4)}>
|
||||
<Stack gap={theme.spacing(1)}>
|
||||
<Typography
|
||||
variant="eyebrow"
|
||||
color="text.secondary"
|
||||
>
|
||||
{t("pages.logs.diagnostics.sections.memoryCpu.title")}
|
||||
</Typography>
|
||||
<Typography color={theme.palette.text.secondary}>
|
||||
{t("pages.logs.diagnostics.sections.memoryCpu.description")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<StatGauges diagnostics={diagnostics} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -4,6 +4,7 @@ import Typography from "@mui/material/Typography";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Select } from "@/Components/inputs";
|
||||
import { TableLogs } from "@/Pages/Logs/components/TableLogs";
|
||||
import { EmptyState } from "@/Components/design-elements";
|
||||
|
||||
import { useTheme } from "@mui/material";
|
||||
import { useGet } from "@/Hooks/UseApi";
|
||||
@@ -15,7 +16,7 @@ import type { RootState } from "@/Types/state";
|
||||
|
||||
export const TabLogs = () => {
|
||||
const theme = useTheme();
|
||||
const { data: logs } = useGet<Log[]>("/logs");
|
||||
const { data: logs, isLoading } = useGet<Log[]>("/logs");
|
||||
const [selectedLogLevel, setSelectedLogLevel] = useState<LogLevelOption>("all");
|
||||
const [page, setPage] = useState(0);
|
||||
const rowsPerPage = useSelector(
|
||||
@@ -33,6 +34,16 @@ export const TabLogs = () => {
|
||||
const paginatedLogs =
|
||||
filteredLogs?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) ?? [];
|
||||
|
||||
if (!isLoading && (logs?.length ?? 0) === 0) {
|
||||
return (
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={t("pages.logs.fallback.title")}
|
||||
description={t("pages.logs.fallback.description")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack gap={theme.spacing(8)}>
|
||||
<Select
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Box from "@mui/material/Box";
|
||||
import { TableJobs, TableFailedJobs } from "./components/TableJobs";
|
||||
|
||||
import { useTheme } from "@mui/material";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import { useGet, usePost } from "@/Hooks/UseApi";
|
||||
import type { QueueData } from "@/Types/Queue";
|
||||
import { Metrics } from "@/Pages/Logs/components/Metrics";
|
||||
import { Button } from "@/Components/inputs";
|
||||
import { EmptyState } from "@/Components/design-elements";
|
||||
|
||||
export const TabQueue = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
data: queueData,
|
||||
// isLoading,
|
||||
isLoading,
|
||||
// error,
|
||||
refetch,
|
||||
} = useGet<QueueData>("/queue/all-metrics", {}, { refreshInterval: 5000 });
|
||||
@@ -23,6 +25,17 @@ export const TabQueue = () => {
|
||||
|
||||
const jobs = queueData?.jobs ?? [];
|
||||
const metrics = queueData?.metrics ?? null;
|
||||
const hasNeverRun = !isLoading && metrics !== null && (metrics.totalRuns ?? 0) === 0;
|
||||
const noQueueData = !isLoading && metrics === null && jobs.length === 0;
|
||||
if (hasNeverRun || noQueueData) {
|
||||
return (
|
||||
<EmptyState
|
||||
fullscreen
|
||||
title={t("pages.logs.queueFallback.title")}
|
||||
description={t("pages.logs.queueFallback.description")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const handleFlushQueue = async () => {
|
||||
await post("/queue/flush", {});
|
||||
@@ -30,22 +43,65 @@ export const TabQueue = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap={theme.spacing(8)}>
|
||||
<Stack gap={theme.spacing(16)}>
|
||||
<Metrics metrics={metrics} />
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ textTransform: "uppercase" }}
|
||||
>
|
||||
{t("pages.logs.jobQueue")}
|
||||
</Typography>
|
||||
<TableJobs jobs={jobs} />
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ textTransform: "uppercase" }}
|
||||
>
|
||||
{t("pages.logs.failedJobs")}
|
||||
</Typography>
|
||||
<TableFailedJobs metrics={metrics} />
|
||||
<Stack gap={theme.spacing(3)}>
|
||||
<Stack gap={theme.spacing(1)}>
|
||||
<Typography
|
||||
variant="eyebrow"
|
||||
color="text.secondary"
|
||||
>
|
||||
{t("pages.logs.jobQueue")}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 13,
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
<Trans
|
||||
i18nKey="pages.logs.jobQueueExplainer"
|
||||
components={{
|
||||
highlight: (
|
||||
<Box
|
||||
component="span"
|
||||
sx={{
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark"
|
||||
? "rgba(19, 113, 91, 0.18)"
|
||||
: "#ECF7F2",
|
||||
color: theme.palette.text.primary,
|
||||
px: 1,
|
||||
py: 0.25,
|
||||
borderRadius: 0.5,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Typography>
|
||||
</Stack>
|
||||
<TableJobs jobs={jobs} />
|
||||
</Stack>
|
||||
<Stack gap={theme.spacing(3)}>
|
||||
<Stack gap={theme.spacing(1)}>
|
||||
<Typography
|
||||
variant="eyebrow"
|
||||
color="text.secondary"
|
||||
>
|
||||
{t("pages.logs.failedJobs")}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: 13,
|
||||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
{t("pages.logs.failedJobsExplainer")}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<TableFailedJobs metrics={metrics} />
|
||||
</Stack>
|
||||
<Stack alignItems={"flex-end"}>
|
||||
<Button
|
||||
variant="contained"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Box from "@mui/material/Box";
|
||||
import { DetailGauge } from "@/Components/design-elements";
|
||||
|
||||
import { getPercentage, formatPercentageFromWhole } from "@/Utils/FormatUtils";
|
||||
@@ -11,62 +11,78 @@ interface StatGaugesProps {
|
||||
diagnostics: Diagnostics | null;
|
||||
}
|
||||
|
||||
const PLACEHOLDER = "—";
|
||||
|
||||
export const StatGauges = ({ diagnostics }: StatGaugesProps) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
if (!diagnostics) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const heapTotalSize = getPercentage(
|
||||
diagnostics?.v8HeapStats?.totalHeapSizeBytes,
|
||||
diagnostics?.v8HeapStats?.heapSizeLimitBytes
|
||||
);
|
||||
const heapTotalSize = diagnostics
|
||||
? getPercentage(
|
||||
diagnostics.v8HeapStats?.totalHeapSizeBytes,
|
||||
diagnostics.v8HeapStats?.heapSizeLimitBytes
|
||||
)
|
||||
: 0;
|
||||
const heapUsedSize = diagnostics
|
||||
? getPercentage(
|
||||
diagnostics.v8HeapStats?.usedHeapSizeBytes,
|
||||
diagnostics.v8HeapStats?.heapSizeLimitBytes
|
||||
)
|
||||
: 0;
|
||||
const actualHeapUsed = diagnostics
|
||||
? getPercentage(
|
||||
diagnostics.v8HeapStats?.usedHeapSizeBytes,
|
||||
diagnostics.v8HeapStats?.totalHeapSizeBytes
|
||||
)
|
||||
: 0;
|
||||
const cpuUsage = diagnostics?.cpuUsage?.usagePercentage ?? 0;
|
||||
|
||||
const heapUsedSize = getPercentage(
|
||||
diagnostics?.v8HeapStats?.usedHeapSizeBytes,
|
||||
diagnostics?.v8HeapStats?.heapSizeLimitBytes
|
||||
);
|
||||
|
||||
const actualHeapUsed = getPercentage(
|
||||
diagnostics?.v8HeapStats?.usedHeapSizeBytes,
|
||||
diagnostics?.v8HeapStats?.totalHeapSizeBytes
|
||||
);
|
||||
const fmt = (n: number) => (diagnostics ? formatPercentageFromWhole(n) : PLACEHOLDER);
|
||||
const bytes = (n: number | undefined) =>
|
||||
diagnostics ? prettyBytes(n ?? 0) : PLACEHOLDER;
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
gap={theme.spacing(8)}
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: { xs: "1fr", md: "repeat(4, 1fr)" },
|
||||
gap: theme.spacing(8),
|
||||
"& > *": { width: "100% !important" },
|
||||
}}
|
||||
>
|
||||
<DetailGauge
|
||||
maxWidth={9999}
|
||||
title={t("pages.logs.diagnostics.gauges.heapAllocation")}
|
||||
progress={heapTotalSize}
|
||||
upperValue={formatPercentageFromWhole(heapTotalSize)}
|
||||
upperValue={fmt(heapTotalSize)}
|
||||
lowerLabel={t("pages.logs.diagnostics.gauges.total")}
|
||||
lowerValue={prettyBytes(diagnostics.v8HeapStats?.heapSizeLimitBytes ?? 0)}
|
||||
lowerValue={bytes(diagnostics?.v8HeapStats?.heapSizeLimitBytes)}
|
||||
/>
|
||||
<DetailGauge
|
||||
maxWidth={9999}
|
||||
title={t("pages.logs.diagnostics.gauges.heapUsage")}
|
||||
progress={heapUsedSize}
|
||||
upperLabel={t("pages.logs.diagnostics.gauges.availableMemoryPercentage")}
|
||||
upperValue={formatPercentageFromWhole(heapUsedSize)}
|
||||
upperValue={fmt(heapUsedSize)}
|
||||
lowerLabel={t("pages.logs.diagnostics.gauges.used")}
|
||||
lowerValue={prettyBytes(diagnostics.v8HeapStats?.usedHeapSizeBytes ?? 0)}
|
||||
lowerValue={bytes(diagnostics?.v8HeapStats?.usedHeapSizeBytes)}
|
||||
/>
|
||||
<DetailGauge
|
||||
maxWidth={9999}
|
||||
title={t("pages.logs.diagnostics.gauges.heapUtilization")}
|
||||
progress={actualHeapUsed}
|
||||
upperLabel={t("pages.logs.diagnostics.gauges.allocatedPercentage")}
|
||||
upperValue={formatPercentageFromWhole(actualHeapUsed)}
|
||||
upperValue={fmt(actualHeapUsed)}
|
||||
lowerLabel={t("pages.logs.diagnostics.gauges.total")}
|
||||
lowerValue={prettyBytes(diagnostics.v8HeapStats?.usedHeapSizeBytes ?? 0)}
|
||||
lowerValue={bytes(diagnostics?.v8HeapStats?.usedHeapSizeBytes)}
|
||||
/>
|
||||
<DetailGauge
|
||||
maxWidth={9999}
|
||||
title={t("pages.logs.diagnostics.gauges.instantCpuUsage")}
|
||||
progress={diagnostics.cpuUsage?.usagePercentage ?? 0}
|
||||
progress={cpuUsage}
|
||||
upperLabel={t("pages.logs.diagnostics.gauges.usedSPercentage")}
|
||||
upperValue={formatPercentageFromWhole(diagnostics.cpuUsage?.usagePercentage ?? 0)}
|
||||
upperValue={fmt(cpuUsage)}
|
||||
/>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Box from "@mui/material/Box";
|
||||
import { StatBox } from "@/Components/design-elements";
|
||||
|
||||
import prettyBytes from "pretty-bytes";
|
||||
@@ -11,41 +11,59 @@ interface StatsProps {
|
||||
diagnostics: Diagnostics | null;
|
||||
}
|
||||
|
||||
const PLACEHOLDER = "—";
|
||||
|
||||
export const Stats = ({ diagnostics }: StatsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
|
||||
if (!diagnostics) {
|
||||
return null;
|
||||
}
|
||||
const eventLoopDelay = diagnostics
|
||||
? prettyMilliseconds(diagnostics.eventLoopDelayMs ?? 0, {
|
||||
millisecondsDecimalDigits: 2,
|
||||
})
|
||||
: PLACEHOLDER;
|
||||
const uptime = diagnostics
|
||||
? prettyMilliseconds(diagnostics.uptimeMs ?? 0, { hideSeconds: true })
|
||||
: PLACEHOLDER;
|
||||
const usedHeap = diagnostics
|
||||
? prettyBytes(diagnostics.v8HeapStats?.usedHeapSizeBytes ?? 0)
|
||||
: PLACEHOLDER;
|
||||
const totalHeap = diagnostics
|
||||
? prettyBytes(diagnostics.v8HeapStats?.totalHeapSizeBytes ?? 0)
|
||||
: PLACEHOLDER;
|
||||
const osMemory = diagnostics
|
||||
? prettyBytes(diagnostics.osStats?.totalMemoryBytes ?? 0)
|
||||
: PLACEHOLDER;
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
gap={theme.spacing(8)}
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: { xs: "1fr", md: "repeat(5, 1fr)" },
|
||||
gap: theme.spacing(8),
|
||||
"& > *": { width: "100% !important" },
|
||||
}}
|
||||
>
|
||||
<StatBox
|
||||
title={t("pages.logs.diagnostics.stats.eventLoopDelay")}
|
||||
subtitle={prettyMilliseconds(diagnostics.eventLoopDelayMs ?? 0, {
|
||||
millisecondsDecimalDigits: 2,
|
||||
})}
|
||||
subtitle={eventLoopDelay}
|
||||
/>
|
||||
<StatBox
|
||||
title={t("pages.logs.diagnostics.stats.uptime")}
|
||||
subtitle={prettyMilliseconds(diagnostics.uptimeMs ?? 0, { hideSeconds: true })}
|
||||
subtitle={uptime}
|
||||
/>
|
||||
<StatBox
|
||||
title={t("pages.logs.diagnostics.stats.usedHeapSize")}
|
||||
subtitle={prettyBytes(diagnostics.v8HeapStats?.usedHeapSizeBytes ?? 0)}
|
||||
subtitle={usedHeap}
|
||||
/>
|
||||
<StatBox
|
||||
title={t("pages.logs.diagnostics.stats.totalHeapSize")}
|
||||
subtitle={prettyBytes(diagnostics.v8HeapStats?.totalHeapSizeBytes ?? 0)}
|
||||
subtitle={totalHeap}
|
||||
/>
|
||||
<StatBox
|
||||
title={t("pages.logs.diagnostics.stats.osMemoryLimit")}
|
||||
subtitle={prettyBytes(diagnostics.osStats?.totalMemoryBytes ?? 0)}
|
||||
subtitle={osMemory}
|
||||
/>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -22,77 +22,92 @@ export const TableJobs = ({ jobs }: TableJobsProps) => {
|
||||
id: job.monitorId,
|
||||
}));
|
||||
|
||||
const cellSx = {
|
||||
whiteSpace: "nowrap" as const,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
maxWidth: 220,
|
||||
};
|
||||
|
||||
const headers: Header<QueueJobWithId>[] = [
|
||||
{
|
||||
id: "id",
|
||||
content: t("common.table.headers.monitorId"),
|
||||
render: (row) => <Typography fontFamily={"monospace"}>{row.monitorId}</Typography>,
|
||||
render: (row) => (
|
||||
<Typography
|
||||
fontFamily={theme.typography.fontFamilyMonospace}
|
||||
title={String(row.monitorId)}
|
||||
sx={cellSx}
|
||||
>
|
||||
{row.monitorId}
|
||||
</Typography>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "url",
|
||||
content: t("common.table.headers.url"),
|
||||
render: (row) => <Typography>{row.monitorUrl}</Typography>,
|
||||
},
|
||||
{
|
||||
id: "interval",
|
||||
content: t("common.table.headers.interval"),
|
||||
render: (row) => (
|
||||
<Typography>{prettyMilliseconds(row.monitorInterval ?? 0)}</Typography>
|
||||
<Typography title={row.monitorUrl ?? ""} sx={cellSx}>
|
||||
{row.monitorUrl}
|
||||
</Typography>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "type",
|
||||
content: t("common.table.headers.type"),
|
||||
render: (row) => <Typography>{row.monitorType}</Typography>,
|
||||
render: (row) => <Typography sx={cellSx}>{row.monitorType}</Typography>,
|
||||
},
|
||||
{
|
||||
id: "active",
|
||||
content: t("common.table.headers.active"),
|
||||
render: (row) => <Typography>{row.active.toString()}</Typography>,
|
||||
},
|
||||
{
|
||||
id: "runCount",
|
||||
content: t("pages.logs.table.headers.runCount"),
|
||||
render: (row) => <Typography>{row.runCount}</Typography>,
|
||||
},
|
||||
{
|
||||
id: "failCount",
|
||||
content: t("pages.logs.table.headers.failCount"),
|
||||
render: (row) => <Typography>{row.failCount}</Typography>,
|
||||
id: "interval",
|
||||
content: t("common.table.headers.interval"),
|
||||
render: (row) => (
|
||||
<Typography sx={cellSx}>{prettyMilliseconds(row.monitorInterval ?? 0)}</Typography>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "lastRun",
|
||||
content: t("pages.logs.table.headers.lastRunAt"),
|
||||
render: (row) => <Typography>{formatTimestamp(row.lastRunAt)}</Typography>,
|
||||
},
|
||||
{
|
||||
id: "lockedAt",
|
||||
content: t("pages.logs.table.headers.lockedAt"),
|
||||
render: (row) => <Typography>{formatTimestamp(row.lockedAt)}</Typography>,
|
||||
},
|
||||
|
||||
{
|
||||
id: "lastFinish",
|
||||
content: t("pages.logs.table.headers.lastFinishedAt"),
|
||||
render: (row) => <Typography>{formatTimestamp(row.lastFinishedAt)}</Typography>,
|
||||
render: (row) => {
|
||||
const v = formatTimestamp(row.lastRunAt) ?? "-";
|
||||
return (
|
||||
<Typography title={v} sx={cellSx}>
|
||||
{v}
|
||||
</Typography>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "lastRunTook",
|
||||
content: t("pages.logs.table.headers.lastRunTook"),
|
||||
render: (row) => {
|
||||
const value = row.lastRunTook ? prettyMilliseconds(row.lastRunTook) : "-";
|
||||
return <Typography>{value}</Typography>;
|
||||
return <Typography sx={cellSx}>{value}</Typography>;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "lockedAt",
|
||||
content: t("pages.logs.table.headers.lockedAt"),
|
||||
render: (row) => {
|
||||
const v = formatTimestamp(row.lockedAt) ?? "-";
|
||||
return (
|
||||
<Typography title={v} sx={cellSx}>
|
||||
{v}
|
||||
</Typography>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const isDark = theme.palette.mode === "dark";
|
||||
const runningBg = isDark ? "rgba(19, 113, 91, 0.18)" : "#ECF7F2";
|
||||
|
||||
return (
|
||||
<Table
|
||||
headers={headers}
|
||||
data={jobsWithId}
|
||||
getRowSx={(row) => ({
|
||||
...(row.lockedAt && {
|
||||
"& td": { backgroundColor: theme.palette.success.light },
|
||||
"& td": { backgroundColor: runningBg },
|
||||
}),
|
||||
})}
|
||||
/>
|
||||
@@ -106,6 +121,7 @@ interface TableFailedJobsProps {
|
||||
}
|
||||
export const TableFailedJobs = ({ metrics }: TableFailedJobsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
if (!metrics) {
|
||||
return null;
|
||||
}
|
||||
@@ -122,7 +138,11 @@ export const TableFailedJobs = ({ metrics }: TableFailedJobsProps) => {
|
||||
id: "monitorId",
|
||||
content: t("common.table.headers.monitorId"),
|
||||
render: (row) => {
|
||||
return <Typography fontFamily={"monospace"}>{row.monitorId}</Typography>;
|
||||
return (
|
||||
<Typography fontFamily={theme.typography.fontFamilyMonospace}>
|
||||
{row.monitorId}
|
||||
</Typography>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@ const LevelBadge = ({ level }: { level: LogLevel }) => {
|
||||
|
||||
export const TableLogs = ({ logs, logCount, page, setPage }: TableLogsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const rowsPerPage = useSelector(
|
||||
(state: RootState) => state?.ui?.logs?.rowsPerPage ?? 15
|
||||
@@ -55,7 +56,7 @@ export const TableLogs = ({ logs, logCount, page, setPage }: TableLogsProps) =>
|
||||
id: "timestamp",
|
||||
content: t("pages.logs.table.headers.timestamp"),
|
||||
render: (row) => (
|
||||
<Typography sx={{ fontFamily: "monospace" }}>
|
||||
<Typography sx={{ fontFamily: theme.typography.fontFamilyMonospace }}>
|
||||
{formatTimestamp(row.timestamp)}
|
||||
</Typography>
|
||||
),
|
||||
@@ -74,7 +75,9 @@ export const TableLogs = ({ logs, logCount, page, setPage }: TableLogsProps) =>
|
||||
id: "method",
|
||||
content: t("pages.logs.table.headers.method"),
|
||||
render: (row) => (
|
||||
<Typography fontFamily={"monospace"}>{row.method || "-"}</Typography>
|
||||
<Typography fontFamily={theme.typography.fontFamilyMonospace}>
|
||||
{row.method || "-"}
|
||||
</Typography>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ const LogsPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const [activeTab, setActiveTab] = useState<number>(1);
|
||||
return (
|
||||
<BasePage>
|
||||
<BasePage headerKey="logs">
|
||||
<Tabs
|
||||
value={activeTab}
|
||||
onChange={(_, newValue: number) => setActiveTab(newValue)}
|
||||
|
||||
@@ -32,11 +32,10 @@ const MaintenanceWindowPage = () => {
|
||||
|
||||
return (
|
||||
<BasePageWithStates
|
||||
headerKey="maintenanceWindow"
|
||||
page={t("pages.maintenanceWindow.fallback.title")}
|
||||
totalCount={maintenanceWindowCount}
|
||||
bullets={
|
||||
t("pages.maintenanceWindow.fallback.checks", { returnObjects: true }) as string[]
|
||||
}
|
||||
description={t("pages.maintenanceWindow.fallback.description")}
|
||||
loading={isLoading}
|
||||
error={!!error}
|
||||
actionButtonText={t("pages.maintenanceWindow.fallback.actionButton")}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { ActionsMenu, type ActionMenuItem } from "@/Components/actions-menu";
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import type { Header } from "@/Components/design-elements/Table";
|
||||
import { Table } from "@/Components/design-elements";
|
||||
import { Pagination } from "@/Components/design-elements/Table";
|
||||
import { useClientPagination } from "@/Hooks/useClientPagination";
|
||||
|
||||
import type { Notification } from "@/Types/Notification";
|
||||
import { useNavigate } from "react-router";
|
||||
@@ -20,6 +23,7 @@ export const NotificationsTable = ({
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const { pagedRows, paginationProps } = useClientPagination(notifications);
|
||||
|
||||
const getActions = (channel: Notification): ActionMenuItem[] => {
|
||||
return [
|
||||
@@ -68,7 +72,23 @@ export const NotificationsTable = ({
|
||||
id: "destination",
|
||||
content: t("pages.notifications.table.headers.destination"),
|
||||
render: (row) => {
|
||||
return <Typography>{row?.address}</Typography>;
|
||||
return (
|
||||
<Box sx={{ maxWidth: 320, mx: "auto" }}>
|
||||
<Typography
|
||||
title={row?.address}
|
||||
sx={{
|
||||
direction: "rtl",
|
||||
textAlign: "left",
|
||||
unicodeBidi: "plaintext",
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}}
|
||||
>
|
||||
{row?.address}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -82,15 +102,16 @@ export const NotificationsTable = ({
|
||||
return headers;
|
||||
};
|
||||
|
||||
const headers = getHeaders();
|
||||
|
||||
return (
|
||||
<Table
|
||||
headers={headers}
|
||||
data={notifications}
|
||||
onRowClick={(row) => {
|
||||
navigate(`/notifications/configure/${row.id}`);
|
||||
}}
|
||||
/>
|
||||
<>
|
||||
<Table
|
||||
headers={getHeaders()}
|
||||
data={pagedRows}
|
||||
onRowClick={(row) => {
|
||||
navigate(`/notifications/configure/${row.id}`);
|
||||
}}
|
||||
/>
|
||||
{notifications.length > 0 && <Pagination {...paginationProps} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -147,30 +147,33 @@ const NotificationsCreatePage = () => {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{watchedType !== "matrix" && watchedType !== "telegram" && (
|
||||
<ConfigBox
|
||||
title={addressConfig.title}
|
||||
subtitle={addressConfig.description}
|
||||
rightContent={
|
||||
<Controller
|
||||
name="address"
|
||||
control={control}
|
||||
defaultValue={"address" in defaults ? defaults.address : ""}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={addressConfig.fieldLabel}
|
||||
placeholder={addressConfig.placeholder}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{watchedType !== "matrix" &&
|
||||
watchedType !== "telegram" &&
|
||||
watchedType !== "pushover" &&
|
||||
watchedType !== "twilio" && (
|
||||
<ConfigBox
|
||||
title={addressConfig.title}
|
||||
subtitle={addressConfig.description}
|
||||
rightContent={
|
||||
<Controller
|
||||
name="address"
|
||||
control={control}
|
||||
defaultValue={"address" in defaults ? defaults.address : ""}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={addressConfig.fieldLabel}
|
||||
placeholder={addressConfig.placeholder}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{watchedType === "telegram" && (
|
||||
<ConfigBox
|
||||
title={t("pages.notifications.form.telegram.title")}
|
||||
@@ -214,6 +217,134 @@ const NotificationsCreatePage = () => {
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{watchedType === "pushover" && (
|
||||
<ConfigBox
|
||||
title={t("pages.notifications.form.pushover.title")}
|
||||
subtitle={t("pages.notifications.form.pushover.description")}
|
||||
rightContent={
|
||||
<Stack spacing={theme.spacing(8)}>
|
||||
<Controller
|
||||
name="accessToken"
|
||||
control={control}
|
||||
defaultValue={"accessToken" in defaults ? defaults.accessToken : ""}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={t("pages.notifications.form.pushover.optionAppToken")}
|
||||
placeholder={t(
|
||||
"pages.notifications.form.pushover.placeholderAppToken"
|
||||
)}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="address"
|
||||
control={control}
|
||||
defaultValue={"address" in defaults ? defaults.address : ""}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={t("pages.notifications.form.pushover.optionUserKey")}
|
||||
placeholder={t(
|
||||
"pages.notifications.form.pushover.placeholderUserKey"
|
||||
)}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{watchedType === "twilio" && (
|
||||
<ConfigBox
|
||||
title={t("pages.notifications.form.twilio.title")}
|
||||
subtitle={t("pages.notifications.form.twilio.description")}
|
||||
rightContent={
|
||||
<Stack spacing={theme.spacing(8)}>
|
||||
<Controller
|
||||
name="accountSid"
|
||||
control={control}
|
||||
defaultValue={"accountSid" in defaults ? defaults.accountSid : ""}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={t("pages.notifications.form.twilio.optionAccountSid")}
|
||||
placeholder={t(
|
||||
"pages.notifications.form.twilio.placeholderAccountSid"
|
||||
)}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="accessToken"
|
||||
control={control}
|
||||
defaultValue={"accessToken" in defaults ? defaults.accessToken : ""}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={t("pages.notifications.form.twilio.optionAuthToken")}
|
||||
placeholder={t(
|
||||
"pages.notifications.form.twilio.placeholderAuthToken"
|
||||
)}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="twilioPhoneNumber"
|
||||
control={control}
|
||||
defaultValue={
|
||||
"twilioPhoneNumber" in defaults ? defaults.twilioPhoneNumber : ""
|
||||
}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={t("pages.notifications.form.twilio.optionFromNumber")}
|
||||
placeholder={t(
|
||||
"pages.notifications.form.twilio.placeholderFromNumber"
|
||||
)}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="phone"
|
||||
control={control}
|
||||
defaultValue={"phone" in defaults ? defaults.phone : ""}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
type="text"
|
||||
fieldLabel={t("pages.notifications.form.twilio.optionToNumber")}
|
||||
placeholder={t("pages.notifications.form.twilio.placeholderToNumber")}
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message ?? ""}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{watchedType === "matrix" && (
|
||||
<ConfigBox
|
||||
title={t("pages.notifications.form.matrix.title")}
|
||||
|
||||
@@ -39,10 +39,9 @@ const NotificationsPage = () => {
|
||||
|
||||
return (
|
||||
<BasePageWithStates
|
||||
headerKey="notifications"
|
||||
page={t("pages.notifications.fallback.title")}
|
||||
bullets={
|
||||
t("pages.notifications.fallback.checks", { returnObjects: true }) as string[]
|
||||
}
|
||||
description={t("pages.notifications.fallback.description")}
|
||||
loading={isLoading || isValidating}
|
||||
error={!!error}
|
||||
totalCount={notifications?.length ?? 0}
|
||||
|
||||
@@ -77,6 +77,7 @@ const PageSpeedMonitorsPage = () => {
|
||||
|
||||
return (
|
||||
<MonitorBasePageWithStates
|
||||
headerKey="pageSpeed"
|
||||
loading={isLoading}
|
||||
error={monitorsError || settingsError}
|
||||
totalCount={summary?.totalMonitors ?? 0}
|
||||
|
||||
@@ -24,6 +24,7 @@ import type { SettingsFormData, SettingsFormInput } from "@/Validation/settings"
|
||||
import { useState } from "react";
|
||||
import { Controller } from "react-hook-form";
|
||||
import { TextField, Button, FieldLabel, SliderWithLabel } from "@/Components/inputs";
|
||||
import { languageNames } from "@/Components/inputs/LanguageSelector";
|
||||
import { Box, Typography } from "@mui/material";
|
||||
import { useDelete } from "@/Hooks/UseApi";
|
||||
|
||||
@@ -277,6 +278,7 @@ export const SettingsPage = () => {
|
||||
|
||||
return (
|
||||
<BasePage
|
||||
headerKey="settings"
|
||||
component="form"
|
||||
onSubmit={form.handleSubmit(onSubmit, onError)}
|
||||
>
|
||||
@@ -326,7 +328,7 @@ export const SettingsPage = () => {
|
||||
key={lang}
|
||||
value={lang}
|
||||
>
|
||||
{lang.toUpperCase()}
|
||||
{languageNames[lang] ?? lang}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
@@ -578,11 +580,11 @@ export const SettingsPage = () => {
|
||||
<Box
|
||||
component="pre"
|
||||
sx={{
|
||||
fontFamily: "monospace",
|
||||
fontFamily: theme.typography.fontFamilyMonospace,
|
||||
p: 2,
|
||||
borderRadius: 1,
|
||||
overflow: "auto",
|
||||
backgroundColor: theme.palette.mode === "dark" ? "#1e1e1e" : "#f5f5f5",
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
}}
|
||||
>
|
||||
<code>
|
||||
@@ -974,19 +976,13 @@ export const SettingsPage = () => {
|
||||
loading={isDeletingAllMonitors}
|
||||
/>
|
||||
|
||||
{/* Sticky Save Button */}
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="flex-end"
|
||||
sx={{
|
||||
position: "sticky",
|
||||
bottom: 0,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
padding: theme.spacing(LAYOUT.MD),
|
||||
marginLeft: theme.spacing(-LAYOUT.MD),
|
||||
marginRight: theme.spacing(-LAYOUT.MD),
|
||||
marginBottom: theme.spacing(-LAYOUT.MD),
|
||||
zIndex: 1000,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,35 +1,115 @@
|
||||
import { AlertTriangle, CircleCheck } from "lucide-react";
|
||||
import {
|
||||
AlertTriangle,
|
||||
CircleCheck,
|
||||
CircleX,
|
||||
Loader,
|
||||
PauseCircle,
|
||||
ShieldAlert,
|
||||
Wrench,
|
||||
} from "lucide-react";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import type { Theme } from "@mui/material";
|
||||
import { useTheme } from "@mui/material";
|
||||
import type { Monitor } from "@/Types/Monitor";
|
||||
import type { Theme } from "@mui/material";
|
||||
import type { Monitor, MonitorStatus } from "@/Types/Monitor";
|
||||
|
||||
interface StatusDisplay {
|
||||
icon: JSX.Element;
|
||||
msg?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const getMonitorStatus = (monitors: Monitor[], theme: Theme, t: Function) => {
|
||||
const monitorsStatus: Record<string, any> = {
|
||||
const monitorsStatus: StatusDisplay = {
|
||||
icon: <AlertTriangle size={24} />,
|
||||
};
|
||||
|
||||
if (monitors.every((monitor) => monitor.status === "up")) {
|
||||
// Handle empty monitors array
|
||||
if (monitors.length === 0) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.noMonitors");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
monitorsStatus.icon = <CircleX size={24} />;
|
||||
return monitorsStatus;
|
||||
}
|
||||
|
||||
const allOf = (...statuses: MonitorStatus[]) =>
|
||||
monitors.every((m) => statuses.includes(m.status));
|
||||
const someOf = (...statuses: MonitorStatus[]) =>
|
||||
monitors.some((m) => statuses.includes(m.status));
|
||||
const noneOf = (...statuses: MonitorStatus[]) =>
|
||||
monitors.every((m) => !statuses.includes(m.status));
|
||||
|
||||
// All monitors in a single state
|
||||
if (allOf("up")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.allUp");
|
||||
monitorsStatus.color = theme.palette.success.main;
|
||||
monitorsStatus.icon = <CircleCheck size={24} />;
|
||||
return monitorsStatus;
|
||||
} else if (monitors.every((monitor) => monitor.status === "down")) {
|
||||
} else if (allOf("breached")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.allBreached");
|
||||
monitorsStatus.color = theme.palette.error.main;
|
||||
monitorsStatus.icon = <ShieldAlert size={24} />;
|
||||
} else if (allOf("maintenance")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.allMaintenance");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
monitorsStatus.icon = <Wrench size={24} />;
|
||||
} else if (allOf("down")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.allDown");
|
||||
monitorsStatus.color = theme.palette.error.main;
|
||||
return monitorsStatus;
|
||||
} else if (monitors.some((monitor) => monitor.status === "down")) {
|
||||
monitorsStatus.icon = <CircleX size={24} />;
|
||||
} else if (allOf("paused")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.allPaused");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
monitorsStatus.icon = <PauseCircle size={24} />;
|
||||
} else if (allOf("initializing")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.allInitializing");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
monitorsStatus.icon = <Loader size={24} />;
|
||||
|
||||
// Breached takes highest priority in mixed states
|
||||
} else if (someOf("breached") && someOf("down")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.breachedAndDown");
|
||||
monitorsStatus.color = theme.palette.error.main;
|
||||
monitorsStatus.icon = <ShieldAlert size={24} />;
|
||||
} else if (someOf("breached")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.breached");
|
||||
monitorsStatus.color = theme.palette.error.main;
|
||||
monitorsStatus.icon = <ShieldAlert size={24} />;
|
||||
|
||||
// Maintenance combinations
|
||||
} else if (someOf("maintenance") && someOf("down")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.maintenanceAndDown");
|
||||
monitorsStatus.color = theme.palette.error.main;
|
||||
monitorsStatus.icon = <Wrench size={24} />;
|
||||
} else if (someOf("maintenance") && noneOf("down")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.maintenance");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
monitorsStatus.icon = <Wrench size={24} />;
|
||||
|
||||
// Degraded (some down, no maintenance/breached)
|
||||
} else if (someOf("down")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.degraded");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
return monitorsStatus;
|
||||
monitorsStatus.icon = <AlertTriangle size={24} />;
|
||||
|
||||
// Some Paused
|
||||
} else if (someOf("paused")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.partiallyPaused");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
monitorsStatus.icon = <PauseCircle size={24} />;
|
||||
|
||||
// Initializing
|
||||
} else if (someOf("initializing")) {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.initializing");
|
||||
monitorsStatus.color = theme.palette.info.main;
|
||||
monitorsStatus.icon = <Loader size={24} />;
|
||||
} else {
|
||||
monitorsStatus.msg = t("pages.statusPages.statusBar.unknown");
|
||||
monitorsStatus.color = theme.palette.warning.main;
|
||||
return monitorsStatus;
|
||||
}
|
||||
|
||||
return monitorsStatus;
|
||||
};
|
||||
|
||||
interface StatusBarProps {
|
||||
|
||||
@@ -2,7 +2,9 @@ import Box from "@mui/material/Box";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { Table, type Header, ValueLabel } from "@/Components/design-elements";
|
||||
import { Pagination } from "@/Components/design-elements/Table";
|
||||
import { ActionsMenu, type ActionMenuItem } from "@/Components/actions-menu";
|
||||
import { useClientPagination } from "@/Hooks/useClientPagination";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -23,6 +25,7 @@ export const StatusPagesTable = ({
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const { pagedRows, paginationProps } = useClientPagination(data);
|
||||
|
||||
const getActions = (row: StatusPage): ActionMenuItem[] => {
|
||||
return [
|
||||
@@ -133,10 +136,11 @@ export const StatusPagesTable = ({
|
||||
<Box>
|
||||
<Table
|
||||
headers={getHeaders()}
|
||||
data={data}
|
||||
data={pagedRows}
|
||||
onRowClick={handleRowClick}
|
||||
emptyViewText={t("common.table.empty")}
|
||||
/>
|
||||
{data.length > 0 && <Pagination {...paginationProps} />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -37,11 +37,10 @@ const StatusPages = () => {
|
||||
|
||||
return (
|
||||
<BasePageWithStates
|
||||
page={t("pages.statusPages.title")}
|
||||
headerKey="statusPages"
|
||||
page={t("pages.statusPages.fallback.title")}
|
||||
loading={isLoading}
|
||||
bullets={
|
||||
t("pages.statusPages.fallback.checks", { returnObjects: true }) as string[]
|
||||
}
|
||||
description={t("pages.statusPages.fallback.description")}
|
||||
error={!!error}
|
||||
totalCount={statusPages?.length ?? 0}
|
||||
actionButtonText={t("pages.statusPages.fallback.actionButton")}
|
||||
|
||||
@@ -71,16 +71,24 @@ export const MonitorTable = ({
|
||||
refetch();
|
||||
};
|
||||
|
||||
const isBrowserOpenable = (monitor: Monitor): boolean => {
|
||||
if (monitor.type !== "http" && monitor.type !== "pagespeed") return false;
|
||||
return /^https?:\/\//i.test(monitor.url ?? "");
|
||||
};
|
||||
|
||||
const getActions = (monitor: Monitor): ActionMenuItem[] => {
|
||||
return [
|
||||
{
|
||||
const actions: ActionMenuItem[] = [];
|
||||
if (isBrowserOpenable(monitor)) {
|
||||
actions.push({
|
||||
id: 1,
|
||||
label: t("pages.common.monitors.actions.openSite"),
|
||||
action: () => {
|
||||
window.open(monitor.url, "_blank", "noreferrer");
|
||||
},
|
||||
closeMenu: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
actions.push(
|
||||
{
|
||||
id: 2,
|
||||
label: t("pages.common.monitors.actions.details"),
|
||||
@@ -130,8 +138,9 @@ export const MonitorTable = ({
|
||||
),
|
||||
action: () => setSelectedMonitor(monitor),
|
||||
closeMenu: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
);
|
||||
return actions;
|
||||
};
|
||||
|
||||
const getHeaders = (chartType: string) => {
|
||||
|
||||
@@ -140,6 +140,7 @@ const UptimeMonitorsPage = () => {
|
||||
|
||||
return (
|
||||
<MonitorBasePageWithStates
|
||||
headerKey="uptime"
|
||||
loading={isLoading}
|
||||
error={monitorsWithChecksError}
|
||||
totalCount={effectiveTotalCount}
|
||||
|
||||
@@ -7,6 +7,8 @@ export const NotificationChannels = [
|
||||
"matrix",
|
||||
"teams",
|
||||
"telegram",
|
||||
"pushover",
|
||||
"twilio",
|
||||
] as const;
|
||||
export type NotificationChannel = (typeof NotificationChannels)[number];
|
||||
|
||||
@@ -21,6 +23,8 @@ export interface Notification {
|
||||
homeserverUrl?: string;
|
||||
roomId?: string;
|
||||
accessToken?: string;
|
||||
accountSid?: string;
|
||||
twilioPhoneNumber?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
@@ -56,10 +56,12 @@ export const getResponseColor = (
|
||||
// 0–300ms: interpolate start (good) -> mid (warning)
|
||||
// 300–600ms: interpolate mid (warning) -> end (error)
|
||||
// >600ms: solid end (error)
|
||||
// MUI default success/warning/error.main values, used only when the caller
|
||||
// fails to pass theme colors (defensive — keeps the gradient meaningful).
|
||||
const safe = { ...colors };
|
||||
if (!safe.start) safe.start = "#4caf50"; // fallback green
|
||||
if (!safe.mid) safe.mid = "#ff9800"; // fallback orange
|
||||
if (!safe.end) safe.end = "#f44336"; // fallback red
|
||||
if (!safe.start) safe.start = "#4caf50";
|
||||
if (!safe.mid) safe.mid = "#ff9800";
|
||||
if (!safe.end) safe.end = "#f44336";
|
||||
|
||||
const toHex = (c: number) => c.toString(16).padStart(2, "0");
|
||||
const clamp = (n: number) => Math.min(255, Math.max(0, Math.round(n)));
|
||||
|
||||
@@ -14,21 +14,25 @@ export const colors = {
|
||||
gray700: "#313131",
|
||||
gray900: "#151518",
|
||||
gray850: "#1c1c21",
|
||||
blueBlueWave: "#1570EF",
|
||||
brandGreen: "#13715B",
|
||||
brandGreenLight: "#4DAF94",
|
||||
};
|
||||
|
||||
export const lightPalette = {
|
||||
primary: {
|
||||
main: colors.blueBlueWave,
|
||||
main: colors.brandGreen,
|
||||
},
|
||||
secondary: {
|
||||
main: colors.gray200,
|
||||
},
|
||||
sidebar: {
|
||||
accent: colors.brandGreen,
|
||||
},
|
||||
};
|
||||
|
||||
export const darkPalette = {
|
||||
primary: {
|
||||
main: colors.blueBlueWave,
|
||||
main: colors.brandGreen,
|
||||
},
|
||||
secondary: {
|
||||
main: colors.gray700,
|
||||
@@ -37,4 +41,7 @@ export const darkPalette = {
|
||||
default: colors.gray900,
|
||||
paper: colors.gray850,
|
||||
},
|
||||
sidebar: {
|
||||
accent: colors.brandGreenLight,
|
||||
},
|
||||
};
|
||||
@@ -2,12 +2,38 @@ import { createTheme } from "@mui/material";
|
||||
import { lightPalette, darkPalette, typographyLevels } from "@/Utils/Theme/Palette";
|
||||
|
||||
import type { Theme } from "@mui/material/styles";
|
||||
import type {} from "@mui/material/styles";
|
||||
|
||||
declare module "@mui/material/styles" {
|
||||
interface TypographyVariants {
|
||||
eyebrow: React.CSSProperties;
|
||||
fontFamilyMonospace: string;
|
||||
}
|
||||
interface TypographyVariantsOptions {
|
||||
eyebrow?: React.CSSProperties;
|
||||
fontFamilyMonospace?: string;
|
||||
}
|
||||
interface Palette {
|
||||
sidebar: { accent: string };
|
||||
}
|
||||
interface PaletteOptions {
|
||||
sidebar?: { accent: string };
|
||||
}
|
||||
}
|
||||
|
||||
declare module "@mui/material/Typography" {
|
||||
interface TypographyPropsVariantOverrides {
|
||||
eyebrow: true;
|
||||
}
|
||||
}
|
||||
|
||||
export type PaletteKey = {
|
||||
[K in keyof Theme["palette"]]: Theme["palette"][K] extends { main: any } ? K : never;
|
||||
}[keyof Theme["palette"]];
|
||||
|
||||
const fontFamilyPrimary = "system-ui, sans-serif";
|
||||
const fontFamilyMonospace =
|
||||
'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace';
|
||||
const shadow =
|
||||
"0px 4px 24px -4px rgba(16, 24, 40, 0.08), 0px 3px 3px -3px rgba(16, 24, 40, 0.03)";
|
||||
|
||||
@@ -29,6 +55,7 @@ export const theme = (mode: string, palette: any) =>
|
||||
},
|
||||
typography: {
|
||||
fontFamily: fontFamilyPrimary,
|
||||
fontFamilyMonospace,
|
||||
fontSize: typographyLevels.base,
|
||||
h1: {
|
||||
fontSize: typographyLevels.xl,
|
||||
@@ -46,6 +73,13 @@ export const theme = (mode: string, palette: any) =>
|
||||
fontSize: typographyLevels.s,
|
||||
fontWeight: 400,
|
||||
},
|
||||
eyebrow: {
|
||||
fontSize: 13,
|
||||
fontWeight: 500,
|
||||
textTransform: "uppercase",
|
||||
letterSpacing: "0.08em",
|
||||
lineHeight: 1.4,
|
||||
},
|
||||
},
|
||||
|
||||
components: {
|
||||
@@ -120,11 +154,17 @@ export const theme = (mode: string, palette: any) =>
|
||||
|
||||
MuiOutlinedInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
root: ({ theme }) => ({
|
||||
"&:hover .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor:
|
||||
theme.palette.mode === "dark"
|
||||
? "rgba(255, 255, 255, 0.23)"
|
||||
: theme.palette.text.primary,
|
||||
},
|
||||
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: palette.primary.main,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -145,6 +185,113 @@ export const theme = (mode: string, palette: any) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
MuiSwitch: {
|
||||
defaultProps: { disableRipple: true },
|
||||
styleOverrides: {
|
||||
root: {
|
||||
width: 36,
|
||||
height: 20,
|
||||
padding: "0 6px 0 0",
|
||||
boxSizing: "content-box",
|
||||
overflow: "visible",
|
||||
},
|
||||
switchBase: ({ theme }) => ({
|
||||
padding: 2,
|
||||
"&.Mui-checked": {
|
||||
transform: "translateX(16px)",
|
||||
color: "#fff",
|
||||
"& + .MuiSwitch-track": {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
opacity: 1,
|
||||
border: 0,
|
||||
},
|
||||
},
|
||||
}),
|
||||
thumb: {
|
||||
width: 16,
|
||||
height: 16,
|
||||
boxShadow: "0 1px 2px rgba(16, 24, 40, 0.1)",
|
||||
},
|
||||
track: ({ theme }) => ({
|
||||
borderRadius: 999,
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark"
|
||||
? "rgba(255,255,255,0.16)"
|
||||
: theme.palette.action.disabledBackground,
|
||||
opacity: 1,
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
||||
MuiRadio: {
|
||||
defaultProps: { disableRipple: true },
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
padding: theme.spacing(2),
|
||||
color: theme.palette.divider,
|
||||
"& .MuiSvgIcon-root": {
|
||||
fontSize: 20,
|
||||
transition: "none",
|
||||
},
|
||||
"&.Mui-checked": {
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
"&.Mui-checked .MuiSvgIcon-root:last-of-type": {
|
||||
transform: "scale(0.6)",
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
||||
MuiSlider: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }) => ({
|
||||
height: 4,
|
||||
padding: "13px 0",
|
||||
color: theme.palette.primary.main,
|
||||
}),
|
||||
rail: ({ theme }) => ({
|
||||
height: 4,
|
||||
borderRadius: 999,
|
||||
opacity: 1,
|
||||
backgroundColor:
|
||||
theme.palette.mode === "dark"
|
||||
? "rgba(255,255,255,0.16)"
|
||||
: theme.palette.action.disabledBackground,
|
||||
}),
|
||||
track: {
|
||||
height: 4,
|
||||
borderRadius: 999,
|
||||
border: "none",
|
||||
},
|
||||
thumb: ({ theme }) => ({
|
||||
width: 18,
|
||||
height: 18,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `2px solid ${theme.palette.primary.main}`,
|
||||
boxShadow: "0 1px 2px rgba(16, 24, 40, 0.1)",
|
||||
"&:hover, &.Mui-focusVisible": {
|
||||
boxShadow: `0 0 0 6px ${theme.palette.primary.main}1f`,
|
||||
},
|
||||
"&.Mui-active": {
|
||||
boxShadow: `0 0 0 8px ${theme.palette.primary.main}29`,
|
||||
},
|
||||
"&::before": { display: "none" },
|
||||
}),
|
||||
mark: ({ theme }) => ({
|
||||
width: 2,
|
||||
height: 2,
|
||||
borderRadius: 999,
|
||||
backgroundColor: theme.palette.text.disabled,
|
||||
opacity: 0.5,
|
||||
}),
|
||||
markActive: ({ theme }) => ({
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
opacity: 0.5,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
shape: {
|
||||
borderRadius: 2,
|
||||
|
||||
@@ -56,6 +56,20 @@ const telegramSchema = baseSchema.extend({
|
||||
accessToken: z.string().min(1, "Bot token is required"),
|
||||
});
|
||||
|
||||
const pushoverSchema = baseSchema.extend({
|
||||
type: z.literal("pushover"),
|
||||
address: z.string().min(1, "User key is required"),
|
||||
accessToken: z.string().min(1, "App token is required"),
|
||||
});
|
||||
|
||||
const twilioSchema = baseSchema.extend({
|
||||
type: z.literal("twilio"),
|
||||
accountSid: z.string().min(1, "Account SID is required"),
|
||||
accessToken: z.string().min(1, "Auth token is required"),
|
||||
phone: z.string().min(1, "Recipient phone number is required"),
|
||||
twilioPhoneNumber: z.string().min(1, "Twilio phone number is required"),
|
||||
});
|
||||
|
||||
export const notificationSchema = z.discriminatedUnion("type", [
|
||||
emailSchema,
|
||||
slackSchema,
|
||||
@@ -65,6 +79,8 @@ export const notificationSchema = z.discriminatedUnion("type", [
|
||||
matrixSchema,
|
||||
teamsSchema,
|
||||
telegramSchema,
|
||||
pushoverSchema,
|
||||
twilioSchema,
|
||||
]);
|
||||
|
||||
export type NotificationFormData = z.infer<typeof notificationSchema>;
|
||||
@@ -1,49 +1,11 @@
|
||||
<svg width="32" height="32" viewBox="0 0 600 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M218.252 79.2667L218.045 78.4143C218.712 77.617 219.642 77.5282 220.615 77.4361C224.829 77.0374 243.307 76.7077 246.676 77.418C248.299 77.76 249.661 78.5248 250.932 79.5734C254.845 82.8003 259.018 88.0302 262.403 91.9284C263.57 93.2734 264.805 95.1623 266.183 96.2584C268.203 99.7185 274.532 101.602 278.167 102.623C278.397 102.688 278.631 102.741 278.863 102.797C274.983 106.185 272.016 110.321 268.272 113.745C272.574 124.188 286.689 184.953 289.397 187.986C290.165 188.212 290.291 188.048 291.045 187.739C290.627 188.446 290.337 189.3 289.588 189.656L288.963 188.533C286.703 188.347 273.044 195.497 269.836 196.808C267.39 197.808 264.851 198.458 262.414 199.405C261.197 196.797 260.413 193.923 259.329 191.244C254.43 179.142 250.091 166.843 245.71 154.552C240.241 139.206 234.226 124.026 228.882 108.642C226.389 101.466 223.549 94.5009 220.953 87.3749C220.026 84.8301 219.72 81.4795 218.252 79.2667Z" fill="#3158B7"/>
|
||||
<path d="M218.252 79.2667L218.045 78.4143C218.712 77.617 219.642 77.5282 220.615 77.4361C224.829 77.0374 243.307 76.7077 246.676 77.418C248.299 77.76 249.661 78.5248 250.932 79.5734C254.845 82.8003 259.018 88.0302 262.403 91.9284C263.57 93.2734 264.805 95.1623 266.183 96.2584C268.203 99.7185 274.532 101.602 278.167 102.623C278.397 102.688 278.631 102.741 278.863 102.797C274.983 106.185 272.016 110.321 268.272 113.745C266.08 111.774 263.588 110.159 261.208 108.427C256.477 104.982 251.692 101.649 246.906 98.282L233.54 88.9767C228.729 85.5908 223.823 81.3267 218.252 79.2667Z" fill="#73E4FA"/>
|
||||
<path d="M299.595 19.4005C302.177 17.8183 305.226 16.8946 307.955 15.5556C310.387 14.3626 312.673 12.8604 315.15 11.7619C315.624 11.5519 315.886 11.4697 316.398 11.4844C315.732 13.7848 316.431 26.6622 316.441 30.2652C316.474 42.2192 316.084 54.2432 316.385 66.1867C316.416 67.4343 316.377 68.6301 316.847 69.8026C316.457 79.0631 316.718 88.4086 316.651 97.6808L316.423 172.062C316.376 177.75 316.385 183.438 316.448 189.125C316.469 192.585 316.902 196.888 316.126 200.243C316.055 199.033 315.728 197.334 316.025 196.183C315.86 197.435 315.463 198.762 315.391 200.002C315.283 201.847 315.798 203.719 315.391 205.559C314.431 204.554 313.43 203.906 312.592 202.729C308.228 196.602 310.556 194.07 301.963 190.683C299.704 189.793 293.054 186.88 291.045 187.739C290.291 188.048 290.165 188.212 289.397 187.986C286.689 184.953 272.574 124.188 268.272 113.745C272.016 110.321 274.983 106.185 278.863 102.797C278.631 102.741 278.397 102.688 278.167 102.623C274.532 101.602 268.203 99.7184 266.183 96.2583C269.435 97.3504 272.901 97.5882 276.304 97.6583C280.306 97.7408 283.403 97.3026 286.383 94.3544C288.086 92.669 289.516 90.6569 291.136 88.8839C293.303 86.512 296.041 84.1801 297.633 81.3777C300.012 77.1924 299.115 62.4967 299.219 57.0841C296.538 56.7086 293.912 56.806 291.218 56.6995C288.184 56.5796 285.396 56.0507 283.294 53.6585C280.886 50.9188 280.696 47.3466 281.035 43.8756C282.423 29.6657 295.122 37.239 298.804 33.8184C299.712 32.9739 299.469 21.618 299.595 19.4005Z" fill="#3D7ECD"/>
|
||||
<path d="M362.288 269.421L362.773 270.062C364.332 274.37 365.193 279.073 366.359 283.516C368.419 291.371 370.61 299.194 372.793 307.015L395.769 388.039L411.304 442.863L415.766 458.213C416.528 460.836 417.569 463.467 417.96 466.175C417.89 466.842 418.03 466.869 417.485 467.324C413.349 466.406 409.11 465.92 404.942 465.147C396.892 463.653 388.881 461.984 380.817 460.552C380.516 459.221 380.489 457.712 380.305 456.347C379.896 453.327 379.359 450.33 378.694 447.356C376.712 438.738 374.16 430.227 372.075 421.626L351.327 334.35C349.071 324.725 347.019 314.981 344.607 305.405C342.561 297.284 340.078 289.201 338.622 280.946C339.912 280.649 340.991 280.35 342.142 279.684C345.072 278.136 348.264 277.064 351.221 275.536C354.9 273.636 358.345 270.649 362.288 269.421Z" fill="#73E4FA"/>
|
||||
<path d="M316.398 11.4845C316.949 11.6168 317.496 11.7682 318.021 11.982C320.527 13.0022 322.595 14.8975 325.025 16.0401C326.641 16.7993 328.506 17.0278 330.066 17.9189C330.615 18.2326 331.175 18.6401 331.516 19.1833C333.638 22.5617 329.941 33.143 334.144 34.5595C335.071 34.872 336.309 34.7269 337.278 34.6636C342.517 34.3216 346.04 34.3235 349.065 39.1827C350.891 42.117 351.841 45.3207 350.982 48.7564C350.164 52.0314 347.831 55.4635 344.902 57.2399C344.309 57.5993 343.657 57.8308 343.003 58.0488C342.382 58.2541 341.729 58.4831 341.176 58.8402C339.34 60.0257 337.705 61.6472 335.85 62.8819C335.083 63.3916 333.536 63.9343 333.114 64.7163C333.015 64.8989 332.938 65.0921 332.849 65.2797C331.994 71.778 330.942 74.7954 335.242 80.4525C338.105 84.2196 345.676 93.407 349.248 96.0711C350.329 96.8768 351.548 97.3899 352.858 97.674C354.638 97.679 356.567 97.8353 358.319 97.4932C366.986 95.8002 372.945 85.6789 379.155 80.1412C380.557 78.8916 382.117 77.8947 383.974 77.4926C387.385 76.754 391.296 77.2429 394.773 77.2627C400.744 77.2966 406.631 77.1509 412.603 77.4939C413.066 77.8038 413.08 77.6663 413.16 78.1487C413.385 79.5036 412.832 81.0938 412.41 82.377C409.805 90.2864 406.49 98.1119 403.607 105.936L387.525 150.29C383.617 161.269 379.569 172.195 375.381 183.07C373.017 189.241 370.826 195.663 367.756 201.518C366.906 200.846 366.105 200.384 365.115 199.946C357.118 196.547 349.468 191.947 341.757 187.926C341.211 187.423 341.102 187.207 340.301 187.318C338.422 187.579 336.346 188.419 334.502 188.929C330.434 190.055 321.796 191.764 319.469 195.652C318.572 197.151 317.692 200.22 316.337 201.245C316.225 200.886 316.145 200.621 316.126 200.243C316.902 196.888 316.469 192.585 316.448 189.125C316.385 183.438 316.377 177.75 316.423 172.062L316.651 97.6809C316.718 88.4087 316.457 79.0632 316.847 69.8027C316.377 68.6302 316.416 67.4344 316.385 66.1868C316.084 54.2433 316.474 42.2193 316.441 30.2653C316.431 26.6623 315.732 13.7849 316.398 11.4845Z" fill="#73E4FA"/>
|
||||
<path d="M332.127 57.4141C335.751 57.5106 339.378 57.8905 343.003 58.0488C342.382 58.2541 341.729 58.4831 341.176 58.8402C339.34 60.0257 337.705 61.6472 335.85 62.8819C335.083 63.3916 333.536 63.9343 333.114 64.7163C333.015 64.8989 332.938 65.0921 332.849 65.2797C332.684 62.6459 332.422 60.0356 332.127 57.4141Z" fill="black"/>
|
||||
<path d="M352.858 97.674C354.638 97.679 356.567 97.8353 358.319 97.4932C366.986 95.8002 372.945 85.6789 379.155 80.1412C380.557 78.8916 382.117 77.8947 383.974 77.4926C387.385 76.754 391.296 77.2429 394.773 77.2627C400.744 77.2966 406.631 77.1509 412.603 77.4939C412.123 77.5931 411.776 77.6589 411.35 77.9133C409.284 79.1482 407.188 81.3404 405.081 82.7802C394.559 89.9716 384.283 97.4873 373.787 104.715C371.042 106.605 368.398 108.696 365.587 110.481C363.016 106.042 360.879 102.667 356.684 99.576C355.908 99.004 354.963 98.1848 354.042 97.8844C353.777 97.7979 353.467 97.7915 353.199 97.7482C353.084 97.7297 352.972 97.6988 352.858 97.674Z" fill="#4F91E0"/>
|
||||
<path d="M316.847 69.8027C321.242 72.4105 326.84 79.7356 330.518 83.5726C335.063 88.3145 340.305 92.4625 345.078 96.9857C348.754 100.47 359.102 112.197 362.531 113.979C362.884 116.416 347.596 173.131 345.411 179.979C344.657 182.345 343.764 185.35 342.254 187.338C342.099 187.543 341.927 187.734 341.757 187.926C341.211 187.423 341.102 187.207 340.301 187.318C338.422 187.579 336.346 188.419 334.502 188.929C330.434 190.055 321.796 191.764 319.469 195.652C318.572 197.151 317.692 200.22 316.337 201.245C316.225 200.886 316.145 200.621 316.126 200.243C316.902 196.888 316.469 192.585 316.448 189.125C316.385 183.438 316.376 177.75 316.423 172.062L316.651 97.6809C316.718 88.4087 316.457 79.0632 316.847 69.8027Z" fill="#5BBFFC"/>
|
||||
<path d="M316.126 200.243C316.145 200.621 316.225 200.886 316.337 201.245C317.692 200.22 318.572 197.151 319.469 195.652C321.796 191.764 330.434 190.055 334.502 188.929C336.346 188.419 338.422 187.579 340.301 187.318C341.102 187.207 341.211 187.423 341.757 187.926C349.468 191.947 357.118 196.547 365.115 199.946C366.105 200.384 366.906 200.846 367.756 201.518C367.27 202.637 366.763 203.747 366.234 204.848C365.063 207.595 364.344 210.137 363.459 212.952C367.613 213.364 371.797 213.297 375.966 213.194C386.171 213.341 399.134 211.56 407.006 219.438C408.262 220.694 409.583 222.077 410.315 223.707C411.447 228.7 410.939 234.09 410.692 239.173C410.661 239.285 410.628 239.397 410.599 239.511C410.317 240.612 410.264 241.816 409.76 242.846C408.269 245.89 403.918 248.67 401.099 250.509L397.101 250.535C392.229 251.156 386.936 250.764 382.02 250.742C380.258 252.242 379.572 253.4 379.015 255.621C375.623 257.067 372.349 258.186 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663L305.359 267.78C304.526 268.174 303.726 268.445 302.836 268.679L302.422 268.516C302.97 267.994 303.581 267.707 304.249 267.371C303.346 267.089 302.592 267.405 301.795 267.828C300.798 268.358 299.724 269.109 298.638 269.418C296.45 270.04 293.748 268.782 292.771 271.723C291.539 275.429 292.836 276.598 289.342 279.245L289.264 279.106L289.746 279.665C289.922 279.642 290.098 279.617 290.274 279.596C290.788 279.534 291.072 279.562 291.552 279.784C283.761 280.886 276.08 271.943 269.481 268.727C269.532 267.685 269.414 267.036 268.848 266.155C266.793 262.951 261.551 259.21 258.011 257.869C256.773 257.4 255.382 257.17 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742C234.444 250.731 231.884 250.523 229.351 250.403C226.903 249.086 224.175 246.485 222.644 244.15C220.166 240.368 220.112 229.455 221.195 225.05C221.962 221.93 223.946 219.508 226.648 217.845C227.525 217.021 228.391 216.267 229.547 215.874C232.606 214.832 236.233 214.827 239.433 214.547C243.327 214.206 247.238 213.733 251.141 213.538C256.502 213.269 261.883 213.36 267.25 213.257C267.293 213.167 267.345 213.08 267.378 212.986C268.103 210.948 263.421 201.839 262.414 199.405C264.851 198.458 267.39 197.808 269.836 196.808C273.044 195.497 286.703 188.347 288.963 188.533L289.588 189.656C290.337 189.3 290.627 188.446 291.045 187.739C293.054 186.88 299.704 189.793 301.963 190.683C310.556 194.07 308.228 196.602 312.592 202.729C313.43 203.906 314.431 204.554 315.391 205.559C315.798 203.719 315.283 201.847 315.391 200.002C315.463 198.762 315.86 197.435 316.025 196.183C315.728 197.334 316.055 199.033 316.126 200.243Z" fill="#73E4FA"/>
|
||||
<path d="M226.648 217.845C227.525 217.021 228.391 216.267 229.547 215.874C232.606 214.832 236.233 214.827 239.433 214.547C243.327 214.206 247.238 213.733 251.141 213.538C256.502 213.269 261.883 213.36 267.25 213.257C273.5 213.971 279.834 213.445 286.108 213.605C286.028 213.626 285.948 213.648 285.867 213.666C283.762 214.153 281.367 213.997 279.208 214.037C272.251 214.165 265.326 213.83 258.375 213.88C253.031 213.919 247.886 214.67 242.578 215.017C240.895 215.127 236.024 214.805 235.01 216.105C234.814 216.356 234.778 216.499 234.672 216.773C235.26 217.358 235.736 217.319 236.534 217.341C240.179 217.439 243.921 217.212 247.585 217.238C254.057 217.283 260.516 217.54 266.99 217.551C270.978 217.557 278.548 217.235 282.283 217.919C273.611 218.558 264.721 217.948 256.023 218.03C249.71 217.873 243.396 217.847 237.081 217.954C233.732 217.991 229.946 218.398 226.648 217.845Z" fill="#4F91E0"/>
|
||||
<path d="M321 196.5C321.019 196.878 320.86 194.141 320.972 194.5C322.327 193.475 318.572 197.151 319.469 195.652C321.796 191.764 330.434 190.055 334.502 188.929C336.346 188.419 338.422 187.579 340.301 187.318C341.102 187.207 341.211 187.423 341.757 187.926C349.468 191.947 357.118 196.547 365.115 199.946C366.105 200.384 366.906 200.846 367.756 201.518C367.27 202.637 366.763 203.747 366.234 204.848C365.063 207.595 364.344 210.137 363.459 212.952L361.76 212.951C346.809 213.807 331.759 213.014 316.787 213.074L315.391 205.559C315.798 203.719 315.283 201.847 315.391 200.002C315.463 198.762 315.835 196.752 316 195.5C315.5 195 323.374 191.757 321 196.5Z" fill="#3158B7"/>
|
||||
<path d="M291.045 187.739C293.054 186.88 299.704 189.793 301.963 190.683C310.556 194.07 305.5 191.5 312.5 194.5C314 195 315.54 193.995 316.5 195L316.787 213.074C306.586 212.996 296.304 213.296 286.108 213.605C279.834 213.445 273.5 213.971 267.25 213.257C267.293 213.167 267.345 213.08 267.378 212.986C268.103 210.948 263.421 201.839 262.414 199.405C264.851 198.458 267.39 197.808 269.836 196.808C273.044 195.497 286.703 188.347 288.963 188.533L289.5 188.5C290.249 188.144 290.627 188.446 291.045 187.739Z" fill="#15337C"/>
|
||||
<path d="M316.158 217.961C333.626 218.066 351.372 216.648 368.745 218.663C369.093 229.235 368.662 239.88 368.76 250.467L387.46 250.44C390.609 250.437 393.982 250.193 397.101 250.535C392.229 251.156 386.936 250.764 382.02 250.742L316.217 250.777C316.034 247.101 316.2 243.334 316.205 239.649C316.23 232.42 316.215 225.19 316.158 217.961Z" fill="#5BBFFC"/>
|
||||
<path d="M229.351 250.403C226.903 249.086 224.175 246.485 222.644 244.15C220.166 240.368 220.112 229.455 221.195 225.05C221.962 221.93 223.946 219.508 226.648 217.845C229.946 218.398 233.732 217.991 237.081 217.954C243.396 217.847 249.71 217.873 256.023 218.03C264.721 217.948 273.611 218.558 282.283 217.919L316.158 217.961C316.215 225.19 316.23 232.42 316.205 239.649C316.2 243.334 316.034 247.101 316.217 250.777L382.02 250.742C380.258 252.242 379.572 253.4 379.015 255.621C375.623 257.067 372.349 258.186 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663L305.359 267.78C304.526 268.174 303.726 268.445 302.836 268.679L302.422 268.516C302.97 267.994 303.581 267.707 304.249 267.371C303.346 267.089 302.592 267.405 301.795 267.828C300.798 268.358 299.724 269.109 298.638 269.418C296.45 270.04 293.748 268.782 292.771 271.723C291.539 275.429 292.836 276.598 289.342 279.245L289.264 279.106L289.746 279.665C289.922 279.642 290.098 279.617 290.274 279.596C290.788 279.534 291.072 279.562 291.552 279.784C283.761 280.886 276.08 271.943 269.481 268.727C269.532 267.685 269.414 267.036 268.848 266.155C266.793 262.951 261.551 259.21 258.011 257.869C256.773 257.4 255.382 257.17 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742C234.444 250.731 231.884 250.523 229.351 250.403Z" fill="#3D7ECD"/>
|
||||
<path d="M229.5 250.5C227.052 249.183 224.175 246.485 222.644 244.15C220.166 240.368 220.112 229.455 221.195 225.05C221.962 221.93 223.946 219.508 226.648 217.845C229.946 218.398 233.732 217.991 237.081 217.954C243.396 217.847 249.71 217.873 256.023 218.03C258.057 218.243 260.081 218.239 262.124 218.245C262.036 228.982 261.779 239.713 261.935 250.452C267.117 250.445 282.096 249.873 286.095 250.724C281.121 250.989 276.017 250.759 271.029 250.75C261.584 250.723 252.14 250.748 242.696 250.824C240.816 250.676 238.867 250.759 236.978 250.742C234.444 250.731 232.033 250.62 229.5 250.5Z" fill="#3158B7"/>
|
||||
<path d="M242.696 250.824C252.14 250.748 261.584 250.723 271.029 250.75C276.017 250.759 281.121 250.989 286.095 250.724C296.126 250.796 306.188 250.976 316.217 250.777L382.02 250.742C380.258 252.242 379.572 253.4 379.015 255.621C375.623 257.067 372.349 258.186 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663L305.359 267.78C304.526 268.174 303.726 268.445 302.836 268.679L302.422 268.516C302.97 267.994 303.581 267.707 304.249 267.371C303.346 267.089 302.592 267.405 301.795 267.828C300.798 268.358 299.724 269.109 298.638 269.418C296.45 270.04 293.748 268.782 292.771 271.723C291.539 275.429 292.836 276.598 289.342 279.245L289.264 279.106L289.746 279.665C289.922 279.642 290.098 279.617 290.274 279.596C290.788 279.534 291.072 279.562 291.552 279.784C283.761 280.886 276.08 271.943 269.481 268.727C269.532 267.685 269.414 267.036 268.848 266.155C266.793 262.951 261.551 259.21 258.011 257.869C256.773 257.4 255.382 257.17 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742C238.867 250.759 240.816 250.676 242.696 250.824Z" fill="url(#paint0_linear_4222_6997)"/>
|
||||
<path d="M236.978 250.742C238.867 250.759 240.816 250.676 242.696 250.824C242.881 250.874 243.066 250.928 243.252 250.974C245.298 251.479 247.92 251.212 250.051 251.224C248.443 251.53 247.073 251.291 245.943 252.702C245.85 253.55 245.913 253.633 246.31 254.399C248.336 255.702 252.778 255.161 254.087 256.899C250.725 256.497 247.482 255.358 244.173 254.665C241.651 254.137 239.029 253.962 236.466 253.728C236.969 252.907 236.631 251.749 236.978 250.742Z" fill="#15337C"/>
|
||||
<path d="M315.839 263.948C315.537 262.501 315.708 261.013 315.229 259.629C314.46 258.966 313.976 259.049 312.984 258.933C313.102 258.884 313.213 258.814 313.338 258.787C315.769 258.246 325.519 258.983 328.801 258.983L357.499 259.017C359.803 259.006 366.156 258.505 368.097 258.96C368.485 259.051 368.546 259.119 368.836 259.31C366.357 260.996 362.191 264.345 361.869 267.495C361.803 268.145 361.893 268.578 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965L337.631 281.175C336.996 280.978 336.122 280.707 335.64 280.22C335.013 279.586 332.112 273.818 330.826 272.131C327.237 267.42 322.458 264.909 316.638 264.129L316.192 264.037C314.993 265.535 316.083 270.149 315.579 272.213C315.076 269.916 316.559 267.352 315.272 265.334C314.562 264.951 314 264.949 313.234 265.15C310.643 265.828 308.244 267.144 305.601 267.663C307.941 265.704 312.848 264.583 315.839 263.948Z" fill="url(#paint1_linear_4222_6997)"/>
|
||||
<path d="M334.406 268.36C340.718 267.927 347.148 267.514 353.456 268.191C355.699 268.431 360.368 269.793 362.175 269.155L362.288 269.421C358.345 270.649 354.9 273.636 351.221 275.536C348.264 277.064 345.072 278.136 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965C338.013 279.917 337.843 278.75 337.605 277.665C336.155 274.684 336.233 271.392 334.406 268.36Z" fill="#4F91E0"/>
|
||||
<path d="M337.605 277.665C338.101 277.244 338.105 277.263 338.759 277.253C340.026 277.925 341.077 278.732 342.142 279.684C340.991 280.35 339.912 280.649 338.622 280.946L338.374 280.965C338.013 279.917 337.843 278.75 337.605 277.665Z" fill="#5BBFFC"/>
|
||||
<path d="M162.994 506.672C163.51 506.136 164.063 505.686 164.643 505.225C167.325 506.032 178.659 505.485 182.142 505.49L221.176 505.555C226.755 505.582 232.376 505.443 237.949 505.628C269.102 506.183 300.329 505.731 331.491 505.742L372.011 505.764C380.199 505.77 388.457 505.962 396.635 505.618C396.442 517.711 396.022 529.884 396.433 541.975C409.395 542.082 422.357 542.091 435.32 542.002C441.062 542.005 447.41 541.469 453.076 542.23C457.801 542.254 462.724 542.135 467.419 542.679C465.179 543.78 463.234 548.572 462.043 550.796V551.298L462.794 551.648C454.827 551.784 446.872 552.172 438.929 552.813C436.511 552.995 434.06 552.553 431.644 552.413C428.22 552.214 424.779 552.237 421.352 552.25C402.933 552.322 384.531 552.526 366.11 552.346L227.563 552.274C215.642 552.277 203.672 552.344 191.757 552.13C182.178 551.958 172.491 551.389 162.923 551.866C164.053 549.046 163.345 544.905 162.658 542.024C162.018 536.512 162.277 530.737 162.288 525.186C162.299 519.081 161.931 512.699 162.994 506.672Z" fill="#15337C"/>
|
||||
<path d="M162.994 506.672C163.51 506.136 164.063 505.686 164.643 505.225C167.325 506.032 178.659 505.485 182.142 505.49L221.176 505.555C226.755 505.582 232.376 505.443 237.949 505.628C237.694 517.722 237.219 529.932 237.571 542.021L396.433 541.975C409.395 542.082 422.357 542.091 435.32 542.002C441.062 542.005 447.41 541.469 453.076 542.23C445.432 542.447 437.752 542.287 430.104 542.288L384.066 542.238L236.646 542.27L181.968 542.237C175.536 542.231 169.083 541.914 162.658 542.024C162.018 536.512 162.277 530.737 162.288 525.186C162.299 519.081 161.931 512.699 162.994 506.672Z" fill="#3158B7"/>
|
||||
<path d="M237.949 505.628C269.102 506.183 300.329 505.731 331.491 505.742L372.011 505.764C380.199 505.77 388.457 505.962 396.635 505.618C396.442 517.711 396.022 529.884 396.433 541.975L237.571 542.021C237.219 529.932 237.694 517.722 237.949 505.628Z" fill="#3D7ECD"/>
|
||||
<path d="M316.173 450.214L316.356 450.171C327.599 451.012 338.68 453.515 349.747 455.526C360.085 457.318 370.442 458.993 380.817 460.552C388.881 461.984 396.892 463.653 404.942 465.147C409.11 465.92 413.349 466.406 417.485 467.324C418.03 466.869 417.89 466.842 417.96 466.175C418.868 471.139 419.01 474.417 418.882 479.505C424.212 480.991 428.904 484.71 433.752 487.295L467.07 504.914C467.988 505.502 468.749 505.944 468.955 507.111C469.514 510.282 469.469 539.486 468.739 541.824C468.292 542.267 468.021 542.487 467.419 542.679C462.724 542.135 457.801 542.254 453.076 542.23C447.41 541.469 441.062 542.005 435.32 542.002C422.357 542.091 409.395 542.082 396.433 541.975C396.022 529.884 396.442 517.711 396.635 505.618C388.457 505.962 380.199 505.77 372.011 505.764L331.491 505.742C300.329 505.731 269.102 506.183 237.949 505.628C232.376 505.443 226.755 505.582 221.176 505.555L182.142 505.49C178.659 505.485 167.325 506.032 164.643 505.225C166.684 503.613 169.31 502.543 171.632 501.378C176.276 499.048 181.007 496.831 185.604 494.419C192.121 490.999 198.566 487.372 204.999 483.795C207.005 482.679 208.919 481.328 210.961 480.297C211.664 479.943 212.437 479.729 213.192 479.519C213.447 477.939 213.28 476.121 213.292 474.511C213.314 471.755 213.495 469.182 213.961 466.462C214.147 466.81 214.01 466.597 214.452 467.044C227.245 465.759 239.827 462.451 252.483 460.143C260.461 458.819 268.511 457.946 276.475 456.519L300.283 452.407C305.401 451.522 310.98 450.069 316.173 450.214Z" fill="#73E4FA"/>
|
||||
<path d="M316.173 450.214L316.356 450.171C327.599 451.012 338.68 453.515 349.747 455.526C360.085 457.318 370.442 458.993 380.817 460.552C388.881 461.984 396.892 463.653 404.942 465.147C409.11 465.92 413.349 466.406 417.485 467.324C418.03 466.869 417.89 466.842 417.96 466.175C418.868 471.139 419.01 474.417 418.882 479.505C407.542 478.716 395.89 479.365 384.514 479.436C370.443 479.525 356.374 479.202 342.302 479.225L326.141 479.166C322.94 479.164 319.619 479.396 316.441 479.069C316.286 469.43 316.022 459.862 316.173 450.214Z" fill="#3D7ECD"/>
|
||||
<path d="M467.07 504.914C467.988 505.502 468.749 505.944 468.955 507.111C469.514 510.282 469.469 539.486 468.739 541.824C468.292 542.267 468.021 542.487 467.419 542.679C462.724 542.135 457.801 542.254 453.076 542.23C447.41 541.469 441.062 542.005 435.32 542.002C422.357 542.091 409.395 542.082 396.433 541.975C396.022 529.884 396.442 517.711 396.635 505.618C399.774 505.933 403.063 505.785 406.221 505.786L422.299 505.784C435.31 505.785 448.476 506.228 461.464 505.68C463.339 505.6 465.314 505.634 467.07 504.914Z" fill="#5BBFFC"/>
|
||||
<path d="M252.483 460.143C260.461 458.819 268.511 457.946 276.475 456.519L300.283 452.407C305.401 451.522 310.98 450.069 316.173 450.214C316.022 459.862 316.286 469.43 316.441 479.069C313.41 479.108 310.372 479.425 307.371 479.847C292.468 483.6 277.556 488.899 263.025 493.906C257.708 495.738 251.924 497.128 246.801 499.408C243.673 500.8 240.545 502.657 238.239 505.216L351.838 505.253L382.181 505.431C386.77 505.429 392.191 504.724 396.635 505.618C388.457 505.962 380.199 505.77 372.011 505.764L331.491 505.742C300.329 505.731 269.102 506.183 237.949 505.628C232.376 505.443 226.755 505.582 221.176 505.555L182.142 505.49C178.659 505.485 167.325 506.032 164.643 505.225C166.684 503.613 169.31 502.543 171.632 501.378C176.276 499.048 181.007 496.831 185.604 494.419C192.121 490.999 198.566 487.372 204.999 483.795C207.005 482.679 208.919 481.328 210.961 480.297C211.664 479.943 212.437 479.729 213.192 479.519C213.447 477.939 213.28 476.121 213.292 474.511C213.314 471.755 213.495 469.182 213.961 466.462C214.147 466.81 214.01 466.597 214.452 467.044C227.245 465.759 239.827 462.451 252.483 460.143Z" fill="url(#paint2_linear_4222_6997)"/>
|
||||
<path d="M252.483 460.143C260.461 458.819 268.511 457.946 276.475 456.519L300.283 452.407C305.401 451.522 310.98 450.069 316.173 450.214C316.022 459.862 316.286 469.43 316.441 479.069C313.41 479.108 310.372 479.425 307.371 479.847C280.73 478.905 253.933 479.206 227.271 479.298C222.578 479.314 217.879 479.538 213.192 479.519C213.447 477.939 213.28 476.121 213.292 474.511C213.314 471.755 213.495 469.182 213.961 466.462C214.147 466.81 214.01 466.597 214.452 467.044C227.245 465.759 239.827 462.451 252.483 460.143Z" fill="#15337C"/>
|
||||
<path d="M305.601 267.663C308.244 267.144 310.643 265.828 313.234 265.15C314 264.949 314.562 264.951 315.272 265.334C316.559 267.352 315.076 269.916 315.579 272.213C316.083 270.149 314.993 265.535 316.192 264.037L316.638 264.129C322.458 264.909 327.237 267.42 330.826 272.131C332.112 273.818 335.013 279.586 335.64 280.22C336.122 280.707 336.996 280.978 337.631 281.175L338.374 280.965L338.622 280.946C340.078 289.201 342.561 297.284 344.607 305.405C347.019 314.981 349.071 324.725 351.327 334.35L372.075 421.626C374.16 430.227 376.712 438.738 378.694 447.356C379.359 450.33 379.896 453.327 380.305 456.347C380.489 457.712 380.516 459.221 380.817 460.552C370.442 458.993 360.085 457.318 349.747 455.526C338.68 453.515 327.599 451.012 316.356 450.171L316.173 450.214C310.98 450.069 305.401 451.522 300.283 452.407L276.475 456.519C268.511 457.946 260.461 458.819 252.483 460.143C239.827 462.451 227.245 465.759 214.452 467.044C214.01 466.597 214.147 466.81 213.961 466.462C217.335 455.731 219.76 444.734 222.73 433.889L237.945 379.405L269.481 268.727C276.08 271.943 283.761 280.886 291.552 279.784C291.072 279.562 290.788 279.534 290.274 279.596C290.098 279.617 289.922 279.642 289.746 279.665L289.264 279.106L289.342 279.245C292.836 276.598 291.539 275.429 292.771 271.723C293.748 268.782 296.45 270.04 298.638 269.418C299.724 269.109 300.798 268.358 301.795 267.828C302.592 267.405 303.346 267.089 304.249 267.371C303.581 267.707 302.97 267.994 302.422 268.516L302.836 268.679C303.726 268.445 304.526 268.174 305.359 267.78L305.601 267.663Z" fill="#3D7ECD"/>
|
||||
<path d="M213.961 466.462C217.335 455.731 219.76 444.734 222.73 433.889L237.945 379.405L269.481 268.727C276.08 271.943 283.761 280.886 291.552 279.784C294.318 279.786 297.526 280.103 300.239 279.671C302.32 279.34 293.35 281.165 295.5 281C292.765 282.129 294.815 282.321 291.94 282.461C291.8 282.468 291.66 282.481 291.519 282.489C291.435 282.494 291.35 282.496 291.266 282.5C290.329 287.67 289.473 292.882 288.349 298.015L265.21 399.097L256.243 437.602C255.364 441.302 250.844 457.078 251.4 459.744C251.766 459.902 252.097 460.037 252.483 460.143C239.827 462.451 227.245 465.759 214.452 467.044C214.01 466.597 214.147 466.81 213.961 466.462Z" fill="#3158B7"/>
|
||||
<path d="M316.638 264.129C322.458 264.909 327.237 267.42 330.826 272.131C332.112 273.818 335.013 279.586 335.64 280.22C336.122 280.707 336.996 280.978 337.631 281.175L338.374 280.965L338.622 280.946C340.078 289.201 342.561 297.284 344.607 305.405C347.019 314.981 349.071 324.725 351.327 334.35L372.075 421.626C374.16 430.227 376.712 438.738 378.694 447.356C379.359 450.33 379.896 453.327 380.305 456.347C380.489 457.712 380.516 459.221 380.817 460.552C370.442 458.993 360.085 457.318 349.747 455.526C338.68 453.515 327.599 451.012 316.356 450.171L316.124 267.318C316.132 266.225 316.016 265.039 316.638 264.129Z" fill="#5BBFFC"/>
|
||||
<path d="M162.602 542.012C222.681 542.667 282.903 542.133 343 542.146L421.144 542.172C436.934 542.179 452.86 542.406 468.631 542C468.259 556.284 468.631 576.5 466.168 585H164.5C162.602 574 162.11 556.297 162.602 542.012Z" fill="#2E57AB"/>
|
||||
<path d="M263.193 261.724L235.532 253.517L232.5 252.5L229.5 250.5L402 250L377.5 261.724L364 275.5L339.134 284H289.345L269.731 271.69L263.193 261.724Z" fill="#2950B6"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_4222_6997" x1="313.33" y1="251.065" x2="313.326" y2="279.202" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#122869"/>
|
||||
<stop offset="1" stop-color="#2950B6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_4222_6997" x1="342.025" y1="256.698" x2="339.592" y2="280.614" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#3052A7"/>
|
||||
<stop offset="1" stop-color="#2671CE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_4222_6997" x1="233.914" y1="479.018" x2="235.081" y2="504.885" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#486DC9"/>
|
||||
<stop offset="1" stop-color="#599BEA"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 45" width="45" height="45">
|
||||
<title>Checkmate</title>
|
||||
<desc>King silhouette adapted from Cburnett's chess set (Wikimedia Commons, CC BY-SA 3.0).</desc>
|
||||
<g fill="none" stroke="#13715B" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
||||
<path stroke-linejoin="miter" d="M22.5 11.63V6M20 8h5"/>
|
||||
<path fill="#fff" stroke-linecap="butt" stroke-linejoin="miter" d="M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5"/>
|
||||
<path fill="#fff" d="M12.5 37c5.5 3.5 14.5 3.5 20 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-2.5-7.5-12-10.5-16-4-3 6 6 10.5 6 10.5v7"/>
|
||||
<path d="M12.5 30c5.5-3 14.5-3 20 0m-20 3.5c5.5-3 14.5-3 20 0m-20 3.5c5.5-3 14.5-3 20 0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 819 B |
+179
-57
@@ -13,7 +13,7 @@
|
||||
"content": "تحذير: لم تقم بإضافة مفتاح Google PageSpeed API بعد. قم بزيارة <settingsLink>الإعدادات</settingsLink> لإضافته. بدونه، لن تعمل مراقبة PageSpeed."
|
||||
}
|
||||
},
|
||||
"appName": "",
|
||||
"appName": "Checkmate",
|
||||
"breadcrumbs": {
|
||||
"details": "التفاصيل",
|
||||
"home": "الرئيسية"
|
||||
@@ -35,11 +35,11 @@
|
||||
"sendInvite": "إرسال دعوة",
|
||||
"test": "اختبار",
|
||||
"testNotifications": "اختبار الإشعارات",
|
||||
"toggleTheme": "",
|
||||
"toggleTheme": "تبديل الوضع الفاتح والداكن",
|
||||
"flushQueue": "تفريغ قائمة الانتظار",
|
||||
"notFound": "الانتقال إلى لوحة التحكم الرئيسية",
|
||||
"resetPassword": "",
|
||||
"reset": "",
|
||||
"resetPassword": "إعادة تعيين كلمة المرور",
|
||||
"reset": "إعادة تعيين",
|
||||
"clear": "مسح",
|
||||
"addDemo": "إضافة مراقبات تجريبية",
|
||||
"removeMonitors": "إزالة المراقبات",
|
||||
@@ -53,8 +53,8 @@
|
||||
"labels": {
|
||||
"averageResponseTime": "متوسط وقت الاستجابة",
|
||||
"downtime": "وقت التوقف",
|
||||
"high": "",
|
||||
"low": "",
|
||||
"high": "مرتفع",
|
||||
"low": "منخفض",
|
||||
"uptime": "وقت التشغيل"
|
||||
},
|
||||
"histogram": {
|
||||
@@ -86,12 +86,12 @@
|
||||
"name": {
|
||||
"option": {
|
||||
"firstName": {
|
||||
"label": "",
|
||||
"placeholder": ""
|
||||
"label": "الاسم الأول",
|
||||
"placeholder": "أدخل اسمك الأول"
|
||||
},
|
||||
"lastName": {
|
||||
"label": "",
|
||||
"placeholder": ""
|
||||
"label": "اسم العائلة",
|
||||
"placeholder": "أدخل اسم عائلتك"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -107,14 +107,14 @@
|
||||
"table": {
|
||||
"empty": "لا يوجد شيء هنا",
|
||||
"headers": {
|
||||
"actions": "",
|
||||
"actions": "إجراءات",
|
||||
"dateTime": "التاريخ والوقت",
|
||||
"message": "الرسالة",
|
||||
"monitor": "المراقب",
|
||||
"monitorId": "معرّف المراقب",
|
||||
"name": "الاسم",
|
||||
"status": "الحالة",
|
||||
"type": "",
|
||||
"type": "النوع",
|
||||
"url": "الرابط",
|
||||
"interval": "الفاصل الزمني",
|
||||
"active": "نشط",
|
||||
@@ -125,17 +125,17 @@
|
||||
"components": {
|
||||
"imageUpload": {
|
||||
"clickToUpload": "انقر للرفع",
|
||||
"dragAndDrop": "",
|
||||
"supportedFormats": "",
|
||||
"maxSize": "",
|
||||
"dragAndDrop": "أو اسحب وأسقط",
|
||||
"supportedFormats": "الصيغ المدعومة",
|
||||
"maxSize": "الحجم الأقصى",
|
||||
"orDragAndDrop": "أو اسحب وأفلت",
|
||||
"errors": {
|
||||
"invalidFileSize": "",
|
||||
"invalidFileFormat": ""
|
||||
"invalidFileSize": "حجم الملف كبير جدًا!",
|
||||
"invalidFileFormat": "تنسيق الملف غير مدعوم!"
|
||||
}
|
||||
},
|
||||
"headerStatusPageControls": {
|
||||
"publicLink": ""
|
||||
"publicLink": "رابط عام"
|
||||
},
|
||||
"headerTimeRange": {
|
||||
"labels": {
|
||||
@@ -155,26 +155,26 @@
|
||||
"serverUnreachable": "تعذر الوصول إلى الخادم",
|
||||
"retry": "إعادة المحاولة",
|
||||
"retrying": "جارٍ إعادة المحاولة...",
|
||||
"reconnected": ""
|
||||
"reconnected": "تمت استعادة الاتصال"
|
||||
},
|
||||
"sidebar": {
|
||||
"menu": {
|
||||
"uptime": "",
|
||||
"pagespeed": "",
|
||||
"infrastructure": "",
|
||||
"notifications": "",
|
||||
"uptime": "وقت التشغيل",
|
||||
"pagespeed": "Pagespeed",
|
||||
"infrastructure": "البنية التحتية",
|
||||
"notifications": "الإشعارات",
|
||||
"checks": "الفحوصات",
|
||||
"incidents": "",
|
||||
"statusPages": "",
|
||||
"maintenance": "",
|
||||
"logs": "",
|
||||
"settings": ""
|
||||
"incidents": "الحوادث",
|
||||
"statusPages": "صفحات الحالة",
|
||||
"maintenance": "الصيانة",
|
||||
"logs": "السجلات",
|
||||
"settings": "الإعدادات"
|
||||
},
|
||||
"bottomMenu": {
|
||||
"support": "",
|
||||
"discussions": "",
|
||||
"docs": "",
|
||||
"changelog": ""
|
||||
"support": "الدعم",
|
||||
"discussions": "المناقشات",
|
||||
"docs": "الوثائق",
|
||||
"changelog": "سجل التغييرات"
|
||||
},
|
||||
"accountMenu": {
|
||||
"profile": "الملف الشخصي",
|
||||
@@ -186,19 +186,27 @@
|
||||
"description": "اطلع على أحدث الإصدارات وساعد في تنمية المجتمع على GitHub"
|
||||
},
|
||||
"authFooter": {
|
||||
"navControls": "",
|
||||
"logOut": "",
|
||||
"navControls": "عناصر التحكم",
|
||||
"logOut": "تسجيل الخروج",
|
||||
"roles": {
|
||||
"superAdmin": "مسؤول أعلى",
|
||||
"admin": "مسؤول",
|
||||
"user": "مستخدم",
|
||||
"demoUser": ""
|
||||
"demoUser": "مستخدم تجريبي"
|
||||
}
|
||||
}
|
||||
},
|
||||
"starPrompt": {
|
||||
"title": "أضف نجمة لـ Checkmate",
|
||||
"description": "اطلع على أحدث الإصدارات وساعد في تنمية المجتمع على GitHub"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "الدعم",
|
||||
"discussions": "المناقشات",
|
||||
"docs": "التوثيق",
|
||||
"changelog": "سجل التغييرات"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -251,15 +259,15 @@
|
||||
"team": {
|
||||
"filter": {
|
||||
"placeholder": "تصفية حسب الدور",
|
||||
"all": "",
|
||||
"all": "كل الأدوار",
|
||||
"admin": "مسؤول",
|
||||
"member": ""
|
||||
"member": "عضو"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"email": "البريد الإلكتروني",
|
||||
"role": "الدور",
|
||||
"created": ""
|
||||
"created": "تم الإنشاء في"
|
||||
}
|
||||
},
|
||||
"addMember": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "اختر دوراً"
|
||||
},
|
||||
"linkLabel": "رابط الدعوة"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "لا يوجد بعد أعضاء فريق",
|
||||
"description": "ادعُ زملاءك عبر البريد الإلكتروني أو أضفهم مباشرة. بمجرد انضمامهم، سيظهرون هنا مع دورهم."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "الحساب",
|
||||
"description": "إدارة ملفك الشخصي وكلمة المرور والفريق وتفضيلات مساحة العمل."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "المراقبة المفتوحة المصدر للبنية التحتية",
|
||||
"tagline": "راقب كل خطوة تقوم بها خوادمك.",
|
||||
"description": "تتبع حالة التشغيل وأوقات الاستجابة والحوادث في الوقت الفعلي - ذاتية الاستضافة وتبقى لك."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "مرحباً بعودتك إلى Checkmate!",
|
||||
"subtitle": "سجّل للبدء",
|
||||
"submit": "تسجيل"
|
||||
"submit": "تسجيل",
|
||||
"setupNotice": "هذه الصفحة متاحة فقط أثناء الإعداد الأولي. بمجرد تسجيل المسؤول الأعلى، يمكن دعوة مستخدمين إضافيين من إعدادات الفريق."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "نسيت كلمة المرور؟",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "رمز الحالة",
|
||||
"location": "الموقع"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "لا توجد فحوصات بعد",
|
||||
"description": "بمجرد إنشاء جهاز مراقبة، ستظهر هنا كل عملية فحص حالة ووقت استجابة كفحص."
|
||||
},
|
||||
"header": {
|
||||
"title": "الفحوصات",
|
||||
"description": "كل فحص يجريه Checkmate على مراقبيك يظهر هنا برمز الحالة ووقت الاستجابة."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "نشط منذ",
|
||||
"certificateExpiry": "انتهاء الشهادة",
|
||||
"lastCheck": "آخر فحص",
|
||||
"lastResponseTime": "آخر وقت استجابة"
|
||||
"lastResponseTime": "آخر وقت استجابة",
|
||||
"serviceIsDown": "الخدمة معطلة"
|
||||
},
|
||||
"status": {
|
||||
"down": "متوقف",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "لا حوادث — جميع الأنظمة سليمة",
|
||||
"description": "عندما يتعطل جهاز مراقبة أو يتعافى، سيظهر الحادث هنا مع الأوقات وتفاصيل الجهاز وسجل الحل."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "حل الحادثة",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "نشط",
|
||||
"resolved": "تم الحل"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "الحوادث",
|
||||
"description": "عندما يتعطل جهاز مراقبة أو يتعافى، تظهر الحوادث هنا مع الأوقات وتفاصيل الجهاز وسجل الحل."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,21 +813,31 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "أنشئ مراقباً!",
|
||||
"checks": "تتبع أداء خوادمك,تحديد الاختناقات وتحسين الاستخدام,ضمان الموثوقية من خلال المراقبة في الوقت الفعلي",
|
||||
"title": "يُستخدم مراقب البنية التحتية من أجل:"
|
||||
"title": "لا توجد بعد أجهزة مراقبة للبنية التحتية",
|
||||
"description": "تتبّع أداء الخوادم وحدد الاختناقات واضمن الموثوقية مع مراقبة البنية التحتية في الوقت الفعلي."
|
||||
},
|
||||
"header": {
|
||||
"title": "مراقبات البنية التحتية",
|
||||
"description": "تتبّع أداء الخوادم وحدد الاختناقات واضمن الموثوقية مع مراقبة البنية التحتية في الوقت الفعلي."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "لا توجد سجلات بعد",
|
||||
"description": "ستظهر هنا نشاط الخادم والتحذيرات والأخطاء أثناء تشغيل Checkmate."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "",
|
||||
"logs": "",
|
||||
"queue": ""
|
||||
"diagnostics": "التشخيص",
|
||||
"logs": "السجلات",
|
||||
"queue": "قائمة المهام"
|
||||
},
|
||||
"logLevelSelect": {
|
||||
"label": "مستوى السجل"
|
||||
},
|
||||
"jobQueue": "قائمة المهام",
|
||||
"jobQueueExplainer": "<highlight>الصفوف المميزة</highlight> هي المهام التي تتم معالجتها حالياً بواسطة عامل.",
|
||||
"failedJobs": "المهام الفاشلة",
|
||||
"failedJobsExplainer": "حالات الفشل الأخيرة حسب المراقب — وقت آخر فشل، وعدد مرات الفشل، والسبب.",
|
||||
"noLogs": "لم يتم العثور على سجلات",
|
||||
"metrics": {
|
||||
"jobs": "المهام",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% من 1 ثانية مستخدمة بواسطة CPU",
|
||||
"total": "الإجمالي",
|
||||
"used": "مستخدم"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "إحصائيات التشغيل",
|
||||
"description": "لقطة لعملية Node.js والجهاز المضيف. يتم التحديث كل 5 ثوانٍ."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "الذاكرة والمعالج",
|
||||
"description": "كيف تستخدم العملية الذاكرة المخصصة لها ومعالج الجهاز المضيف."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "آخر فشل في",
|
||||
"failReason": "سبب الفشل"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "لا توجد مهام في قائمة الانتظار",
|
||||
"description": "ستظهر هنا فحوصات أجهزة المراقبة المجدولة أو قيد التشغيل. قائمة الانتظار الفارغة تعني أن كل شيء محدّث."
|
||||
},
|
||||
"header": {
|
||||
"title": "السجلات وقائمة الانتظار",
|
||||
"description": "افحص سجلات الخادم وقائمة انتظار مهام المراقبة وتشخيصات وقت التشغيل في مكان واحد."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "أنشئ نافذة صيانة!",
|
||||
"checks": "تحديد فترات الصيانة,التخلص من أي سوء فهم,إيقاف إرسال التنبيهات أثناء نوافذ الصيانة",
|
||||
"title": "تُستخدم نافذة الصيانة من أجل:"
|
||||
"title": "لا توجد نوافذ صيانة مجدولة",
|
||||
"description": "حدد مواعيد التوقف المخطط لها لإيقاف التنبيهات وإعلام فريقك ومستخدميك بما يتوقعونه."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "نوافذ الصيانة",
|
||||
"description": "حدد مواعيد التوقف المخطط لها لإيقاف التنبيهات وإعلام فريقك ومستخدميك بما يتوقعونه."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "إنشاء قناة",
|
||||
"checks": "تنبيه الفرق حول التوقف أو مشكلات الأداء,إعلام المهندسين عند حدوث الحوادث,إبقاء المسؤولين على اطلاع بتغييرات النظام",
|
||||
"title": "تُستخدم قنوات الإشعارات من أجل:"
|
||||
"title": "لا توجد بعد قنوات إشعار",
|
||||
"description": "اربط Slack وDiscord والبريد الإلكتروني وWebhooks والمزيد ليعلم الأشخاص المناسبون بالحوادث فور حدوثها."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "معرّف المحادثة",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "إعدادات Pushover",
|
||||
"description": "أدخل رمز التطبيق ومفتاح المستخدم في Pushover.",
|
||||
"optionAppToken": "رمز التطبيق",
|
||||
"placeholderAppToken": "أدخل رمز التطبيق",
|
||||
"optionUserKey": "مفتاح المستخدم",
|
||||
"placeholderUserKey": "أدخل مفتاح المستخدم"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "إعدادات Twilio",
|
||||
"description": "أدخل بيانات اعتماد حساب Twilio لإرسال الرسائل النصية.",
|
||||
"optionAccountSid": "معرف الحساب (SID)",
|
||||
"placeholderAccountSid": "أدخل معرف الحساب",
|
||||
"optionAuthToken": "رمز المصادقة",
|
||||
"placeholderAuthToken": "أدخل رمز المصادقة",
|
||||
"optionFromNumber": "من الرقم",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "إلى الرقم",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "الوجهة"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "الإشعارات",
|
||||
"description": "اربط Slack وDiscord والبريد الإلكتروني وWebhooks والمزيد ليعلم الأشخاص المناسبون بالحوادث فور حدوثها."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "أنشئ مراقباً!",
|
||||
"checks": "تقديم تقرير عن تجربة المستخدم للصفحة,المساعدة في تحليل سرعة الصفحة,تقديم اقتراحات لتحسين الصفحة",
|
||||
"title": "يُستخدم مراقب PageSpeed من أجل:"
|
||||
"title": "لا توجد بعد أجهزة مراقبة PageSpeed",
|
||||
"description": "تابع Core Web Vitals ودرجات Lighthouse عبر الزمن لاكتشاف التراجع قبل أن يلاحظه المستخدمون."
|
||||
},
|
||||
"header": {
|
||||
"title": "مراقبات PageSpeed",
|
||||
"description": "تابع Core Web Vitals ودرجات Lighthouse عبر الزمن لاكتشاف التراجع قبل أن يلاحظه المستخدمون."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "يرجى إصلاح أخطاء التحقق التالية:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "الإعدادات",
|
||||
"description": "تكوين SMTP والتكاملات والاحتفاظ والسلوك العام للتطبيق."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "تم حذف صفحة الحالة بنجاح",
|
||||
"fallback": {
|
||||
"title": "تُستخدم صفحة الحالة من أجل:",
|
||||
"checks": "إيصال حالة النظام للمستخدمين وأصحاب المصلحة,عرض معلومات وقت التشغيل في الوقت الفعلي للعامة,بناء الثقة من خلال مراقبة الخدمة الشفافة,تقليل طلبات الدعم أثناء الحوادث",
|
||||
"actionButton": "أنشئ صفحة حالة!"
|
||||
"title": "لا توجد بعد صفحات حالة",
|
||||
"actionButton": "أنشئ صفحة حالة!",
|
||||
"description": "انشر صفحة عامة تُظهر للعملاء وأصحاب المصلحة وقت التشغيل الفعلي وتاريخ الحوادث."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "خريطة حرارية",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "جميع الأنظمة متوقفة",
|
||||
"allUp": "جميع الأنظمة تعمل بشكل طبيعي",
|
||||
"degraded": "بعض الأنظمة تواجه مشكلات",
|
||||
"unknown": "تعذر تحديد حالة النظام"
|
||||
"unknown": "تعذر تحديد حالة النظام",
|
||||
"allBreached": "تجاوزت جميع الأنظمة الحدود",
|
||||
"allMaintenance": "جميع الأنظمة قيد الصيانة",
|
||||
"allPaused": "جميع الأنظمة متوقفة مؤقتًا",
|
||||
"allInitializing": "جميع الأنظمة قيد التهيئة",
|
||||
"breachedAndDown": "تجاوزت بعض الأنظمة الحدود وهي معطلة",
|
||||
"breached": "تجاوزت بعض الأنظمة الحدود",
|
||||
"maintenanceAndDown": "بعض الأنظمة معطلة أثناء الصيانة",
|
||||
"maintenance": "بعض الأنظمة قيد الصيانة",
|
||||
"partiallyPaused": "بعض الأنظمة متوقفة مؤقتًا",
|
||||
"initializing": "بعض الأنظمة قيد التهيئة",
|
||||
"noMonitors": "لم يتم تكوين أي شاشة"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "صفحات الحالة",
|
||||
"description": "انشر صفحات عامة تُظهر للعملاء وأصحاب المصلحة وقت التشغيل الفعلي وتاريخ الحوادث."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "أنشئ مراقباً!",
|
||||
"checks": "التحقق مما إذا كانت المواقع أو الخوادم متصلة ومتجاوبة,تنبيه الفرق حول التوقف أو مشكلات الأداء,مراقبة نقاط نهاية HTTP والـ Ping والحاويات والمنافذ,تتبع اتجاهات وقت التشغيل والموثوقية التاريخية",
|
||||
"title": "يُستخدم مراقب وقت التشغيل من أجل:"
|
||||
"title": "لا توجد بعد أجهزة مراقبة وقت التشغيل",
|
||||
"description": "راقب نقاط نهاية HTTP وعمليات Ping والحاويات والمنافذ — احصل على تنبيه فور حدوث عطل."
|
||||
},
|
||||
"header": {
|
||||
"title": "مراقبات وقت التشغيل",
|
||||
"description": "راقب نقاط نهاية HTTP وعمليات Ping والحاويات والمنافذ — احصل على تنبيه فور حدوث عطل."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+171
-49
@@ -39,7 +39,7 @@
|
||||
"flushQueue": "Vyprázdnit frontu",
|
||||
"notFound": "Přejít na hlavní přehled",
|
||||
"resetPassword": "Obnovit heslo",
|
||||
"reset": "",
|
||||
"reset": "Resetovat",
|
||||
"clear": "Vymazat",
|
||||
"addDemo": "Přidat ukázkové monitory",
|
||||
"removeMonitors": "Odebrat monitory",
|
||||
@@ -53,8 +53,8 @@
|
||||
"labels": {
|
||||
"averageResponseTime": "Průměrná doba odezvy",
|
||||
"downtime": "Výpadek",
|
||||
"high": "",
|
||||
"low": "",
|
||||
"high": "Vysoké",
|
||||
"low": "Nízké",
|
||||
"uptime": "Dostupnost"
|
||||
},
|
||||
"histogram": {
|
||||
@@ -107,14 +107,14 @@
|
||||
"table": {
|
||||
"empty": "Zde nic není",
|
||||
"headers": {
|
||||
"actions": "",
|
||||
"actions": "Akce",
|
||||
"dateTime": "Datum a čas",
|
||||
"message": "Zpráva",
|
||||
"monitor": "Monitor",
|
||||
"monitorId": "ID monitoru",
|
||||
"name": "Název",
|
||||
"status": "Stav",
|
||||
"type": "",
|
||||
"type": "Typ",
|
||||
"url": "URL",
|
||||
"interval": "Interval",
|
||||
"active": "Aktivní",
|
||||
@@ -125,17 +125,17 @@
|
||||
"components": {
|
||||
"imageUpload": {
|
||||
"clickToUpload": "Klikněte pro nahrání",
|
||||
"dragAndDrop": "",
|
||||
"supportedFormats": "",
|
||||
"maxSize": "",
|
||||
"dragAndDrop": "nebo přetáhněte",
|
||||
"supportedFormats": "Podporované formáty",
|
||||
"maxSize": "Max. velikost",
|
||||
"orDragAndDrop": "nebo přetáhněte soubor",
|
||||
"errors": {
|
||||
"invalidFileSize": "",
|
||||
"invalidFileFormat": ""
|
||||
"invalidFileSize": "Soubor je příliš velký!",
|
||||
"invalidFileFormat": "Nepodporovaný formát souboru!"
|
||||
}
|
||||
},
|
||||
"headerStatusPageControls": {
|
||||
"publicLink": ""
|
||||
"publicLink": "Veřejný odkaz"
|
||||
},
|
||||
"headerTimeRange": {
|
||||
"labels": {
|
||||
@@ -159,22 +159,22 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"menu": {
|
||||
"uptime": "",
|
||||
"pagespeed": "",
|
||||
"infrastructure": "",
|
||||
"notifications": "",
|
||||
"uptime": "Dostupnost",
|
||||
"pagespeed": "Pagespeed",
|
||||
"infrastructure": "Infrastruktura",
|
||||
"notifications": "Oznámení",
|
||||
"checks": "Kontroly",
|
||||
"incidents": "",
|
||||
"statusPages": "",
|
||||
"maintenance": "",
|
||||
"logs": "",
|
||||
"settings": ""
|
||||
"incidents": "Incidenty",
|
||||
"statusPages": "Stavové stránky",
|
||||
"maintenance": "Údržba",
|
||||
"logs": "Záznamy",
|
||||
"settings": "Nastavení"
|
||||
},
|
||||
"bottomMenu": {
|
||||
"support": "",
|
||||
"discussions": "",
|
||||
"docs": "",
|
||||
"changelog": ""
|
||||
"support": "Podpora",
|
||||
"discussions": "Diskuze",
|
||||
"docs": "Dokumentace",
|
||||
"changelog": "Záznam změn"
|
||||
},
|
||||
"accountMenu": {
|
||||
"profile": "Profil",
|
||||
@@ -186,19 +186,27 @@
|
||||
"description": "Sledujte nejnovější vydání a pomozte rozšířit komunitu na GitHubu"
|
||||
},
|
||||
"authFooter": {
|
||||
"navControls": "",
|
||||
"logOut": "",
|
||||
"navControls": "Ovládací prvky",
|
||||
"logOut": "Odhlásit se",
|
||||
"roles": {
|
||||
"superAdmin": "Superadministrátor",
|
||||
"admin": "Administrátor",
|
||||
"user": "Uživatel",
|
||||
"demoUser": ""
|
||||
"demoUser": "Demo uživatel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"starPrompt": {
|
||||
"title": "Ohodnoťte Checkmate",
|
||||
"description": "Sledujte nejnovější vydání a pomozte rozšířit komunitu na GitHubu"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Podpora",
|
||||
"discussions": "Diskuze",
|
||||
"docs": "Dokumentace",
|
||||
"changelog": "Seznam změn"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -251,15 +259,15 @@
|
||||
"team": {
|
||||
"filter": {
|
||||
"placeholder": "Filtrovat podle role",
|
||||
"all": "",
|
||||
"all": "Všechny role",
|
||||
"admin": "Administrátor",
|
||||
"member": ""
|
||||
"member": "Člen"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"email": "Email",
|
||||
"role": "Role",
|
||||
"created": ""
|
||||
"created": "Vytvořeno"
|
||||
}
|
||||
},
|
||||
"addMember": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "Vyberte roli"
|
||||
},
|
||||
"linkLabel": "Odkaz pro pozvánku"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Zatím žádní členové týmu",
|
||||
"description": "Pozvěte kolegy e-mailem nebo je přidejte přímo. Jakmile se připojí, objeví se zde se svou rolí."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Účet",
|
||||
"description": "Spravujte profil, heslo, tým a předvolby pracovního prostoru."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Open-source monitoring infrastruktury",
|
||||
"tagline": "Sledujte každý krok vašich serverů.",
|
||||
"description": "Monitorování dostupnosti, doby odezvy a incidentů v reálném čase - self-hosted a vaše."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "Vítejte v Checkmate!",
|
||||
"subtitle": "Zaregistrujte se a začněte",
|
||||
"submit": "Registrovat"
|
||||
"submit": "Registrovat",
|
||||
"setupNotice": "Tato stránka je k dispozici pouze během počátečního nastavení. Po zaregistrování super administrátora lze pozvat další uživatele z nastavení týmu."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "Zapomněli jste heslo?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "Stavový kód",
|
||||
"location": "Umístění"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Zatím žádné kontroly",
|
||||
"description": "Jakmile vytvoříte monitor, každá kontrola stavu a doba odezvy se zde zobrazí jako kontrola."
|
||||
},
|
||||
"header": {
|
||||
"title": "Kontroly",
|
||||
"description": "Každá sonda, kterou Checkmate spustí proti vašim monitorům, se zde objeví se stavovým kódem a dobou odezvy."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Aktivní po dobu",
|
||||
"certificateExpiry": "Expirace certifikátu",
|
||||
"lastCheck": "Poslední kontrola",
|
||||
"lastResponseTime": "Poslední doba odezvy"
|
||||
"lastResponseTime": "Poslední doba odezvy",
|
||||
"serviceIsDown": "Služba je nedostupná"
|
||||
},
|
||||
"status": {
|
||||
"down": "nedostupný",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Žádné incidenty — všechny systémy v pořádku",
|
||||
"description": "Když monitor vypadne nebo se zotaví, incident se zobrazí zde spolu s časem, detaily monitoru a historií řešení."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Vyřešit incident",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Aktivní",
|
||||
"resolved": "Vyřešeno"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Incidenty",
|
||||
"description": "Když monitor vypadne nebo se zotaví, incidenty se zobrazí zde spolu s časem, detaily monitoru a historií řešení."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,21 +813,31 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Vytvořte monitor!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "Monitor infrastruktury slouží k:"
|
||||
"title": "Zatím žádné monitory infrastruktury",
|
||||
"description": "Sledujte výkon serverů, identifikujte úzká místa a zajistěte spolehlivost pomocí monitoringu infrastruktury v reálném čase."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitory infrastruktury",
|
||||
"description": "Sledujte výkon serverů, identifikujte úzká místa a zajistěte spolehlivost pomocí monitoringu infrastruktury v reálném čase."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Zatím žádné protokoly",
|
||||
"description": "Aktivita serveru, varování a chyby se zobrazí zde, jak Checkmate běží."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "",
|
||||
"logs": "",
|
||||
"queue": ""
|
||||
"diagnostics": "Diagnostika",
|
||||
"logs": "Záznamy",
|
||||
"queue": "Fronta úloh"
|
||||
},
|
||||
"logLevelSelect": {
|
||||
"label": "Úroveň logování"
|
||||
},
|
||||
"jobQueue": "Fronta úloh",
|
||||
"jobQueueExplainer": "<highlight>Zvýrazněné řádky</highlight> jsou úlohy, které právě zpracovává worker.",
|
||||
"failedJobs": "Neúspěšné úlohy",
|
||||
"failedJobsExplainer": "Nedávná selhání podle monitoru — čas posledního selhání, počet selhání a důvod.",
|
||||
"noLogs": "Žádné logy nebyly nalezeny",
|
||||
"metrics": {
|
||||
"jobs": "Úlohy",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% z 1s využito CPU",
|
||||
"total": "Celkem",
|
||||
"used": "Použité"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Statistiky běhu",
|
||||
"description": "Snímek procesu Node.js a hostitelského počítače. Aktualizuje se každých 5 sekund."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Paměť a CPU",
|
||||
"description": "Jak proces využívá přidělenou paměť a CPU hostitele."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "Poslední selhání",
|
||||
"failReason": "Důvod selhání"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "Žádné úlohy ve frontě",
|
||||
"description": "Naplánované nebo běžící kontroly monitorů se objeví zde. Prázdná fronta znamená, že je vše aktuální."
|
||||
},
|
||||
"header": {
|
||||
"title": "Protokoly a fronta",
|
||||
"description": "Zkontrolujte serverové protokoly, frontu úloh monitoru a diagnostiku v jednom místě."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Vytvořte okno údržby!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "Okno údržby slouží k:"
|
||||
"title": "Žádná naplánovaná okna údržby",
|
||||
"description": "Naplánujte plánované odstávky, aby byly výstrahy potlačeny a váš tým i uživatelé věděli, co očekávat."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Okna údržby",
|
||||
"description": "Naplánujte plánované odstávky, aby byly výstrahy potlačeny a váš tým i uživatelé věděli, co očekávat."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Vytvořit kanál",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "Kanály oznámení slouží k:"
|
||||
"title": "Zatím žádné notifikační kanály",
|
||||
"description": "Připojte Slack, Discord, e-mail, webhooky a další, aby se ti správní lidé dozvěděli o incidentech v okamžiku, kdy nastanou."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "ID chatu",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Konfigurace Pushover",
|
||||
"description": "Zadejte token aplikace a uživatelský klíč Pushover.",
|
||||
"optionAppToken": "Token aplikace",
|
||||
"placeholderAppToken": "Zadejte token aplikace",
|
||||
"optionUserKey": "Uživatelský klíč",
|
||||
"placeholderUserKey": "Zadejte uživatelský klíč"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Konfigurace Twilio",
|
||||
"description": "Zadejte přihlašovací údaje účtu Twilio pro odesílání SMS.",
|
||||
"optionAccountSid": "SID účtu",
|
||||
"placeholderAccountSid": "Zadejte SID účtu",
|
||||
"optionAuthToken": "Autentizační token",
|
||||
"placeholderAuthToken": "Zadejte autentizační token",
|
||||
"optionFromNumber": "Z čísla",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Na číslo",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Cíl"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Notifikace",
|
||||
"description": "Připojte Slack, Discord, e-mail, webhooky a další, aby se ti správní lidé dozvěděli o incidentech v okamžiku, kdy nastanou."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Vytvořte monitor!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "Monitor PageSpeed slouží k:"
|
||||
"title": "Zatím žádné PageSpeed monitory",
|
||||
"description": "Sledujte Core Web Vitals a skóre Lighthouse v čase a zachyťte regrese dříve než vaši uživatelé."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitory PageSpeed",
|
||||
"description": "Sledujte Core Web Vitals a skóre Lighthouse v čase a zachyťte regrese dříve než vaši uživatelé."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Opravte prosím následující chyby validace:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Nastavení",
|
||||
"description": "Nakonfigurujte SMTP, integrace, uchovávání a globální chování aplikace."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Stavová stránka byla úspěšně smazána",
|
||||
"fallback": {
|
||||
"title": "Stavová stránka slouží k:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "Vytvořte stavovou stránku!"
|
||||
"title": "Zatím žádné stavové stránky",
|
||||
"actionButton": "Vytvořte stavovou stránku!",
|
||||
"description": "Publikujte veřejnou stránku, která zákazníkům a zúčastněným stranám zobrazuje dostupnost v reálném čase a historii incidentů."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Heatmapa",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "Všechny systémy jsou nedostupné",
|
||||
"allUp": "Všechny systémy fungují",
|
||||
"degraded": "Některé systémy mají problémy",
|
||||
"unknown": "Nelze určit stav systému"
|
||||
"unknown": "Nelze určit stav systému",
|
||||
"allBreached": "Všechny systémy překročily prahové hodnoty",
|
||||
"allMaintenance": "Všechny systémy jsou v údržbě",
|
||||
"allPaused": "Všechny systémy jsou pozastavené",
|
||||
"allInitializing": "Všechny systémy se inicializují",
|
||||
"breachedAndDown": "Některé systémy překročily prahové hodnoty a jsou nedostupné",
|
||||
"breached": "Některé systémy překročily prahové hodnoty",
|
||||
"maintenanceAndDown": "Některé systémy jsou nedostupné během údržby",
|
||||
"maintenance": "Některé systémy jsou v údržbě",
|
||||
"partiallyPaused": "Některé systémy jsou pozastavené",
|
||||
"initializing": "Některé systémy se inicializují",
|
||||
"noMonitors": "Nebyly nakonfigurovány žádné monitory"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Stavové stránky",
|
||||
"description": "Publikujte veřejné stránky, které zákazníkům a zúčastněným stranám zobrazují dostupnost v reálném čase a historii incidentů."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Vytvořte monitor!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "Monitor dostupnosti slouží k:"
|
||||
"title": "Zatím žádné monitory dostupnosti",
|
||||
"description": "Sledujte HTTP koncové body, pingy, kontejnery a porty — buďte upozorněni v okamžiku, kdy něco vypadne."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitory dostupnosti",
|
||||
"description": "Sledujte HTTP koncové body, pingy, kontejnery a porty — buďte upozorněni v okamžiku, kdy něco vypadne."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+138
-16
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "Checkmate bewerten",
|
||||
"description": "Entdecken Sie die neuesten Versionen und helfen Sie der Community auf GitHub"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Support",
|
||||
"discussions": "Diskussionen",
|
||||
"docs": "Dokumentation",
|
||||
"changelog": "Änderungsverlauf"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "Rolle auswählen"
|
||||
},
|
||||
"linkLabel": "Einladungslink"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Noch keine Teammitglieder",
|
||||
"description": "Laden Sie Teammitglieder per E-Mail ein oder fügen Sie sie direkt hinzu. Sobald sie beitreten, erscheinen sie hier mit ihrer Rolle."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Konto",
|
||||
"description": "Verwalten Sie Profil, Passwort, Team und Workspace-Einstellungen."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Open-Source-Infrastruktur-Monitoring",
|
||||
"tagline": "Beobachten Sie jeden Zug Ihrer Server.",
|
||||
"description": "Echtzeit-Überwachung von Verfügbarkeit, Antwortzeiten und Vorfällen - selbst gehostet und in Ihrer Hand."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "Willkommen bei Checkmate!",
|
||||
"subtitle": "Registrieren Sie sich, um loszulegen",
|
||||
"submit": "Registrieren"
|
||||
"submit": "Registrieren",
|
||||
"setupNotice": "Diese Seite ist nur während der Ersteinrichtung verfügbar. Sobald ein Super-Admin registriert ist, können weitere Benutzer in den Team-Einstellungen eingeladen werden."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "Passwort vergessen?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "Statuscode",
|
||||
"location": "Standort"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Noch keine Prüfungen",
|
||||
"description": "Sobald Sie einen Monitor erstellen, erscheinen jede Statusprüfung und Antwortzeit hier als Prüfung."
|
||||
},
|
||||
"header": {
|
||||
"title": "Prüfungen",
|
||||
"description": "Jede Sondierung, die Checkmate gegen Ihre Monitore ausführt, erscheint hier mit Statuscode und Antwortzeit."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Aktiv seit",
|
||||
"certificateExpiry": "Zertifikatablauf",
|
||||
"lastCheck": "Letzter Check",
|
||||
"lastResponseTime": "Letzte Antwortzeit"
|
||||
"lastResponseTime": "Letzte Antwortzeit",
|
||||
"serviceIsDown": "Dienst ist nicht erreichbar"
|
||||
},
|
||||
"status": {
|
||||
"down": "ausgefallen",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Keine Vorfälle — alle Systeme funktionieren",
|
||||
"description": "Wenn ein Monitor ausfällt oder wiederhergestellt wird, erscheint der Vorfall hier mit Zeitangaben, Monitordetails und Lösungsverlauf."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Vorfall lösen",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Aktiv",
|
||||
"resolved": "Gelöst"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Vorfälle",
|
||||
"description": "Wenn ein Monitor ausfällt oder wiederhergestellt wird, erscheinen Vorfälle hier mit Zeitangaben, Monitordetails und Lösungsverlauf."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,11 +813,19 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Monitor erstellen!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "Ein Infrastruktur-Monitor wird verwendet, um:"
|
||||
"title": "Noch keine Infrastruktur-Monitore",
|
||||
"description": "Verfolgen Sie die Serverleistung, identifizieren Sie Engpässe und gewährleisten Sie Zuverlässigkeit mit Echtzeit-Infrastrukturüberwachung."
|
||||
},
|
||||
"header": {
|
||||
"title": "Infrastruktur-Monitore",
|
||||
"description": "Verfolgen Sie die Serverleistung, identifizieren Sie Engpässe und gewährleisten Sie Zuverlässigkeit mit Echtzeit-Infrastrukturüberwachung."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Noch keine Protokolle",
|
||||
"description": "Serveraktivitäten, Warnungen und Fehler werden hier angezeigt, während Checkmate läuft."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "Diagnose",
|
||||
"logs": "Server logs",
|
||||
@@ -788,7 +835,9 @@
|
||||
"label": "Log-Level"
|
||||
},
|
||||
"jobQueue": "Job-Warteschlange",
|
||||
"jobQueueExplainer": "<highlight>Hervorgehobene Zeilen</highlight> sind Jobs, die derzeit von einem Worker verarbeitet werden.",
|
||||
"failedJobs": "Fehlgeschlagene Jobs",
|
||||
"failedJobsExplainer": "Aktuelle Fehler nach Monitor — Zeit des letzten Fehlers, Fehleranzahl und Grund.",
|
||||
"noLogs": "Keine Protokolle gefunden",
|
||||
"metrics": {
|
||||
"jobs": "Jobs",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% von 1s durch CPU genutzt",
|
||||
"total": "Gesamt",
|
||||
"used": "Belegt"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Laufzeitstatistiken",
|
||||
"description": "Snapshot des Node.js-Prozesses und Host-Rechners. Wird alle 5 Sekunden aktualisiert."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Speicher & CPU",
|
||||
"description": "Wie der Prozess seinen zugewiesenen Speicher und die Host-CPU nutzt."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "Letzter Fehler am",
|
||||
"failReason": "Fehlergrund"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "Keine Aufträge in der Warteschlange",
|
||||
"description": "Geplante oder laufende Monitorprüfungen erscheinen hier. Eine leere Warteschlange bedeutet, dass alles aktuell ist."
|
||||
},
|
||||
"header": {
|
||||
"title": "Protokolle & Warteschlange",
|
||||
"description": "Serverprotokolle, Monitor-Warteschlange und Laufzeitdiagnosen an einem Ort."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Wartungsfenster erstellen!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "Ein Wartungsfenster wird verwendet, um:"
|
||||
"title": "Keine Wartungsfenster geplant",
|
||||
"description": "Planen Sie Wartungsausfälle, damit Warnungen unterdrückt werden und Team und Nutzer wissen, was sie erwartet."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Wartungsfenster",
|
||||
"description": "Planen Sie Wartungsausfälle, damit Warnungen unterdrückt werden und Team und Nutzer wissen, was sie erwartet."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Kanal erstellen",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "Benachrichtigungskanäle werden verwendet, um:"
|
||||
"title": "Noch keine Benachrichtigungskanäle",
|
||||
"description": "Verbinden Sie Slack, Discord, E-Mail, Webhooks und mehr, damit die richtigen Personen sofort von Vorfällen erfahren."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "Chat-ID",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Pushover-Konfiguration",
|
||||
"description": "Geben Sie Ihr Anwendungstoken und Ihren Benutzerschlüssel von Pushover ein.",
|
||||
"optionAppToken": "Anwendungstoken",
|
||||
"placeholderAppToken": "Anwendungstoken eingeben",
|
||||
"optionUserKey": "Benutzerschlüssel",
|
||||
"placeholderUserKey": "Benutzerschlüssel eingeben"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Twilio-Konfiguration",
|
||||
"description": "Geben Sie Ihre Twilio-Kontoanmeldeinformationen ein, um SMS zu senden.",
|
||||
"optionAccountSid": "Account-SID",
|
||||
"placeholderAccountSid": "Account-SID eingeben",
|
||||
"optionAuthToken": "Auth-Token",
|
||||
"placeholderAuthToken": "Auth-Token eingeben",
|
||||
"optionFromNumber": "Absendernummer",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Empfängernummer",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Ziel"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Benachrichtigungen",
|
||||
"description": "Verbinden Sie Slack, Discord, E-Mail, Webhooks und mehr, damit die richtigen Personen sofort von Vorfällen erfahren."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Monitor erstellen!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "Ein PageSpeed-Monitor wird verwendet, um:"
|
||||
"title": "Noch keine PageSpeed-Monitore",
|
||||
"description": "Verfolgen Sie Core Web Vitals und Lighthouse-Werte im Zeitverlauf, um Regressionen zu erkennen, bevor Nutzer es tun."
|
||||
},
|
||||
"header": {
|
||||
"title": "PageSpeed-Monitore",
|
||||
"description": "Verfolgen Sie Core Web Vitals und Lighthouse-Werte im Zeitverlauf, um Regressionen zu erkennen, bevor Nutzer es tun."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Bitte beheben Sie die folgenden Validierungsfehler:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Einstellungen",
|
||||
"description": "Konfigurieren Sie SMTP, Integrationen, Aufbewahrung und globales App-Verhalten."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Statusseite erfolgreich gelöscht",
|
||||
"fallback": {
|
||||
"title": "Eine Statusseite wird verwendet, um:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "Statusseite erstellen!"
|
||||
"title": "Noch keine Statusseiten",
|
||||
"actionButton": "Statusseite erstellen!",
|
||||
"description": "Veröffentlichen Sie eine öffentliche Seite, die Kunden und Stakeholdern Echtzeit-Verfügbarkeit und Vorfallsverlauf zeigt."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Heatmap",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "Alle Systeme sind ausgefallen",
|
||||
"allUp": "Alle Systeme funktionsfähig",
|
||||
"degraded": "Einige Systeme haben Probleme",
|
||||
"unknown": "Systemstatus kann nicht ermittelt werden"
|
||||
"unknown": "Systemstatus kann nicht ermittelt werden",
|
||||
"allBreached": "Alle Systeme haben Schwellenwerte überschritten",
|
||||
"allMaintenance": "Alle Systeme befinden sich in Wartung",
|
||||
"allPaused": "Alle Systeme sind pausiert",
|
||||
"allInitializing": "Alle Systeme werden initialisiert",
|
||||
"breachedAndDown": "Einige Systeme haben Schwellenwerte überschritten und sind ausgefallen",
|
||||
"breached": "Einige Systeme haben Schwellenwerte überschritten",
|
||||
"maintenanceAndDown": "Einige Systeme sind während der Wartung ausgefallen",
|
||||
"maintenance": "Einige Systeme befinden sich in Wartung",
|
||||
"partiallyPaused": "Einige Systeme sind pausiert",
|
||||
"initializing": "Einige Systeme werden initialisiert",
|
||||
"noMonitors": "Es wurden keine Monitore konfiguriert"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Statusseiten",
|
||||
"description": "Veröffentlichen Sie öffentliche Seiten, die Kunden und Stakeholdern Echtzeit-Verfügbarkeit und Vorfallsverlauf zeigen."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Monitor erstellen!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "Ein Verfügbarkeitsmonitor wird verwendet, um:"
|
||||
"title": "Noch keine Uptime-Monitore",
|
||||
"description": "Überwachen Sie HTTP-Endpunkte, Pings, Container und Ports und werden Sie sofort benachrichtigt, wenn etwas ausfällt."
|
||||
},
|
||||
"header": {
|
||||
"title": "Uptime-Monitore",
|
||||
"description": "Überwachen Sie HTTP-Endpunkte, Pings, Container und Ports und werden Sie sofort benachrichtigt, wenn etwas ausfällt."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+145
-49
@@ -105,7 +105,7 @@
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"empty": "Nothing here",
|
||||
"empty": "Nothing to show yet",
|
||||
"headers": {
|
||||
"actions": "Actions",
|
||||
"dateTime": "Date & time",
|
||||
@@ -123,6 +123,14 @@
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Support",
|
||||
"discussions": "Discussions",
|
||||
"docs": "Documentation",
|
||||
"changelog": "Changelog"
|
||||
}
|
||||
},
|
||||
"imageUpload": {
|
||||
"clickToUpload": "Click to upload",
|
||||
"dragAndDrop": "or drag and drop",
|
||||
@@ -249,6 +257,10 @@
|
||||
}
|
||||
},
|
||||
"team": {
|
||||
"fallback": {
|
||||
"title": "No team members yet",
|
||||
"description": "Invite teammates by email or add them directly. Once they join, they'll appear here with their role."
|
||||
},
|
||||
"filter": {
|
||||
"placeholder": "Filter by role",
|
||||
"all": "All roles",
|
||||
@@ -279,9 +291,18 @@
|
||||
},
|
||||
"linkLabel": "Invite link"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Account",
|
||||
"description": "Manage your profile, password, team, and workspace preferences."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Open-source infrastructure monitoring",
|
||||
"tagline": "Watch every move your servers make.",
|
||||
"description": "Real-time uptime, response time and incident tracking - self-hosted and yours to keep."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,6 +364,7 @@
|
||||
"register": {
|
||||
"title": "Welcome back to Checkmate!",
|
||||
"subtitle": "Sign up to get started",
|
||||
"setupNotice": "This page is only available during initial setup. Once a super admin is registered, additional users can be invited from team settings.",
|
||||
"submit": "Register"
|
||||
},
|
||||
"forgotPassword": {
|
||||
@@ -362,6 +384,10 @@
|
||||
}
|
||||
},
|
||||
"checks": {
|
||||
"fallback": {
|
||||
"title": "No checks yet",
|
||||
"description": "Once you create a monitor, every status probe and response time will appear here as a check."
|
||||
},
|
||||
"selects": {
|
||||
"monitor": {
|
||||
"all": "All monitors"
|
||||
@@ -378,6 +404,10 @@
|
||||
"statusCode": "Status code",
|
||||
"location": "Location"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Checks",
|
||||
"description": "Every probe Checkmate runs against your monitors lands here, with status code and response time."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Active for",
|
||||
"certificateExpiry": "Certificate expiry",
|
||||
"lastCheck": "Last check",
|
||||
"lastResponseTime": "Last response time"
|
||||
"lastResponseTime": "Last response time",
|
||||
"serviceIsDown": "Service is down"
|
||||
},
|
||||
"status": {
|
||||
"down": "down",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "No incidents — all systems healthy",
|
||||
"description": "When a monitor goes down or recovers, the incident will appear here with timing, monitor details, and resolution history."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Resolve incident",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Active",
|
||||
"resolved": "Resolved"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Incidents",
|
||||
"description": "When monitors go down or recover, incidents appear here with timing, monitor details and resolution history."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -773,16 +812,24 @@
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Create a monitor!",
|
||||
"checks": [
|
||||
"Track the performance of your servers",
|
||||
"Identify bottlenecks and optimize usage",
|
||||
"Ensure reliability with real-time monitoring"
|
||||
],
|
||||
"title": "An infrastructure monitor is used to:"
|
||||
"actionButton": "Create a monitor",
|
||||
"description": "Track server performance, identify bottlenecks, and ensure reliability with real-time infrastructure monitoring.",
|
||||
"title": "No infrastructure monitors yet"
|
||||
},
|
||||
"header": {
|
||||
"title": "Infrastructure monitors",
|
||||
"description": "Track server performance, identify bottlenecks, and ensure reliability with real-time infrastructure monitoring."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "No logs yet",
|
||||
"description": "Server activity, warnings, and errors will appear here as Checkmate runs."
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "No jobs in the queue",
|
||||
"description": "Monitor checks that are scheduled or running will appear here. An empty queue means everything is up to date."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "Diagnostics",
|
||||
"logs": "Logs",
|
||||
@@ -792,7 +839,9 @@
|
||||
"label": "Log level"
|
||||
},
|
||||
"jobQueue": "Job queue",
|
||||
"jobQueueExplainer": "<highlight>Highlighted rows</highlight> are jobs currently being processed by a worker.",
|
||||
"failedJobs": "Failed jobs",
|
||||
"failedJobsExplainer": "Recent failures by monitor — last failure time, fail count, and the reason.",
|
||||
"noLogs": "No logs found",
|
||||
"metrics": {
|
||||
"jobs": "Jobs",
|
||||
@@ -802,6 +851,16 @@
|
||||
"totalFailures": "Total failures"
|
||||
},
|
||||
"diagnostics": {
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Runtime stats",
|
||||
"description": "Snapshot of the Node.js process and host machine. Updates every 5 seconds."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Memory & CPU",
|
||||
"description": "How the process is using its allocated memory and host CPU."
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"eventLoopDelay": "Event loop delay",
|
||||
"uptime": "Uptime",
|
||||
@@ -810,7 +869,7 @@
|
||||
"osMemoryLimit": "OS memory limit"
|
||||
},
|
||||
"gauges": {
|
||||
"heapAllocation": "Heap allocaton",
|
||||
"heapAllocation": "Heap allocation",
|
||||
"heapUsage": "Heap usage",
|
||||
"heapUtilization": "Heap utilization",
|
||||
"instantCpuUsage": "Instant CPU usage",
|
||||
@@ -829,25 +888,25 @@
|
||||
"method": "Method",
|
||||
"monitorId": "Monitor ID",
|
||||
"runCount": "Run count",
|
||||
"failCount": "Fail count",
|
||||
"failCount": "Count",
|
||||
"lastRunAt": "Last run at",
|
||||
"lockedAt": "Locked at",
|
||||
"lastFinishedAt": "Last finished at",
|
||||
"lastRunTook": "Last run took",
|
||||
"lastFailedAt": "Last failed at",
|
||||
"lastFailedAt": "Last failed",
|
||||
"failReason": "Fail reason"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Logs & queue",
|
||||
"description": "Inspect server logs, the monitor job queue, and runtime diagnostics in one place."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Create a maintenance window!",
|
||||
"checks": [
|
||||
"Mark your maintenance periods",
|
||||
"Eliminate any misunderstandings",
|
||||
"Stop sending alerts in maintenance windows"
|
||||
],
|
||||
"title": "A maintenance window is used to:"
|
||||
"actionButton": "Create a maintenance window",
|
||||
"description": "Schedule planned downtime so alerts are suppressed and your team and users know what to expect.",
|
||||
"title": "No maintenance windows scheduled"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -899,17 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Maintenance windows",
|
||||
"description": "Schedule planned downtime so alerts are suppressed and your team and users know what to expect."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Create a channel",
|
||||
"checks": [
|
||||
"Alert teams about downtime or performance issues",
|
||||
"Let engineers know when incidents happen",
|
||||
"Keep administrators informed of system changes"
|
||||
],
|
||||
"title": "Notification channles are used to:"
|
||||
"description": "Connect Slack, Discord, email, webhooks and more so the right people hear about incidents the moment they happen.",
|
||||
"title": "No notification channels yet"
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -959,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "Chat ID",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Pushover configuration",
|
||||
"description": "Configure Pushover to receive push notifications on your devices.",
|
||||
"optionAppToken": "Application API token",
|
||||
"placeholderAppToken": "azGDORePK8gMaC0QOYAMyEEuzJnyUi",
|
||||
"optionUserKey": "User key",
|
||||
"placeholderUserKey": "uQiRzpo4DXghDmr9QzzfQu27cmVRsG"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Twilio SMS configuration",
|
||||
"description": "Configure Twilio to send SMS notifications to a phone number.",
|
||||
"optionAccountSid": "Account SID",
|
||||
"placeholderAccountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"optionAuthToken": "Auth token",
|
||||
"placeholderAuthToken": "your_auth_token",
|
||||
"optionFromNumber": "From number (Twilio)",
|
||||
"placeholderFromNumber": "+15551234567",
|
||||
"optionToNumber": "To number (recipient)",
|
||||
"placeholderToNumber": "+15559876543"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Destination"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Notifications",
|
||||
"description": "Connect Slack, Discord, email, webhooks and more so the right people hear about incidents the moment they happen."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -990,13 +1073,13 @@
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Create a monitor!",
|
||||
"checks": [
|
||||
"Report on the user experience of a page",
|
||||
"Help analyze webpage speed",
|
||||
"Give suggestions on how the page can be improved"
|
||||
],
|
||||
"title": "A PageSpeed monitor is used to:"
|
||||
"actionButton": "Create a monitor",
|
||||
"description": "Track Core Web Vitals and Lighthouse scores over time so you can spot regressions before users do.",
|
||||
"title": "No PageSpeed monitors yet"
|
||||
},
|
||||
"header": {
|
||||
"title": "PageSpeed monitors",
|
||||
"description": "Track Core Web Vitals and Lighthouse scores over time so you can spot regressions before users do."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1174,19 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Please fix the following validation errors:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Settings",
|
||||
"description": "Configure SMTP, integrations, retention, and global app behavior."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Status page deleted successfully",
|
||||
"fallback": {
|
||||
"title": "A status page is used to:",
|
||||
"checks": [
|
||||
"Communicate system status to users and stakeholders",
|
||||
"Display real-time uptime information publicly",
|
||||
"Build trust with transparent service monitoring",
|
||||
"Reduce support requests during incidents"
|
||||
],
|
||||
"actionButton": "Create a status page!"
|
||||
"title": "No status pages yet",
|
||||
"description": "Publish a public page that shows real-time uptime and incident history to your customers and stakeholders.",
|
||||
"actionButton": "Create a status page"
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Heatmap",
|
||||
@@ -1208,9 +1290,20 @@
|
||||
}
|
||||
},
|
||||
"statusBar": {
|
||||
"allDown": "All systems are down",
|
||||
"allUp": "All systems operational",
|
||||
"allBreached": "All systems have exceeded thresholds",
|
||||
"allMaintenance": "All systems are under maintenance",
|
||||
"allDown": "All systems are down",
|
||||
"allPaused": "All systems are paused",
|
||||
"allInitializing": "All systems are initializing",
|
||||
"breachedAndDown": "Some systems have exceeded thresholds and are down",
|
||||
"breached": "Some systems have exceeded thresholds",
|
||||
"degraded": "Some systems are experiencing issues",
|
||||
"maintenanceAndDown": "Some systems are down during maintenance",
|
||||
"maintenance": "Some systems are under maintenance",
|
||||
"partiallyPaused": "Some systems are paused",
|
||||
"initializing": "Some systems are initializing",
|
||||
"noMonitors": "No monitors have been configured",
|
||||
"unknown": "Unable to determine system status"
|
||||
},
|
||||
"table": {
|
||||
@@ -1303,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Status pages",
|
||||
"description": "Publish public pages that show real-time uptime and incident history to your customers and stakeholders."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1317,14 +1414,13 @@
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Create a monitor!",
|
||||
"checks": [
|
||||
"Check if websites or servers are online & responsive",
|
||||
"Alert teams about downtime or performance issues",
|
||||
"Monitor HTTP endpoints, pings, containers & ports",
|
||||
"Track historical uptime and reliability trends"
|
||||
],
|
||||
"title": "An uptime monitor is used to:"
|
||||
"actionButton": "Create a monitor",
|
||||
"description": "Watch HTTP endpoints, pings, containers, and ports — and get alerted the moment something goes down.",
|
||||
"title": "No uptime monitors yet"
|
||||
},
|
||||
"header": {
|
||||
"title": "Uptime monitors",
|
||||
"description": "Watch HTTP endpoints, pings, containers, and ports — and get alerted the moment something goes down."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+230
-94
@@ -13,7 +13,7 @@
|
||||
"content": "Advertencia: Aún no ha agregado una clave de API de Google PageSpeed. Visite <settingsLink>Configuración</settingsLink> para agregar una. Sin ella, el monitor de PageSpeed no funcionará."
|
||||
}
|
||||
},
|
||||
"appName": "",
|
||||
"appName": "Checkmate",
|
||||
"breadcrumbs": {
|
||||
"details": "Detalles",
|
||||
"home": "Inicio"
|
||||
@@ -35,11 +35,11 @@
|
||||
"sendInvite": "Enviar invitación",
|
||||
"test": "Probar",
|
||||
"testNotifications": "Probar notificaciones",
|
||||
"toggleTheme": "",
|
||||
"toggleTheme": "Cambiar tema claro / oscuro",
|
||||
"flushQueue": "Vaciar cola",
|
||||
"notFound": "Ir al panel principal",
|
||||
"resetPassword": "",
|
||||
"reset": "",
|
||||
"resetPassword": "Restablecer contraseña",
|
||||
"reset": "Restablecer",
|
||||
"clear": "Limpiar",
|
||||
"addDemo": "Agregar monitores de demostración",
|
||||
"removeMonitors": "Eliminar monitores",
|
||||
@@ -47,7 +47,14 @@
|
||||
"exportToJSON": "Exportar a JSON",
|
||||
"importFromJSON": "Importar desde JSON",
|
||||
"clearFilters": "Limpiar filtros",
|
||||
"removeUser": "Eliminar usuario"
|
||||
"removeUser": "Eliminar usuario",
|
||||
"testNotification": "Probar notificación",
|
||||
"invite": "Invitar",
|
||||
"copyLink": "Copiar enlace",
|
||||
"regenerateToken": "Regenerar token",
|
||||
"copyToken": "Copiar token",
|
||||
"exportLogs": "Exportar registros",
|
||||
"refresh": "Actualizar"
|
||||
},
|
||||
"charts": {
|
||||
"labels": {
|
||||
@@ -86,12 +93,12 @@
|
||||
"name": {
|
||||
"option": {
|
||||
"firstName": {
|
||||
"label": "",
|
||||
"placeholder": ""
|
||||
"label": "Nombre",
|
||||
"placeholder": "Introduce tu nombre"
|
||||
},
|
||||
"lastName": {
|
||||
"label": "",
|
||||
"placeholder": ""
|
||||
"label": "Apellidos",
|
||||
"placeholder": "Introduce tus apellidos"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -99,7 +106,7 @@
|
||||
"option": {
|
||||
"email": {
|
||||
"label": "Correo electrónico",
|
||||
"placeholder": "you@example.com"
|
||||
"placeholder": "tu@ejemplo.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,14 +114,14 @@
|
||||
"table": {
|
||||
"empty": "No hay nada aquí",
|
||||
"headers": {
|
||||
"actions": "",
|
||||
"actions": "Acciones",
|
||||
"dateTime": "Fecha y hora",
|
||||
"message": "Mensaje",
|
||||
"monitor": "Monitor",
|
||||
"monitorId": "ID de monitor",
|
||||
"name": "Nombre",
|
||||
"status": "Estado",
|
||||
"type": "",
|
||||
"type": "Tipo",
|
||||
"url": "URL",
|
||||
"interval": "Intervalo",
|
||||
"active": "Activo",
|
||||
@@ -125,17 +132,17 @@
|
||||
"components": {
|
||||
"imageUpload": {
|
||||
"clickToUpload": "Haga clic para subir",
|
||||
"dragAndDrop": "",
|
||||
"supportedFormats": "",
|
||||
"maxSize": "",
|
||||
"dragAndDrop": "o arrastra y suelta",
|
||||
"supportedFormats": "Formatos admitidos",
|
||||
"maxSize": "Tamaño máximo",
|
||||
"orDragAndDrop": "o arrastre y suelte",
|
||||
"errors": {
|
||||
"invalidFileSize": "",
|
||||
"invalidFileFormat": ""
|
||||
"invalidFileSize": "¡El archivo es demasiado grande!",
|
||||
"invalidFileFormat": "¡Formato de archivo no admitido!"
|
||||
}
|
||||
},
|
||||
"headerStatusPageControls": {
|
||||
"publicLink": ""
|
||||
"publicLink": "Enlace público"
|
||||
},
|
||||
"headerTimeRange": {
|
||||
"labels": {
|
||||
@@ -155,26 +162,26 @@
|
||||
"serverUnreachable": "No se puede conectar al servidor",
|
||||
"retry": "Reintentar",
|
||||
"retrying": "Reintentando...",
|
||||
"reconnected": ""
|
||||
"reconnected": "Conexión restablecida"
|
||||
},
|
||||
"sidebar": {
|
||||
"menu": {
|
||||
"uptime": "",
|
||||
"pagespeed": "",
|
||||
"infrastructure": "",
|
||||
"notifications": "",
|
||||
"uptime": "Disponibilidad",
|
||||
"pagespeed": "Pagespeed",
|
||||
"infrastructure": "Infraestructura",
|
||||
"notifications": "Notificaciones",
|
||||
"checks": "Verificaciones",
|
||||
"incidents": "",
|
||||
"statusPages": "",
|
||||
"maintenance": "",
|
||||
"logs": "",
|
||||
"settings": ""
|
||||
"incidents": "Incidentes",
|
||||
"statusPages": "Páginas de estado",
|
||||
"maintenance": "Mantenimiento",
|
||||
"logs": "Registros",
|
||||
"settings": "Configuración"
|
||||
},
|
||||
"bottomMenu": {
|
||||
"support": "",
|
||||
"discussions": "",
|
||||
"docs": "",
|
||||
"changelog": ""
|
||||
"support": "Soporte",
|
||||
"discussions": "Discusiones",
|
||||
"docs": "Documentación",
|
||||
"changelog": "Registro de cambios"
|
||||
},
|
||||
"accountMenu": {
|
||||
"profile": "Perfil",
|
||||
@@ -186,19 +193,27 @@
|
||||
"description": "Vea las últimas versiones y ayude a crecer la comunidad en GitHub"
|
||||
},
|
||||
"authFooter": {
|
||||
"navControls": "",
|
||||
"logOut": "",
|
||||
"navControls": "Controles",
|
||||
"logOut": "Cerrar sesión",
|
||||
"roles": {
|
||||
"superAdmin": "Superadministrador",
|
||||
"admin": "Administrador",
|
||||
"user": "Usuario",
|
||||
"demoUser": ""
|
||||
"demoUser": "Usuario demo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"starPrompt": {
|
||||
"title": "Dale estrella a Checkmate",
|
||||
"description": "Vea las últimas versiones y ayude a crecer la comunidad en GitHub"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Soporte",
|
||||
"discussions": "Discusiones",
|
||||
"docs": "Documentación",
|
||||
"changelog": "Registro de cambios"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -251,15 +266,15 @@
|
||||
"team": {
|
||||
"filter": {
|
||||
"placeholder": "Filtrar por rol",
|
||||
"all": "",
|
||||
"all": "Todos los roles",
|
||||
"admin": "Administrador",
|
||||
"member": ""
|
||||
"member": "Miembro"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"email": "Correo electrónico",
|
||||
"role": "Rol",
|
||||
"created": ""
|
||||
"created": "Creado el"
|
||||
}
|
||||
},
|
||||
"addMember": {
|
||||
@@ -278,42 +293,55 @@
|
||||
"placeholder": "Seleccione un rol"
|
||||
},
|
||||
"linkLabel": "Enlace de invitación"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Aún no hay miembros del equipo",
|
||||
"description": "Invita a tus compañeros por correo o añádelos directamente. Una vez que se unan, aparecerán aquí con su rol."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Cuenta",
|
||||
"description": "Administra tu perfil, contraseña, equipo y preferencias del espacio de trabajo."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Monitorización de infraestructura de código abierto",
|
||||
"tagline": "Vigila cada movimiento de tus servidores.",
|
||||
"description": "Monitorización en tiempo real de disponibilidad, tiempo de respuesta e incidentes - autoalojada y tuya."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
"beginning": "",
|
||||
"highlighted": ""
|
||||
"beginning": "Debe tener al menos",
|
||||
"highlighted": "8 caracteres"
|
||||
},
|
||||
"lowercase": {
|
||||
"beginning": "",
|
||||
"highlighted": ""
|
||||
"beginning": "Debe contener al menos",
|
||||
"highlighted": "una letra minúscula"
|
||||
},
|
||||
"match": {
|
||||
"beginning": "",
|
||||
"highlighted": ""
|
||||
"beginning": "Las contraseñas",
|
||||
"highlighted": "deben coincidir"
|
||||
},
|
||||
"number": {
|
||||
"beginning": "",
|
||||
"highlighted": ""
|
||||
"beginning": "Debe contener al menos",
|
||||
"highlighted": "un número"
|
||||
},
|
||||
"special": {
|
||||
"beginning": "",
|
||||
"highlighted": ""
|
||||
"beginning": "Debe contener al menos",
|
||||
"highlighted": "un carácter especial (!?@#$%^&*()-_=+[]{}|;:'\",./\\~`)"
|
||||
},
|
||||
"uppercase": {
|
||||
"beginning": "",
|
||||
"highlighted": ""
|
||||
"beginning": "Debe contener al menos",
|
||||
"highlighted": "una letra mayúscula"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"option": {
|
||||
"email": {
|
||||
"label": "Correo electrónico",
|
||||
"placeholder": "me@example.com"
|
||||
"placeholder": "yo@ejemplo.com"
|
||||
},
|
||||
"password": {
|
||||
"label": "Contraseña",
|
||||
@@ -343,7 +371,8 @@
|
||||
"register": {
|
||||
"title": "¡Bienvenido de nuevo a Checkmate!",
|
||||
"subtitle": "Regístrese para comenzar",
|
||||
"submit": "Registrarse"
|
||||
"submit": "Registrarse",
|
||||
"setupNotice": "Esta página solo está disponible durante la configuración inicial. Una vez que se haya registrado un super administrador, se podrá invitar a usuarios adicionales desde la configuración del equipo."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "¿Olvidó su contraseña?",
|
||||
@@ -378,6 +407,14 @@
|
||||
"statusCode": "Código de estado",
|
||||
"location": "Ubicación"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Aún no hay comprobaciones",
|
||||
"description": "Una vez que crees un monitor, cada sonda de estado y tiempo de respuesta aparecerá aquí como una comprobación."
|
||||
},
|
||||
"header": {
|
||||
"title": "Comprobaciones",
|
||||
"description": "Cada sonda que Checkmate ejecuta contra tus monitores aparece aquí con código de estado y tiempo de respuesta."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +434,8 @@
|
||||
"activeFor": "Activo desde hace",
|
||||
"certificateExpiry": "Vencimiento del certificado",
|
||||
"lastCheck": "Última verificación",
|
||||
"lastResponseTime": "Último tiempo de respuesta"
|
||||
"lastResponseTime": "Último tiempo de respuesta",
|
||||
"serviceIsDown": "El servicio está caído"
|
||||
},
|
||||
"status": {
|
||||
"down": "caído",
|
||||
@@ -438,9 +476,9 @@
|
||||
},
|
||||
"matchMethod": {
|
||||
"label": "Método de coincidencia",
|
||||
"equal": "",
|
||||
"include": "",
|
||||
"regex": ""
|
||||
"equal": "Igual",
|
||||
"include": "Contiene",
|
||||
"regex": "Regex"
|
||||
}
|
||||
},
|
||||
"title": "Configuración avanzada"
|
||||
@@ -452,15 +490,15 @@
|
||||
"label": "Frecuencia de verificación",
|
||||
"value": {
|
||||
"fifteenMinutes": "15 minutos",
|
||||
"fifteenSeconds": "",
|
||||
"fifteenSeconds": "15 segundos",
|
||||
"fiveMinutes": "5 minutos",
|
||||
"fourMinutes": "",
|
||||
"oneMinute": "",
|
||||
"fourMinutes": "4 minutos",
|
||||
"oneMinute": "1 minuto",
|
||||
"tenMinutes": "10 minutos",
|
||||
"thirtyMinutes": "30 minutos",
|
||||
"thirtySeconds": "",
|
||||
"threeMinutes": "",
|
||||
"twoMinutes": ""
|
||||
"thirtySeconds": "30 segundos",
|
||||
"threeMinutes": "3 minutos",
|
||||
"twoMinutes": "2 minutos"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -489,8 +527,8 @@
|
||||
"placeholder": "https://www.google.com"
|
||||
},
|
||||
"game": {
|
||||
"label": "",
|
||||
"placeholder": ""
|
||||
"label": "Elige el juego",
|
||||
"placeholder": "Selecciona un juego"
|
||||
},
|
||||
"port": {
|
||||
"label": "Puerto a monitorear",
|
||||
@@ -508,10 +546,10 @@
|
||||
"title": "Configuración general",
|
||||
"description": {
|
||||
"http": "Ingrese la URL o IP a monitorear (p. ej., https://example.com/ o 192.168.1.100) y agregue un nombre para mostrar que aparecerá en el panel.",
|
||||
"ping": "",
|
||||
"port": "",
|
||||
"docker": "",
|
||||
"game": "",
|
||||
"ping": "Introduce la dirección IP o el nombre de host para hacer ping (p. ej., 192.168.1.100 o ejemplo.com) y un nombre descriptivo que aparecerá en el panel.",
|
||||
"port": "Introduce la URL o IP del servidor, el número de puerto y un nombre descriptivo que aparecerá en el panel.",
|
||||
"docker": "Introduce el nombre o ID del contenedor de Docker. Puedes usar el nombre del contenedor (p. ej., my-app) o su ID.",
|
||||
"game": "Introduce la dirección IP o el nombre de host y el número de puerto para hacer ping (p. ej., 192.168.1.100 o ejemplo.com) y un nombre descriptivo que aparecerá en el panel.",
|
||||
"pagespeed": "Rastree el rendimiento de carga de página, Core Web Vitals y puntuaciones de optimización de su sitio web.",
|
||||
"grpc": "Ingrese el nombre de host y puerto del servidor gRPC, opcionalmente especifique un nombre de servicio para la verificación de salud, y agregue un nombre para mostrar.",
|
||||
"websocket": "Ingrese la URL de WebSocket a monitorear (p. ej., wss://example.com/socket) y agregue un nombre para mostrar.",
|
||||
@@ -640,6 +678,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Sin incidentes — todos los sistemas saludables",
|
||||
"description": "Cuando un monitor falla o se recupera, el incidente aparecerá aquí con los tiempos, los detalles del monitor y el historial de resolución."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Resolver incidente",
|
||||
@@ -712,7 +754,7 @@
|
||||
"headers": {
|
||||
"endTime": "Hora de fin",
|
||||
"resolutionType": "Tipo de resolución",
|
||||
"startTime": "",
|
||||
"startTime": "Hora de inicio",
|
||||
"statusCode": "Código de estado"
|
||||
},
|
||||
"resolvedIncidents": "Incidentes resueltos",
|
||||
@@ -720,6 +762,10 @@
|
||||
"active": "Activo",
|
||||
"resolved": "Resuelto"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Incidentes",
|
||||
"description": "Cuando un monitor falla o se recupera, los incidentes aparecen aquí con los tiempos, los detalles del monitor y el historial de resolución."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -751,10 +797,10 @@
|
||||
}
|
||||
},
|
||||
"statBoxes": {
|
||||
"avgCpuTemperature": "",
|
||||
"cpuFrequency": "",
|
||||
"cpuLogical": "",
|
||||
"cpuPhysical": "",
|
||||
"avgCpuTemperature": "Temperatura media de la CPU",
|
||||
"cpuFrequency": "Frecuencia de la CPU",
|
||||
"cpuLogical": "CPU (lógicas)",
|
||||
"cpuPhysical": "CPU (físicas)",
|
||||
"disk": "Disco",
|
||||
"memory": "Memoria",
|
||||
"os": "SO"
|
||||
@@ -768,27 +814,37 @@
|
||||
},
|
||||
"tabs": {
|
||||
"labels": {
|
||||
"network": "",
|
||||
"network": "Red",
|
||||
"overview": "Resumen"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "¡Cree un monitor!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "Un monitor de infraestructura se usa para:"
|
||||
"title": "Aún no hay monitores de infraestructura",
|
||||
"description": "Rastrea el rendimiento de los servidores, identifica cuellos de botella y garantiza la fiabilidad con monitoreo en tiempo real."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitores de infraestructura",
|
||||
"description": "Rastrea el rendimiento de los servidores, identifica cuellos de botella y garantiza la fiabilidad con monitoreo en tiempo real."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Aún no hay registros",
|
||||
"description": "La actividad del servidor, advertencias y errores aparecerán aquí mientras Checkmate se ejecuta."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "",
|
||||
"logs": "",
|
||||
"queue": ""
|
||||
"diagnostics": "Diagnóstico",
|
||||
"logs": "Registros",
|
||||
"queue": "Cola de trabajos"
|
||||
},
|
||||
"logLevelSelect": {
|
||||
"label": "Nivel de registro"
|
||||
},
|
||||
"jobQueue": "Cola de trabajos",
|
||||
"jobQueueExplainer": "<highlight>Las filas resaltadas</highlight> son los trabajos que un worker está procesando actualmente.",
|
||||
"failedJobs": "Trabajos fallidos",
|
||||
"failedJobsExplainer": "Fallos recientes por monitor — hora del último fallo, número de fallos y motivo.",
|
||||
"noLogs": "No se encontraron registros",
|
||||
"metrics": {
|
||||
"jobs": "Trabajos",
|
||||
@@ -815,6 +871,16 @@
|
||||
"usedSPercentage": "% de 1s usado por CPU",
|
||||
"total": "Total",
|
||||
"used": "Usado"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Estadísticas de tiempo de ejecución",
|
||||
"description": "Instantánea del proceso Node.js y la máquina anfitriona. Se actualiza cada 5 segundos."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Memoria y CPU",
|
||||
"description": "Cómo el proceso utiliza la memoria asignada y la CPU del host."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,18 +899,26 @@
|
||||
"lastFailedAt": "Última falla",
|
||||
"failReason": "Razón de falla"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "No hay trabajos en la cola",
|
||||
"description": "Las comprobaciones de monitores programadas o en ejecución aparecerán aquí. Una cola vacía significa que todo está al día."
|
||||
},
|
||||
"header": {
|
||||
"title": "Registros y cola",
|
||||
"description": "Inspecciona registros del servidor, la cola de trabajos del monitor y los diagnósticos de runtime en un solo lugar."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "¡Cree una ventana de mantenimiento!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "Una ventana de mantenimiento se usa para:"
|
||||
"title": "No hay ventanas de mantenimiento programadas",
|
||||
"description": "Programa interrupciones planificadas para silenciar las alertas y que tu equipo y usuarios sepan qué esperar."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"nextWindow": "",
|
||||
"repeat": ""
|
||||
"nextWindow": "Próxima ventana",
|
||||
"repeat": "Repetición"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
@@ -891,13 +965,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Ventanas de mantenimiento",
|
||||
"description": "Programa interrupciones planificadas para silenciar las alertas y que tu equipo y usuarios sepan qué esperar."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Crear un canal",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "Los canales de notificación se usan para:"
|
||||
"title": "Aún no hay canales de notificación",
|
||||
"description": "Conecta Slack, Discord, correo electrónico, webhooks y más para que las personas adecuadas se enteren de los incidentes en cuanto ocurran."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1025,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "ID de chat",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Configuración de Pushover",
|
||||
"description": "Introduce tu token de aplicación y la clave de usuario de Pushover.",
|
||||
"optionAppToken": "Token de aplicación",
|
||||
"placeholderAppToken": "Introduce el token de aplicación",
|
||||
"optionUserKey": "Clave de usuario",
|
||||
"placeholderUserKey": "Introduce la clave de usuario"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Configuración de Twilio",
|
||||
"description": "Introduce las credenciales de tu cuenta de Twilio para enviar SMS.",
|
||||
"optionAccountSid": "SID de la cuenta",
|
||||
"placeholderAccountSid": "Introduce el SID de la cuenta",
|
||||
"optionAuthToken": "Token de autenticación",
|
||||
"placeholderAuthToken": "Introduce el token de autenticación",
|
||||
"optionFromNumber": "Número de origen",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Número de destino",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Destino"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Notificaciones",
|
||||
"description": "Conecta Slack, Discord, correo electrónico, webhooks y más para que las personas adecuadas se enteren de los incidentes en cuanto ocurran."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1081,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "¡Cree un monitor!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "Un monitor de PageSpeed se usa para:"
|
||||
"title": "Aún no hay monitores de PageSpeed",
|
||||
"description": "Sigue las Core Web Vitals y las puntuaciones de Lighthouse a lo largo del tiempo para detectar regresiones antes que tus usuarios."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitores de PageSpeed",
|
||||
"description": "Sigue las Core Web Vitals y las puntuaciones de Lighthouse a lo largo del tiempo para detectar regresiones antes que tus usuarios."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1083,7 +1189,7 @@
|
||||
"email": {
|
||||
"title": "Configuración de correo electrónico",
|
||||
"description": "Configure los ajustes de correo electrónico de su sistema. Se usa para enviar notificaciones y alertas.",
|
||||
"descriptionTransport": "",
|
||||
"descriptionTransport": "Esto crea un transporte SMTP para NodeMailer",
|
||||
"descriptionTransportLink": "Ver especificaciones aquí",
|
||||
"option": {
|
||||
"host": {
|
||||
@@ -1158,14 +1264,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Corrija los siguientes errores de validación:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Configuración",
|
||||
"description": "Configura SMTP, integraciones, retención y comportamiento global de la app."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Página de estado eliminada exitosamente",
|
||||
"fallback": {
|
||||
"title": "Una página de estado se usa para:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "¡Cree una página de estado!"
|
||||
"title": "Aún no hay páginas de estado",
|
||||
"actionButton": "¡Cree una página de estado!",
|
||||
"description": "Publica una página pública que muestre a tus clientes y partes interesadas la disponibilidad en tiempo real y el historial de incidentes."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Mapa de calor",
|
||||
@@ -1190,7 +1300,18 @@
|
||||
"allDown": "Todos los sistemas están caídos",
|
||||
"allUp": "Todos los sistemas operativos",
|
||||
"degraded": "Algunos sistemas están experimentando problemas",
|
||||
"unknown": "No se puede determinar el estado del sistema"
|
||||
"unknown": "No se puede determinar el estado del sistema",
|
||||
"allBreached": "Todos los sistemas han superado los umbrales",
|
||||
"allMaintenance": "Todos los sistemas están en mantenimiento",
|
||||
"allPaused": "Todos los sistemas están en pausa",
|
||||
"allInitializing": "Todos los sistemas se están inicializando",
|
||||
"breachedAndDown": "Algunos sistemas han superado los umbrales y están caídos",
|
||||
"breached": "Algunos sistemas han superado los umbrales",
|
||||
"maintenanceAndDown": "Algunos sistemas están caídos durante el mantenimiento",
|
||||
"maintenance": "Algunos sistemas están en mantenimiento",
|
||||
"partiallyPaused": "Algunos sistemas están en pausa",
|
||||
"initializing": "Algunos sistemas se están inicializando",
|
||||
"noMonitors": "No se ha configurado ningún monitor"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1403,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Páginas de estado",
|
||||
"description": "Publica páginas públicas que muestren a tus clientes y partes interesadas la disponibilidad en tiempo real y el historial de incidentes."
|
||||
},
|
||||
"publicPage": {
|
||||
"maintenance": {
|
||||
"upcoming": "Mantenimiento programado",
|
||||
"inProgress": "Mantenimiento en curso",
|
||||
"completed": "Mantenimiento completado"
|
||||
}
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1429,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "¡Cree un monitor!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "Un monitor de tiempo de actividad se usa para:"
|
||||
"title": "Aún no hay monitores de uptime",
|
||||
"description": "Observa endpoints HTTP, pings, contenedores y puertos — recibe alertas en el momento en que algo falla."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitores de uptime",
|
||||
"description": "Observa endpoints HTTP, pings, contenedores y puertos — recibe alertas en el momento en que algo falla."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+159
-37
@@ -13,7 +13,7 @@
|
||||
"content": "Varoitus: Et ole vielä lisännyt Google PageSpeed API -avainta. Siirry <settingsLink>Asetuksiin</settingsLink> lisätäksesi sellainen. Ilman sitä PageSpeed-monitorointi ei toimi."
|
||||
}
|
||||
},
|
||||
"appName": "",
|
||||
"appName": "Checkmate",
|
||||
"breadcrumbs": {
|
||||
"details": "Tiedot",
|
||||
"home": "Etusivu"
|
||||
@@ -35,10 +35,10 @@
|
||||
"sendInvite": "Lähetä kutsu",
|
||||
"test": "Testaa",
|
||||
"testNotifications": "Testaa ilmoitukset",
|
||||
"toggleTheme": "",
|
||||
"toggleTheme": "Vaihda vaalea / tumma",
|
||||
"flushQueue": "Tyhjennä jono",
|
||||
"notFound": "Siirry pääsivulle",
|
||||
"resetPassword": "",
|
||||
"resetPassword": "Nollaa salasana",
|
||||
"reset": "Palauta",
|
||||
"clear": "Tyhjennä",
|
||||
"addDemo": "Lisää demomonitorit",
|
||||
@@ -53,8 +53,8 @@
|
||||
"labels": {
|
||||
"averageResponseTime": "Keskimääräinen vasteaika",
|
||||
"downtime": "Käyttökatko",
|
||||
"high": "",
|
||||
"low": "",
|
||||
"high": "Korkea",
|
||||
"low": "Matala",
|
||||
"uptime": "Käytettävyys"
|
||||
},
|
||||
"histogram": {
|
||||
@@ -86,12 +86,12 @@
|
||||
"name": {
|
||||
"option": {
|
||||
"firstName": {
|
||||
"label": "",
|
||||
"placeholder": ""
|
||||
"label": "Etunimi",
|
||||
"placeholder": "Anna etunimesi"
|
||||
},
|
||||
"lastName": {
|
||||
"label": "",
|
||||
"placeholder": ""
|
||||
"label": "Sukunimi",
|
||||
"placeholder": "Anna sukunimesi"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -107,14 +107,14 @@
|
||||
"table": {
|
||||
"empty": "Täällä ei ole mitään",
|
||||
"headers": {
|
||||
"actions": "",
|
||||
"actions": "Toiminnot",
|
||||
"dateTime": "Päivämäärä ja aika",
|
||||
"message": "Viesti",
|
||||
"monitor": "Monitori",
|
||||
"monitorId": "Monitorin tunnus",
|
||||
"name": "Nimi",
|
||||
"status": "Tila",
|
||||
"type": "",
|
||||
"type": "Tyyppi",
|
||||
"url": "Osoite",
|
||||
"interval": "Aikaväli",
|
||||
"active": "Aktiivinen",
|
||||
@@ -131,7 +131,7 @@
|
||||
"orDragAndDrop": "tai vedä ja pudota",
|
||||
"errors": {
|
||||
"invalidFileSize": "Tiedoston koko on liian suuri!",
|
||||
"invalidFileFormat": ""
|
||||
"invalidFileFormat": "Tiedostomuotoa ei tueta!"
|
||||
}
|
||||
},
|
||||
"headerStatusPageControls": {
|
||||
@@ -155,19 +155,19 @@
|
||||
"serverUnreachable": "Palvelimeen ei saada yhteyttä",
|
||||
"retry": "Yritä uudelleen",
|
||||
"retrying": "Yritetään uudelleen...",
|
||||
"reconnected": ""
|
||||
"reconnected": "Yhteys palautettu"
|
||||
},
|
||||
"sidebar": {
|
||||
"menu": {
|
||||
"uptime": "",
|
||||
"pagespeed": "",
|
||||
"uptime": "Käytettävyys",
|
||||
"pagespeed": "Pagespeed",
|
||||
"infrastructure": "Infrastruktuuri",
|
||||
"notifications": "",
|
||||
"notifications": "Ilmoitukset",
|
||||
"checks": "Tarkistukset",
|
||||
"incidents": "",
|
||||
"incidents": "Häiriöt",
|
||||
"statusPages": "Tilasivut",
|
||||
"maintenance": "Huolto",
|
||||
"logs": "",
|
||||
"logs": "Lokit",
|
||||
"settings": "Asetukset"
|
||||
},
|
||||
"bottomMenu": {
|
||||
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "Lisää Checkmate suosikkeihin",
|
||||
"description": "Katso uusimmat julkaisut ja auta kasvattamaan yhteisöä GitHubissa"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Tuki",
|
||||
"discussions": "Keskustelut",
|
||||
"docs": "Dokumentaatio",
|
||||
"changelog": "Muutosloki"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "Valitse rooli"
|
||||
},
|
||||
"linkLabel": "Kutsulinkki"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Ei vielä tiimin jäseniä",
|
||||
"description": "Kutsu tiimin jäsenet sähköpostitse tai lisää heidät suoraan. Kun he liittyvät, he näkyvät tässä roolinsa kanssa."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Tili",
|
||||
"description": "Hallitse profiilia, salasanaa, tiimiä ja työtilan asetuksia."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Avoimen lähdekoodin infrastruktuurin valvonta",
|
||||
"tagline": "Seuraa palvelimiesi jokaista liikettä.",
|
||||
"description": "Reaaliaikainen käytettävyyden, vasteajan ja häiriöiden valvonta - itse isännöity ja sinun."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "Tervetuloa takaisin Checkmateen!",
|
||||
"subtitle": "Rekisteröidy aloittaaksesi",
|
||||
"submit": "Rekisteröidy"
|
||||
"submit": "Rekisteröidy",
|
||||
"setupNotice": "Tämä sivu on käytettävissä vain alkuasennuksen aikana. Kun super-admin on rekisteröity, lisäkäyttäjiä voi kutsua tiimiasetuksista."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "Unohditko salasanasi?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "Tilakoodi",
|
||||
"location": "Sijainti"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Ei vielä tarkistuksia",
|
||||
"description": "Kun luot monitorin, jokainen tilatarkistus ja vasteaika näkyy täällä tarkistuksena."
|
||||
},
|
||||
"header": {
|
||||
"title": "Tarkistukset",
|
||||
"description": "Jokainen tarkistus, jonka Checkmate suorittaa monitoreitasi vastaan, näkyy täällä tilakoodin ja vasteajan kanssa."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Aktiivinen",
|
||||
"certificateExpiry": "Varmenteen vanheneminen",
|
||||
"lastCheck": "Viimeisin tarkistus",
|
||||
"lastResponseTime": "Viimeisin vasteaika"
|
||||
"lastResponseTime": "Viimeisin vasteaika",
|
||||
"serviceIsDown": "Palvelu ei ole käytettävissä"
|
||||
},
|
||||
"status": {
|
||||
"down": "alhaalla",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Ei tapauksia — kaikki järjestelmät ovat kunnossa",
|
||||
"description": "Kun monitori kaatuu tai palautuu, tapaus tulee näkyviin ajoituksen, monitorin tietojen ja ratkaisuhistorian kanssa."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Ratkaise häiriö",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Aktiivinen",
|
||||
"resolved": "Ratkaistu"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Tapaukset",
|
||||
"description": "Kun monitori kaatuu tai palautuu, tapaukset näkyvät täällä ajoituksen, monitorin tietojen ja ratkaisuhistorian kanssa."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,21 +813,31 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Luo monitori!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "Infrastruktuurimonitorilla voit:"
|
||||
"title": "Ei vielä infrastruktuurimonitoreita",
|
||||
"description": "Seuraa palvelinten suorituskykyä, tunnista pullonkauloja ja varmista luotettavuus reaaliaikaisella valvonnalla."
|
||||
},
|
||||
"header": {
|
||||
"title": "Infrastruktuurimonitorit",
|
||||
"description": "Seuraa palvelinten suorituskykyä, tunnista pullonkauloja ja varmista luotettavuus reaaliaikaisella valvonnalla."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Ei vielä lokeja",
|
||||
"description": "Palvelimen toiminta, varoitukset ja virheet näkyvät täällä Checkmaten toimiessa."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "",
|
||||
"logs": "",
|
||||
"queue": ""
|
||||
"diagnostics": "Diagnostiikka",
|
||||
"logs": "Lokit",
|
||||
"queue": "Työjono"
|
||||
},
|
||||
"logLevelSelect": {
|
||||
"label": "Lokitaso"
|
||||
},
|
||||
"jobQueue": "Työnojono",
|
||||
"jobQueueExplainer": "<highlight>Korostetut rivit</highlight> ovat työt, joita työntekijä käsittelee parhaillaan.",
|
||||
"failedJobs": "Epäonnistuneet työt",
|
||||
"failedJobsExplainer": "Viimeisimmät epäonnistumiset valvojan mukaan — viimeisin epäonnistumisaika, epäonnistumismäärä ja syy.",
|
||||
"noLogs": "Lokeja ei löytynyt",
|
||||
"metrics": {
|
||||
"jobs": "Työt",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% sekunnista CPU:n käytössä",
|
||||
"total": "Yhteensä",
|
||||
"used": "Käytetty"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Suoritusajan tilastot",
|
||||
"description": "Node.js-prosessin ja isäntäkoneen tilannekuva. Päivittyy 5 sekunnin välein."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Muisti ja CPU",
|
||||
"description": "Miten prosessi käyttää sille varattua muistia ja isännän CPU:ta."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "Viimeisin epäonnistuminen",
|
||||
"failReason": "Epäonnistumisen syy"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "Jonossa ei ole töitä",
|
||||
"description": "Aikataulutetut tai käynnissä olevat monitoritarkistukset näkyvät täällä. Tyhjä jono tarkoittaa, että kaikki on ajan tasalla."
|
||||
},
|
||||
"header": {
|
||||
"title": "Lokit ja jono",
|
||||
"description": "Tarkasta palvelinlokit, monitorin työjono ja ajonaikaiset diagnostiikat yhdestä paikasta."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Luo huoltoikkuna!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "Huoltoikkunalla voit:"
|
||||
"title": "Ei suunniteltuja huoltokatkoja",
|
||||
"description": "Aikatauluta suunnitellut katkot, jotta hälytykset vaimennetaan ja tiimisi sekä käyttäjät tietävät mitä odottaa."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Huoltoikkunat",
|
||||
"description": "Aikatauluta suunnitellut katkot, jotta hälytykset vaimennetaan ja tiimisi sekä käyttäjät tietävät mitä odottaa."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Luo kanava",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "Ilmoituskanavia käytetään:"
|
||||
"title": "Ei vielä ilmoituskanavia",
|
||||
"description": "Yhdistä Slack, Discord, sähköposti, webhookit ja muut, jotta oikeat ihmiset kuulevat tapauksista heti."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "Chat-tunnus",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Pushover-määritys",
|
||||
"description": "Anna Pushover-sovellustunnus ja käyttäjäavain.",
|
||||
"optionAppToken": "Sovellustunnus",
|
||||
"placeholderAppToken": "Anna sovellustunnus",
|
||||
"optionUserKey": "Käyttäjäavain",
|
||||
"placeholderUserKey": "Anna käyttäjäavain"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Twilio-määritys",
|
||||
"description": "Anna Twilio-tilin tunnistetiedot tekstiviestien lähettämistä varten.",
|
||||
"optionAccountSid": "Tilin SID",
|
||||
"placeholderAccountSid": "Anna tilin SID",
|
||||
"optionAuthToken": "Todennustunnus",
|
||||
"placeholderAuthToken": "Anna todennustunnus",
|
||||
"optionFromNumber": "Lähettäjän numero",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Vastaanottajan numero",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Kohde"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Ilmoitukset",
|
||||
"description": "Yhdistä Slack, Discord, sähköposti, webhookit ja muut, jotta oikeat ihmiset kuulevat tapauksista heti."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Luo monitori!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "PageSpeed-monitorilla voit:"
|
||||
"title": "Ei vielä PageSpeed-monitoreita",
|
||||
"description": "Seuraa Core Web Vitals -mittareita ja Lighthouse-pisteitä ajan mittaan ja huomaa heikennykset ennen käyttäjiä."
|
||||
},
|
||||
"header": {
|
||||
"title": "PageSpeed-monitorit",
|
||||
"description": "Seuraa Core Web Vitals -mittareita ja Lighthouse-pisteitä ajan mittaan ja huomaa heikennykset ennen käyttäjiä."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Korjaa seuraavat vahvistusvirheet:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Asetukset",
|
||||
"description": "Määritä SMTP, integraatiot, säilytys ja sovelluksen yleinen käyttäytyminen."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Tilasivu poistettu onnistuneesti",
|
||||
"fallback": {
|
||||
"title": "Tilasivulla voit:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "Luo tilasivu!"
|
||||
"title": "Ei vielä tilasivuja",
|
||||
"actionButton": "Luo tilasivu!",
|
||||
"description": "Julkaise julkinen sivu, joka näyttää asiakkaille ja sidosryhmille reaaliaikaisen käytettävyyden ja tapaushistorian."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Lämpökartta",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "Kaikki järjestelmät ovat alhaalla",
|
||||
"allUp": "Kaikki järjestelmät toiminnassa",
|
||||
"degraded": "Joissakin järjestelmissä on ongelmia",
|
||||
"unknown": "Järjestelmän tilaa ei voida määrittää"
|
||||
"unknown": "Järjestelmän tilaa ei voida määrittää",
|
||||
"allBreached": "Kaikki järjestelmät ovat ylittäneet kynnysarvot",
|
||||
"allMaintenance": "Kaikki järjestelmät ovat huollossa",
|
||||
"allPaused": "Kaikki järjestelmät on keskeytetty",
|
||||
"allInitializing": "Kaikki järjestelmät alustuvat",
|
||||
"breachedAndDown": "Jotkin järjestelmät ovat ylittäneet kynnysarvot ja ovat alhaalla",
|
||||
"breached": "Jotkin järjestelmät ovat ylittäneet kynnysarvot",
|
||||
"maintenanceAndDown": "Jotkin järjestelmät ovat alhaalla huollon aikana",
|
||||
"maintenance": "Jotkin järjestelmät ovat huollossa",
|
||||
"partiallyPaused": "Jotkin järjestelmät on keskeytetty",
|
||||
"initializing": "Jotkin järjestelmät alustuvat",
|
||||
"noMonitors": "Yhtään monitoria ei ole määritetty"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Tilasivut",
|
||||
"description": "Julkaise julkisia sivuja, jotka näyttävät asiakkaille ja sidosryhmille reaaliaikaisen käytettävyyden ja tapaushistorian."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Luo monitori!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "Käytettävyysmonitorilla voit:"
|
||||
"title": "Ei vielä käytettävyysmonitoreita",
|
||||
"description": "Tarkkaile HTTP-päätepisteitä, pingejä, kontteja ja portteja — saat hälytyksen heti, kun jokin kaatuu."
|
||||
},
|
||||
"header": {
|
||||
"title": "Käytettävyysmonitorit",
|
||||
"description": "Tarkkaile HTTP-päätepisteitä, pingejä, kontteja ja portteja — saat hälytyksen heti, kun jokin kaatuu."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+138
-16
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "Star Checkmate",
|
||||
"description": "Consultez les dernières versions et aidez la communauté à grandir sur GitHub"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Assistance",
|
||||
"discussions": "Discussions",
|
||||
"docs": "Documentation",
|
||||
"changelog": "Journal des modifications"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "Sélectionnez un rôle"
|
||||
},
|
||||
"linkLabel": "Lien d'invitation"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Aucun membre d'équipe pour le moment",
|
||||
"description": "Invitez vos coéquipiers par e-mail ou ajoutez-les directement. Une fois qu'ils auront rejoint, ils apparaîtront ici avec leur rôle."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Compte",
|
||||
"description": "Gérez votre profil, mot de passe, équipe et préférences d'espace de travail."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Surveillance d'infrastructure open source",
|
||||
"tagline": "Surveillez chaque mouvement de vos serveurs.",
|
||||
"description": "Suivi en temps réel de la disponibilité, du temps de réponse et des incidents - auto-hébergé et à vous."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "Bienvenue sur Checkmate !",
|
||||
"subtitle": "Inscrivez-vous pour commencer",
|
||||
"submit": "S'inscrire"
|
||||
"submit": "S'inscrire",
|
||||
"setupNotice": "Cette page n'est disponible que lors de la configuration initiale. Une fois qu'un super administrateur est enregistré, des utilisateurs supplémentaires peuvent être invités depuis les paramètres de l'équipe."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "Mot de passe oublié ?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "Code de statut",
|
||||
"location": "Emplacement"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Aucune vérification pour le moment",
|
||||
"description": "Une fois que vous aurez créé un moniteur, chaque sonde d'état et temps de réponse apparaîtra ici sous forme de vérification."
|
||||
},
|
||||
"header": {
|
||||
"title": "Vérifications",
|
||||
"description": "Chaque sonde que Checkmate exécute contre vos moniteurs apparaît ici avec le code d'état et le temps de réponse."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Actif depuis",
|
||||
"certificateExpiry": "Expiration du certificat",
|
||||
"lastCheck": "Dernière vérification",
|
||||
"lastResponseTime": "Dernier temps de réponse"
|
||||
"lastResponseTime": "Dernier temps de réponse",
|
||||
"serviceIsDown": "Le service est indisponible"
|
||||
},
|
||||
"status": {
|
||||
"down": "hors ligne",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Aucun incident — tous les systèmes sont sains",
|
||||
"description": "Lorsqu'un moniteur tombe en panne ou se rétablit, l'incident apparaîtra ici avec l'horodatage, les détails du moniteur et l'historique de résolution."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Résoudre l'incident",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Actif",
|
||||
"resolved": "Résolu"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Incidents",
|
||||
"description": "Lorsqu'un moniteur tombe en panne ou se rétablit, les incidents apparaissent ici avec l'horodatage, les détails du moniteur et l'historique de résolution."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,11 +813,19 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Créer un moniteur !",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "Un moniteur d'infrastructure sert à :"
|
||||
"title": "Aucun moniteur d'infrastructure",
|
||||
"description": "Suivez les performances des serveurs, identifiez les goulots d'étranglement et garantissez la fiabilité avec une surveillance en temps réel."
|
||||
},
|
||||
"header": {
|
||||
"title": "Moniteurs d'infrastructure",
|
||||
"description": "Suivez les performances des serveurs, identifiez les goulots d'étranglement et garantissez la fiabilité avec une surveillance en temps réel."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Aucun journal pour le moment",
|
||||
"description": "L'activité du serveur, les avertissements et les erreurs apparaîtront ici pendant l'exécution de Checkmate."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "Diagnostic",
|
||||
"logs": "Journaux des serveurs",
|
||||
@@ -788,7 +835,9 @@
|
||||
"label": "Niveau de log"
|
||||
},
|
||||
"jobQueue": "File d'attente des tâches",
|
||||
"jobQueueExplainer": "<highlight>Les lignes mises en évidence</highlight> sont les tâches actuellement traitées par un worker.",
|
||||
"failedJobs": "Tâches échouées",
|
||||
"failedJobsExplainer": "Échecs récents par moniteur — heure du dernier échec, nombre d'échecs et raison.",
|
||||
"noLogs": "Aucun log trouvé",
|
||||
"metrics": {
|
||||
"jobs": "Tâches",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% de 1s utilisé par le CPU",
|
||||
"total": "Total",
|
||||
"used": "Utilisé"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Statistiques d'exécution",
|
||||
"description": "Aperçu du processus Node.js et de la machine hôte. Mis à jour toutes les 5 secondes."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Mémoire et CPU",
|
||||
"description": "Comment le processus utilise sa mémoire allouée et le CPU de l'hôte."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "Dernier échec",
|
||||
"failReason": "Raison de l'échec"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "Aucun travail dans la file",
|
||||
"description": "Les vérifications de moniteurs planifiées ou en cours apparaîtront ici. Une file vide signifie que tout est à jour."
|
||||
},
|
||||
"header": {
|
||||
"title": "Journaux et file",
|
||||
"description": "Inspectez les journaux serveur, la file des tâches de moniteur et les diagnostics d'exécution au même endroit."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Créer une fenêtre de maintenance !",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "Une fenêtre de maintenance sert à :"
|
||||
"title": "Aucune fenêtre de maintenance planifiée",
|
||||
"description": "Planifiez les interruptions afin que les alertes soient supprimées et que votre équipe et vos utilisateurs sachent à quoi s'attendre."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Fenêtres de maintenance",
|
||||
"description": "Planifiez les interruptions afin que les alertes soient supprimées et que votre équipe et vos utilisateurs sachent à quoi s'attendre."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Créer un canal",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "Les canaux de notification servent à :"
|
||||
"title": "Aucun canal de notification",
|
||||
"description": "Connectez Slack, Discord, e-mail, webhooks et plus encore pour que les bonnes personnes soient prévenues dès qu'un incident survient."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "ID du chat",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Configuration Pushover",
|
||||
"description": "Entrez votre jeton d'application et votre clé utilisateur Pushover.",
|
||||
"optionAppToken": "Jeton d'application",
|
||||
"placeholderAppToken": "Entrez le jeton d'application",
|
||||
"optionUserKey": "Clé utilisateur",
|
||||
"placeholderUserKey": "Entrez la clé utilisateur"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Configuration Twilio",
|
||||
"description": "Entrez les identifiants de votre compte Twilio pour envoyer des SMS.",
|
||||
"optionAccountSid": "SID du compte",
|
||||
"placeholderAccountSid": "Entrez le SID du compte",
|
||||
"optionAuthToken": "Jeton d'authentification",
|
||||
"placeholderAuthToken": "Entrez le jeton d'authentification",
|
||||
"optionFromNumber": "Numéro d'origine",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Numéro de destination",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Destination"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Notifications",
|
||||
"description": "Connectez Slack, Discord, e-mail, webhooks et plus encore pour que les bonnes personnes soient prévenues dès qu'un incident survient."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Créer un moniteur !",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "Un moniteur PageSpeed sert à :"
|
||||
"title": "Aucun moniteur PageSpeed",
|
||||
"description": "Suivez les Core Web Vitals et les scores Lighthouse au fil du temps pour détecter les régressions avant vos utilisateurs."
|
||||
},
|
||||
"header": {
|
||||
"title": "Moniteurs PageSpeed",
|
||||
"description": "Suivez les Core Web Vitals et les scores Lighthouse au fil du temps pour détecter les régressions avant vos utilisateurs."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Veuillez corriger les erreurs de validation suivantes :"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Paramètres",
|
||||
"description": "Configurez SMTP, intégrations, rétention et comportement global de l'application."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Page de statut supprimée avec succès",
|
||||
"fallback": {
|
||||
"title": "Une page de statut sert à :",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "Créer une page de statut !"
|
||||
"title": "Aucune page de statut",
|
||||
"actionButton": "Créer une page de statut !",
|
||||
"description": "Publiez une page publique qui montre à vos clients et parties prenantes la disponibilité en temps réel et l'historique des incidents."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Carte thermique",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "Tous les systèmes sont hors service",
|
||||
"allUp": "Tous les systèmes sont opérationnels",
|
||||
"degraded": "Certains systèmes rencontrent des problèmes",
|
||||
"unknown": "Impossible de déterminer le statut du système"
|
||||
"unknown": "Impossible de déterminer le statut du système",
|
||||
"allBreached": "Tous les systèmes ont dépassé les seuils",
|
||||
"allMaintenance": "Tous les systèmes sont en maintenance",
|
||||
"allPaused": "Tous les systèmes sont en pause",
|
||||
"allInitializing": "Tous les systèmes sont en cours d'initialisation",
|
||||
"breachedAndDown": "Certains systèmes ont dépassé les seuils et sont hors ligne",
|
||||
"breached": "Certains systèmes ont dépassé les seuils",
|
||||
"maintenanceAndDown": "Certains systèmes sont hors ligne pendant la maintenance",
|
||||
"maintenance": "Certains systèmes sont en maintenance",
|
||||
"partiallyPaused": "Certains systèmes sont en pause",
|
||||
"initializing": "Certains systèmes sont en cours d'initialisation",
|
||||
"noMonitors": "Aucun moniteur n'a été configuré"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Pages de statut",
|
||||
"description": "Publiez des pages publiques montrant à vos clients et parties prenantes la disponibilité en temps réel et l'historique des incidents."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Créer un moniteur !",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "Un moniteur de disponibilité sert à :"
|
||||
"title": "Aucun moniteur de disponibilité",
|
||||
"description": "Surveillez les points de terminaison HTTP, les pings, les conteneurs et les ports — soyez alerté dès qu'une panne survient."
|
||||
},
|
||||
"header": {
|
||||
"title": "Moniteurs de disponibilité",
|
||||
"description": "Surveillez les points de terminaison HTTP, les pings, les conteneurs et les ports — soyez alerté dès qu'une panne survient."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+138
-16
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "Checkmateにスターを付ける",
|
||||
"description": "GitHubで最新リリースを確認し、コミュニティの成長に貢献しましょう"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "サポート",
|
||||
"discussions": "ディスカッション",
|
||||
"docs": "ドキュメント",
|
||||
"changelog": "変更履歴"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "ロールを選択"
|
||||
},
|
||||
"linkLabel": "招待リンク"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "チームメンバーがまだいません",
|
||||
"description": "メールでチームメイトを招待するか、直接追加してください。参加すると、役割とともにここに表示されます。"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "アカウント",
|
||||
"description": "プロファイル、パスワード、チーム、ワークスペースの設定を管理します。"
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "オープンソースのインフラ監視",
|
||||
"tagline": "サーバーのすべての動きを見守ろう。",
|
||||
"description": "稼働状況、応答時間、インシデントをリアルタイムで追跡 - セルフホスト型で完全にあなたのもの。"
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "Checkmateへようこそ!",
|
||||
"subtitle": "サインアップして始めましょう",
|
||||
"submit": "登録"
|
||||
"submit": "登録",
|
||||
"setupNotice": "このページは初期セットアップ中のみ利用できます。スーパー管理者が登録されると、追加のユーザーはチーム設定から招待できます。"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "パスワードをお忘れですか?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "ステータスコード",
|
||||
"location": "ロケーション"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "チェックがまだありません",
|
||||
"description": "モニターを作成すると、すべてのステータスプローブと応答時間がここにチェックとして表示されます。"
|
||||
},
|
||||
"header": {
|
||||
"title": "チェック",
|
||||
"description": "Checkmateがモニターに対して実行するすべてのプローブが、ステータスコードと応答時間とともにここに表示されます。"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "稼働期間",
|
||||
"certificateExpiry": "証明書の有効期限",
|
||||
"lastCheck": "最終チェック",
|
||||
"lastResponseTime": "最終応答時間"
|
||||
"lastResponseTime": "最終応答時間",
|
||||
"serviceIsDown": "サービスがダウンしています"
|
||||
},
|
||||
"status": {
|
||||
"down": "ダウン",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "インシデントなし — すべてのシステムが正常です",
|
||||
"description": "モニターがダウンまたは復旧すると、タイミング、モニターの詳細、解決履歴とともにここに表示されます。"
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "インシデントを解決",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "アクティブ",
|
||||
"resolved": "解決済み"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "インシデント",
|
||||
"description": "モニターがダウンまたは復旧すると、インシデントがタイミング、モニターの詳細、解決履歴とともにここに表示されます。"
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,11 +813,19 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "モニターを作成!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "インフラストラクチャモニターの用途:"
|
||||
"title": "インフラモニターがまだありません",
|
||||
"description": "サーバーのパフォーマンスを追跡し、ボトルネックを特定し、リアルタイムのインフラ監視で信頼性を確保します。"
|
||||
},
|
||||
"header": {
|
||||
"title": "インフラ監視",
|
||||
"description": "サーバーのパフォーマンスを追跡し、ボトルネックを特定し、リアルタイムのインフラ監視で信頼性を確保します。"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "ログがまだありません",
|
||||
"description": "サーバーのアクティビティ、警告、エラーがCheckmateの実行中にここに表示されます。"
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "診断",
|
||||
"logs": "サーバーログ",
|
||||
@@ -788,7 +835,9 @@
|
||||
"label": "ログレベル"
|
||||
},
|
||||
"jobQueue": "ジョブキュー",
|
||||
"jobQueueExplainer": "<highlight>ハイライトされた行</highlight>は、現在ワーカーによって処理中のジョブです。",
|
||||
"failedJobs": "失敗したジョブ",
|
||||
"failedJobsExplainer": "モニター別の最近の失敗 — 最終失敗時刻、失敗回数、および理由。",
|
||||
"noLogs": "ログが見つかりません",
|
||||
"metrics": {
|
||||
"jobs": "ジョブ",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "CPUによる1秒あたりの使用%",
|
||||
"total": "合計",
|
||||
"used": "使用済み"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "ランタイム統計",
|
||||
"description": "Node.jsプロセスとホストマシンのスナップショット。5秒ごとに更新されます。"
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "メモリとCPU",
|
||||
"description": "プロセスが割り当てられたメモリとホストCPUをどのように使用しているか。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "最終失敗日時",
|
||||
"failReason": "失敗理由"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "キューにジョブがありません",
|
||||
"description": "スケジュールされたモニターチェックや実行中のチェックがここに表示されます。空のキューはすべてが最新であることを意味します。"
|
||||
},
|
||||
"header": {
|
||||
"title": "ログとキュー",
|
||||
"description": "サーバーログ、モニタージョブキュー、ランタイム診断を一か所で確認できます。"
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "メンテナンスウィンドウを作成!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "メンテナンスウィンドウの用途:"
|
||||
"title": "予定されているメンテナンスウィンドウはありません",
|
||||
"description": "計画されたダウンタイムをスケジュールしてアラートを抑制し、チームとユーザーに事前に知らせます。"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "メンテナンスウィンドウ",
|
||||
"description": "計画されたダウンタイムをスケジュールしてアラートを抑制し、チームとユーザーに事前に知らせます。"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "チャンネルを作成",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "通知チャンネルの用途:"
|
||||
"title": "通知チャンネルがまだありません",
|
||||
"description": "Slack、Discord、メール、Webhookなどを接続して、インシデント発生時に適切な担当者に通知します。"
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "チャットID",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Pushover の設定",
|
||||
"description": "Pushover のアプリケーショントークンとユーザーキーを入力してください。",
|
||||
"optionAppToken": "アプリトークン",
|
||||
"placeholderAppToken": "アプリトークンを入力",
|
||||
"optionUserKey": "ユーザーキー",
|
||||
"placeholderUserKey": "ユーザーキーを入力"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Twilio の設定",
|
||||
"description": "SMS を送信するための Twilio アカウント認証情報を入力してください。",
|
||||
"optionAccountSid": "アカウント SID",
|
||||
"placeholderAccountSid": "アカウント SID を入力",
|
||||
"optionAuthToken": "認証トークン",
|
||||
"placeholderAuthToken": "認証トークンを入力",
|
||||
"optionFromNumber": "送信元番号",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "送信先番号",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "送信先"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "通知",
|
||||
"description": "Slack、Discord、メール、Webhookなどを接続して、インシデント発生時に適切な担当者に通知します。"
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "モニターを作成!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "PageSpeedモニターの用途:"
|
||||
"title": "PageSpeedモニターがまだありません",
|
||||
"description": "Core Web VitalsとLighthouseスコアを継続的に追跡し、ユーザーが気付く前に劣化を発見します。"
|
||||
},
|
||||
"header": {
|
||||
"title": "PageSpeed監視",
|
||||
"description": "Core Web VitalsとLighthouseスコアを継続的に追跡し、ユーザーが気付く前に劣化を発見します。"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "以下のバリデーションエラーを修正してください:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "設定",
|
||||
"description": "SMTP、統合、保持、グローバルアプリの動作を設定します。"
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "ステータスページが正常に削除されました",
|
||||
"fallback": {
|
||||
"title": "ステータスページの用途:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "ステータスページを作成!"
|
||||
"title": "ステータスページがまだありません",
|
||||
"actionButton": "ステータスページを作成!",
|
||||
"description": "顧客と関係者にリアルタイムの稼働状況とインシデント履歴を表示する公開ページを公開します。"
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "ヒートマップ",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "すべてのシステムがダウンしています",
|
||||
"allUp": "すべてのシステムが正常に稼働しています",
|
||||
"degraded": "一部のシステムに問題が発生しています",
|
||||
"unknown": "システムステータスを判定できません"
|
||||
"unknown": "システムステータスを判定できません",
|
||||
"allBreached": "すべてのシステムがしきい値を超えました",
|
||||
"allMaintenance": "すべてのシステムがメンテナンス中です",
|
||||
"allPaused": "すべてのシステムが一時停止中です",
|
||||
"allInitializing": "すべてのシステムが初期化中です",
|
||||
"breachedAndDown": "一部のシステムがしきい値を超えてダウンしています",
|
||||
"breached": "一部のシステムがしきい値を超えています",
|
||||
"maintenanceAndDown": "一部のシステムがメンテナンス中にダウンしています",
|
||||
"maintenance": "一部のシステムがメンテナンス中です",
|
||||
"partiallyPaused": "一部のシステムが一時停止中です",
|
||||
"initializing": "一部のシステムが初期化中です",
|
||||
"noMonitors": "モニターが設定されていません"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "ステータスページ",
|
||||
"description": "顧客と関係者にリアルタイムの稼働状況とインシデント履歴を表示する公開ページを公開します。"
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "モニターを作成!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "稼働時間モニターの用途:"
|
||||
"title": "アップタイムモニターがまだありません",
|
||||
"description": "HTTPエンドポイント、Ping、コンテナ、ポートを監視し、ダウンした瞬間に通知を受け取ります。"
|
||||
},
|
||||
"header": {
|
||||
"title": "稼働監視",
|
||||
"description": "HTTPエンドポイント、Ping、コンテナ、ポートを監視し、ダウンした瞬間に通知を受け取ります。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+138
-16
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "Avalie o Checkmate",
|
||||
"description": "Veja os últimos lançamentos e ajude a comunidade a crescer no GitHub"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Suporte",
|
||||
"discussions": "Discussões",
|
||||
"docs": "Documentação",
|
||||
"changelog": "Notas de versão"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "Selecione uma função"
|
||||
},
|
||||
"linkLabel": "Link de convite"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Ainda não há membros na equipe",
|
||||
"description": "Convide colegas por e-mail ou adicione-os diretamente. Assim que entrarem, aparecerão aqui com sua função."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Conta",
|
||||
"description": "Gerencie seu perfil, senha, equipe e preferências de workspace."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Monitoramento de infraestrutura open-source",
|
||||
"tagline": "Acompanhe cada passo dos seus servidores.",
|
||||
"description": "Monitoramento em tempo real de disponibilidade, tempo de resposta e incidentes - auto-hospedado e seu."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "Bem-vindo ao Checkmate!",
|
||||
"subtitle": "Cadastre-se para começar",
|
||||
"submit": "Cadastrar"
|
||||
"submit": "Cadastrar",
|
||||
"setupNotice": "Esta página está disponível apenas durante a configuração inicial. Após o registro de um super administrador, usuários adicionais podem ser convidados a partir das configurações da equipe."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "Esqueceu sua senha?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "Código de status",
|
||||
"location": "Localização"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Ainda não há verificações",
|
||||
"description": "Assim que você criar um monitor, cada sondagem de status e tempo de resposta aparecerá aqui como uma verificação."
|
||||
},
|
||||
"header": {
|
||||
"title": "Verificações",
|
||||
"description": "Cada sonda que o Checkmate executa contra seus monitores aparece aqui com código de status e tempo de resposta."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Ativo há",
|
||||
"certificateExpiry": "Validade do certificado",
|
||||
"lastCheck": "Última verificação",
|
||||
"lastResponseTime": "Último tempo de resposta"
|
||||
"lastResponseTime": "Último tempo de resposta",
|
||||
"serviceIsDown": "O serviço está fora do ar"
|
||||
},
|
||||
"status": {
|
||||
"down": "fora do ar",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Sem incidentes — todos os sistemas saudáveis",
|
||||
"description": "Quando um monitor falha ou se recupera, o incidente aparecerá aqui com horários, detalhes do monitor e histórico de resolução."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Resolver incidente",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Ativo",
|
||||
"resolved": "Resolvido"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Incidentes",
|
||||
"description": "Quando um monitor falha ou se recupera, os incidentes aparecem aqui com horários, detalhes do monitor e histórico de resolução."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,11 +813,19 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Criar um monitor!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "Um monitor de infraestrutura é usado para:"
|
||||
"title": "Ainda não há monitores de infraestrutura",
|
||||
"description": "Acompanhe o desempenho dos servidores, identifique gargalos e garanta confiabilidade com monitoramento em tempo real."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitores de infraestrutura",
|
||||
"description": "Acompanhe o desempenho dos servidores, identifique gargalos e garanta confiabilidade com monitoramento em tempo real."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Ainda não há logs",
|
||||
"description": "Atividade do servidor, avisos e erros aparecerão aqui enquanto o Checkmate roda."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "Diagnóstico",
|
||||
"logs": "Logs do servidor",
|
||||
@@ -788,7 +835,9 @@
|
||||
"label": "Nível de log"
|
||||
},
|
||||
"jobQueue": "Fila de tarefas",
|
||||
"jobQueueExplainer": "<highlight>As linhas destacadas</highlight> são as tarefas que estão sendo processadas atualmente por um worker.",
|
||||
"failedJobs": "Tarefas com falha",
|
||||
"failedJobsExplainer": "Falhas recentes por monitor — horário da última falha, contagem de falhas e o motivo.",
|
||||
"noLogs": "Nenhum log encontrado",
|
||||
"metrics": {
|
||||
"jobs": "Tarefas",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% de 1s usado pela CPU",
|
||||
"total": "Total",
|
||||
"used": "Usado"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Estatísticas de execução",
|
||||
"description": "Snapshot do processo Node.js e da máquina host. Atualiza a cada 5 segundos."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Memória e CPU",
|
||||
"description": "Como o processo está usando a memória alocada e a CPU do host."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "Última falha em",
|
||||
"failReason": "Motivo da falha"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "Sem tarefas na fila",
|
||||
"description": "Verificações de monitores agendadas ou em execução aparecerão aqui. Uma fila vazia significa que tudo está em dia."
|
||||
},
|
||||
"header": {
|
||||
"title": "Logs e fila",
|
||||
"description": "Inspecione logs do servidor, fila de tarefas de monitor e diagnósticos de runtime em um só lugar."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Criar uma janela de manutenção!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "Uma janela de manutenção é usada para:"
|
||||
"title": "Nenhuma janela de manutenção agendada",
|
||||
"description": "Programe paradas planejadas para que os alertas sejam suprimidos e sua equipe e usuários saibam o que esperar."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Janelas de manutenção",
|
||||
"description": "Programe paradas planejadas para que os alertas sejam suprimidos e sua equipe e usuários saibam o que esperar."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Criar um canal",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "Canais de notificação são usados para:"
|
||||
"title": "Ainda não há canais de notificação",
|
||||
"description": "Conecte Slack, Discord, e-mail, webhooks e outros para que as pessoas certas saibam dos incidentes assim que acontecerem."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "ID do chat",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Configuração do Pushover",
|
||||
"description": "Insira o token de aplicação e a chave de usuário do Pushover.",
|
||||
"optionAppToken": "Token de aplicação",
|
||||
"placeholderAppToken": "Insira o token de aplicação",
|
||||
"optionUserKey": "Chave de usuário",
|
||||
"placeholderUserKey": "Insira a chave de usuário"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Configuração do Twilio",
|
||||
"description": "Insira as credenciais da conta Twilio para enviar SMS.",
|
||||
"optionAccountSid": "SID da conta",
|
||||
"placeholderAccountSid": "Insira o SID da conta",
|
||||
"optionAuthToken": "Token de autenticação",
|
||||
"placeholderAuthToken": "Insira o token de autenticação",
|
||||
"optionFromNumber": "Número de origem",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Número de destino",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Destino"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Notificações",
|
||||
"description": "Conecte Slack, Discord, e-mail, webhooks e outros para que as pessoas certas saibam dos incidentes assim que acontecerem."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Criar um monitor!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "Um monitor PageSpeed é usado para:"
|
||||
"title": "Ainda não há monitores PageSpeed",
|
||||
"description": "Acompanhe Core Web Vitals e pontuações do Lighthouse ao longo do tempo para detectar regressões antes dos seus usuários."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitores PageSpeed",
|
||||
"description": "Acompanhe Core Web Vitals e pontuações do Lighthouse ao longo do tempo para detectar regressões antes dos seus usuários."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Por favor, corrija os seguintes erros de validação:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Configurações",
|
||||
"description": "Configure SMTP, integrações, retenção e comportamento global do app."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Página de status excluída com sucesso",
|
||||
"fallback": {
|
||||
"title": "Uma página de status é usada para:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "Criar uma página de status!"
|
||||
"title": "Ainda não há páginas de status",
|
||||
"actionButton": "Criar uma página de status!",
|
||||
"description": "Publique uma página pública que mostre aos seus clientes e partes interessadas o tempo de atividade em tempo real e o histórico de incidentes."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Mapa de calor",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "Todos os sistemas estão fora do ar",
|
||||
"allUp": "Todos os sistemas operacionais",
|
||||
"degraded": "Alguns sistemas estão com problemas",
|
||||
"unknown": "Não foi possível determinar o status do sistema"
|
||||
"unknown": "Não foi possível determinar o status do sistema",
|
||||
"allBreached": "Todos os sistemas excederam os limites",
|
||||
"allMaintenance": "Todos os sistemas estão em manutenção",
|
||||
"allPaused": "Todos os sistemas estão pausados",
|
||||
"allInitializing": "Todos os sistemas estão inicializando",
|
||||
"breachedAndDown": "Alguns sistemas excederam os limites e estão fora do ar",
|
||||
"breached": "Alguns sistemas excederam os limites",
|
||||
"maintenanceAndDown": "Alguns sistemas estão fora do ar durante a manutenção",
|
||||
"maintenance": "Alguns sistemas estão em manutenção",
|
||||
"partiallyPaused": "Alguns sistemas estão pausados",
|
||||
"initializing": "Alguns sistemas estão inicializando",
|
||||
"noMonitors": "Nenhum monitor foi configurado"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Páginas de status",
|
||||
"description": "Publique páginas públicas que mostram aos seus clientes e partes interessadas o tempo de atividade em tempo real e o histórico de incidentes."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Criar um monitor!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "Um monitor de uptime é usado para:"
|
||||
"title": "Ainda não há monitores de uptime",
|
||||
"description": "Acompanhe endpoints HTTP, pings, contêineres e portas — receba alertas no momento em que algo falhar."
|
||||
},
|
||||
"header": {
|
||||
"title": "Monitores de uptime",
|
||||
"description": "Acompanhe endpoints HTTP, pings, contêineres e portas — receba alertas no momento em que algo falhar."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+138
-16
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "Star Checkmate",
|
||||
"description": "Следите за последними релизами и помогайте развивать сообщество на GitHub"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Поддержка",
|
||||
"discussions": "Обсуждения",
|
||||
"docs": "Документация",
|
||||
"changelog": "Журнал изменений"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "Выберите роль"
|
||||
},
|
||||
"linkLabel": "Ссылка-приглашение"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Пока нет участников команды",
|
||||
"description": "Пригласите коллег по электронной почте или добавьте их напрямую. Как только они присоединятся, они появятся здесь со своей ролью."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Учётная запись",
|
||||
"description": "Управляйте профилем, паролем, командой и настройками рабочего пространства."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Мониторинг инфраструктуры с открытым исходным кодом",
|
||||
"tagline": "Следите за каждым шагом ваших серверов.",
|
||||
"description": "Мониторинг доступности, времени отклика и инцидентов в реальном времени - self-hosted и принадлежит вам."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "С возвращением в Checkmate!",
|
||||
"subtitle": "Зарегистрируйтесь, чтобы начать",
|
||||
"submit": "Регистрация"
|
||||
"submit": "Регистрация",
|
||||
"setupNotice": "Эта страница доступна только во время первоначальной настройки. После регистрации суперадминистратора дополнительных пользователей можно пригласить из настроек команды."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "Забыли пароль?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "Код статуса",
|
||||
"location": "Расположение"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Пока нет проверок",
|
||||
"description": "Как только вы создадите монитор, каждая проверка состояния и время отклика появятся здесь."
|
||||
},
|
||||
"header": {
|
||||
"title": "Проверки",
|
||||
"description": "Каждый зонд, который Checkmate выполняет к вашим мониторам, появится здесь с кодом состояния и временем отклика."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Активен",
|
||||
"certificateExpiry": "Истечение сертификата",
|
||||
"lastCheck": "Последняя проверка",
|
||||
"lastResponseTime": "Последнее время ответа"
|
||||
"lastResponseTime": "Последнее время ответа",
|
||||
"serviceIsDown": "Сервис недоступен"
|
||||
},
|
||||
"status": {
|
||||
"down": "недоступен",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Инцидентов нет — все системы исправны",
|
||||
"description": "Когда монитор перестаёт работать или восстанавливается, инцидент появится здесь со временем, деталями монитора и историей решения."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Решить инцидент",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Активный",
|
||||
"resolved": "Решён"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Инциденты",
|
||||
"description": "Когда монитор перестаёт работать или восстанавливается, инцидент появляется здесь со временем, деталями монитора и историей решения."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,11 +813,19 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Создать монитор!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "Монитор инфраструктуры используется для:"
|
||||
"title": "Пока нет инфраструктурных мониторов",
|
||||
"description": "Отслеживайте производительность серверов, выявляйте узкие места и обеспечивайте надёжность с мониторингом в реальном времени."
|
||||
},
|
||||
"header": {
|
||||
"title": "Инфраструктурные мониторы",
|
||||
"description": "Отслеживайте производительность серверов, выявляйте узкие места и обеспечивайте надёжность с мониторингом в реальном времени."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Пока нет журналов",
|
||||
"description": "Активность сервера, предупреждения и ошибки появятся здесь во время работы Checkmate."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "Диагностика",
|
||||
"logs": "Серверные логи",
|
||||
@@ -788,7 +835,9 @@
|
||||
"label": "Уровень логов"
|
||||
},
|
||||
"jobQueue": "Очередь заданий",
|
||||
"jobQueueExplainer": "<highlight>Выделенные строки</highlight> — это задания, которые в данный момент обрабатываются воркером.",
|
||||
"failedJobs": "Неудачные задания",
|
||||
"failedJobsExplainer": "Недавние сбои по мониторам — время последнего сбоя, количество сбоев и причина.",
|
||||
"noLogs": "Логи не найдены",
|
||||
"metrics": {
|
||||
"jobs": "Задания",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% 1с использовано CPU",
|
||||
"total": "Всего",
|
||||
"used": "Использовано"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Статистика выполнения",
|
||||
"description": "Снимок процесса Node.js и хост-машины. Обновляется каждые 5 секунд."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Память и ЦП",
|
||||
"description": "Как процесс использует выделенную память и ЦП хоста."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "Последняя ошибка",
|
||||
"failReason": "Причина ошибки"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "В очереди нет заданий",
|
||||
"description": "Запланированные или выполняемые проверки мониторов будут отображаться здесь. Пустая очередь означает, что всё актуально."
|
||||
},
|
||||
"header": {
|
||||
"title": "Журналы и очередь",
|
||||
"description": "Изучайте журналы сервера, очередь заданий мониторов и диагностику в одном месте."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Создать окно обслуживания!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "Окно обслуживания используется для:"
|
||||
"title": "Нет запланированных окон обслуживания",
|
||||
"description": "Планируйте плановые простои, чтобы оповещения были подавлены, а команда и пользователи знали, чего ожидать."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Окна обслуживания",
|
||||
"description": "Планируйте плановые простои, чтобы оповещения были подавлены, а команда и пользователи знали, чего ожидать."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Создать канал",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "Каналы уведомлений используются для:"
|
||||
"title": "Пока нет каналов уведомлений",
|
||||
"description": "Подключите Slack, Discord, email, вебхуки и другое, чтобы нужные люди узнавали об инцидентах сразу же."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "ID чата",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Настройка Pushover",
|
||||
"description": "Введите токен приложения и ключ пользователя Pushover.",
|
||||
"optionAppToken": "Токен приложения",
|
||||
"placeholderAppToken": "Введите токен приложения",
|
||||
"optionUserKey": "Ключ пользователя",
|
||||
"placeholderUserKey": "Введите ключ пользователя"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Настройка Twilio",
|
||||
"description": "Введите учётные данные аккаунта Twilio для отправки SMS.",
|
||||
"optionAccountSid": "SID аккаунта",
|
||||
"placeholderAccountSid": "Введите SID аккаунта",
|
||||
"optionAuthToken": "Токен аутентификации",
|
||||
"placeholderAuthToken": "Введите токен аутентификации",
|
||||
"optionFromNumber": "Номер отправителя",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Номер получателя",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Назначение"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Уведомления",
|
||||
"description": "Подключите Slack, Discord, email, вебхуки и другое, чтобы нужные люди узнавали об инцидентах сразу же."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Создать монитор!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "Монитор PageSpeed используется для:"
|
||||
"title": "Пока нет мониторов PageSpeed",
|
||||
"description": "Отслеживайте Core Web Vitals и оценки Lighthouse во времени, чтобы заметить регрессии раньше пользователей."
|
||||
},
|
||||
"header": {
|
||||
"title": "Мониторы PageSpeed",
|
||||
"description": "Отслеживайте Core Web Vitals и оценки Lighthouse во времени, чтобы заметить регрессии раньше пользователей."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Пожалуйста, исправьте следующие ошибки валидации:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Настройки",
|
||||
"description": "Настройте SMTP, интеграции, сроки хранения и общее поведение приложения."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Страница статуса успешно удалена",
|
||||
"fallback": {
|
||||
"title": "Страница статуса используется для:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "Создать страницу статуса!"
|
||||
"title": "Пока нет страниц состояния",
|
||||
"actionButton": "Создать страницу статуса!",
|
||||
"description": "Опубликуйте публичную страницу, показывающую клиентам и заинтересованным сторонам реальное время работы и историю инцидентов."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Тепловая карта",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "Все системы недоступны",
|
||||
"allUp": "Все системы работают",
|
||||
"degraded": "Некоторые системы испытывают проблемы",
|
||||
"unknown": "Не удаётся определить статус системы"
|
||||
"unknown": "Не удаётся определить статус системы",
|
||||
"allBreached": "Все системы превысили пороговые значения",
|
||||
"allMaintenance": "Все системы на техническом обслуживании",
|
||||
"allPaused": "Все системы приостановлены",
|
||||
"allInitializing": "Все системы инициализируются",
|
||||
"breachedAndDown": "Некоторые системы превысили пороги и недоступны",
|
||||
"breached": "Некоторые системы превысили пороги",
|
||||
"maintenanceAndDown": "Некоторые системы недоступны во время техобслуживания",
|
||||
"maintenance": "Некоторые системы на техобслуживании",
|
||||
"partiallyPaused": "Некоторые системы приостановлены",
|
||||
"initializing": "Некоторые системы инициализируются",
|
||||
"noMonitors": "Мониторы не настроены"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Страницы состояния",
|
||||
"description": "Публикуйте публичные страницы со временем работы и историей инцидентов для клиентов и заинтересованных сторон."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Создать монитор!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "Монитор аптайма используется для:"
|
||||
"title": "Пока нет мониторов работоспособности",
|
||||
"description": "Наблюдайте за HTTP-конечными точками, пингами, контейнерами и портами — получайте уведомления в момент отказа."
|
||||
},
|
||||
"header": {
|
||||
"title": "Мониторы работоспособности",
|
||||
"description": "Наблюдайте за HTTP-конечными точками, пингами, контейнерами и портами — получайте уведомления в момент отказа."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+138
-16
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "ให้ดาว Checkmate",
|
||||
"description": "ดูรุ่นล่าสุดและช่วยเติบโตชุมชนบน GitHub"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "ฝ่ายสนับสนุน",
|
||||
"discussions": "การสนทนา",
|
||||
"docs": "เอกสาร",
|
||||
"changelog": "บันทึกการเปลี่ยนแปลง"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "เลือกบทบาท"
|
||||
},
|
||||
"linkLabel": "ลิงก์เชิญ"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "ยังไม่มีสมาชิกทีม",
|
||||
"description": "เชิญเพื่อนร่วมทีมทางอีเมลหรือเพิ่มพวกเขาโดยตรง เมื่อพวกเขาเข้าร่วม พวกเขาจะปรากฏที่นี่พร้อมบทบาทของพวกเขา"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "บัญชี",
|
||||
"description": "จัดการโปรไฟล์ รหัสผ่าน ทีม และการตั้งค่าพื้นที่ทำงานของคุณ"
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "การมอนิเตอร์โครงสร้างพื้นฐานโอเพนซอร์ส",
|
||||
"tagline": "คอยจับตาดูทุกการเคลื่อนไหวของเซิร์ฟเวอร์ของคุณ",
|
||||
"description": "ติดตามสถานะ เวลาตอบสนอง และเหตุการณ์ผิดปกติแบบเรียลไทม์ - โฮสต์เองและเป็นของคุณ"
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "ยินดีต้อนรับกลับสู่ Checkmate!",
|
||||
"subtitle": "สมัครสมาชิกเพื่อเริ่มต้น",
|
||||
"submit": "ลงทะเบียน"
|
||||
"submit": "ลงทะเบียน",
|
||||
"setupNotice": "หน้านี้พร้อมใช้งานเฉพาะระหว่างการตั้งค่าเริ่มต้นเท่านั้น เมื่อลงทะเบียนผู้ดูแลระบบสูงสุดแล้ว สามารถเชิญผู้ใช้เพิ่มเติมได้จากการตั้งค่าทีม"
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "ลืมรหัสผ่านใช่ไหม?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "รหัสสถานะ",
|
||||
"location": "ตำแหน่ง"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "ยังไม่มีการตรวจสอบ",
|
||||
"description": "เมื่อคุณสร้างตัวตรวจสอบ การตรวจสอบสถานะและเวลาตอบสนองทุกครั้งจะปรากฏที่นี่เป็นการตรวจสอบ"
|
||||
},
|
||||
"header": {
|
||||
"title": "การตรวจสอบ",
|
||||
"description": "การตรวจสอบทุกครั้งที่ Checkmate ทำกับตัวตรวจสอบของคุณจะปรากฏที่นี่พร้อมรหัสสถานะและเวลาตอบสนอง"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "ทำงานมาแล้ว",
|
||||
"certificateExpiry": "วันหมดอายุใบรับรอง",
|
||||
"lastCheck": "ตรวจสอบล่าสุด",
|
||||
"lastResponseTime": "เวลาตอบสนองล่าสุด"
|
||||
"lastResponseTime": "เวลาตอบสนองล่าสุด",
|
||||
"serviceIsDown": "บริการขัดข้อง"
|
||||
},
|
||||
"status": {
|
||||
"down": "ล่ม",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "ไม่มีเหตุการณ์ — ระบบทั้งหมดทำงานปกติ",
|
||||
"description": "เมื่อตัวตรวจสอบล่มหรือฟื้นตัว เหตุการณ์จะปรากฏที่นี่พร้อมเวลา รายละเอียดตัวตรวจสอบ และประวัติการแก้ไข"
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "แก้ไขเหตุการณ์",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "ใช้งานอยู่",
|
||||
"resolved": "แก้ไขแล้ว"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "เหตุการณ์",
|
||||
"description": "เมื่อตัวตรวจสอบล่มหรือฟื้นตัว เหตุการณ์จะปรากฏที่นี่พร้อมเวลา รายละเอียดตัวตรวจสอบ และประวัติการแก้ไข"
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,11 +813,19 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "สร้างมอนิเตอร์!",
|
||||
"checks": "Track the performance of your servers,Identify bottlenecks and optimize usage,Ensure reliability with real-time monitoring",
|
||||
"title": "มอนิเตอร์โครงสร้างพื้นฐานใช้เพื่อ:"
|
||||
"title": "ยังไม่มีตัวตรวจสอบโครงสร้างพื้นฐาน",
|
||||
"description": "ติดตามประสิทธิภาพเซิร์ฟเวอร์ ระบุคอขวด และมั่นใจในความน่าเชื่อถือด้วยการตรวจสอบโครงสร้างพื้นฐานแบบเรียลไทม์"
|
||||
},
|
||||
"header": {
|
||||
"title": "ตัวตรวจสอบโครงสร้างพื้นฐาน",
|
||||
"description": "ติดตามประสิทธิภาพเซิร์ฟเวอร์ ระบุคอขวด และมั่นใจในความน่าเชื่อถือด้วยการตรวจสอบโครงสร้างพื้นฐานแบบเรียลไทม์"
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "ยังไม่มีบันทึก",
|
||||
"description": "กิจกรรมเซิร์ฟเวอร์ คำเตือน และข้อผิดพลาดจะปรากฏที่นี่ในขณะที่ Checkmate ทำงาน"
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "วินิจฉัย",
|
||||
"logs": "Logs เซิร์ฟเวอร์",
|
||||
@@ -788,7 +835,9 @@
|
||||
"label": "ระดับบันทึก"
|
||||
},
|
||||
"jobQueue": "คิวงาน",
|
||||
"jobQueueExplainer": "<highlight>แถวที่ไฮไลต์</highlight> คืองานที่กำลังถูกประมวลผลโดยเวิร์กเกอร์อยู่ในขณะนี้",
|
||||
"failedJobs": "งานที่ล้มเหลว",
|
||||
"failedJobsExplainer": "ความล้มเหลวล่าสุดตามมอนิเตอร์ — เวลาที่ล้มเหลวล่าสุด จำนวนครั้งที่ล้มเหลว และเหตุผล",
|
||||
"noLogs": "ไม่พบบันทึก",
|
||||
"metrics": {
|
||||
"jobs": "งาน",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% ของ 1 วินาทีที่ CPU ใช้",
|
||||
"total": "ทั้งหมด",
|
||||
"used": "ใช้แล้ว"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "สถิติรันไทม์",
|
||||
"description": "ภาพรวมของโปรเซส Node.js และเครื่องโฮสต์ อัปเดตทุก 5 วินาที"
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "หน่วยความจำและ CPU",
|
||||
"description": "กระบวนการใช้หน่วยความจำที่จัดสรรและ CPU ของโฮสต์อย่างไร"
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "ล้มเหลวล่าสุดเมื่อ",
|
||||
"failReason": "สาเหตุที่ล้มเหลว"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "ไม่มีงานในคิว",
|
||||
"description": "การตรวจสอบตัวตรวจสอบที่กำหนดเวลาหรือกำลังทำงานจะปรากฏที่นี่ คิวที่ว่างหมายความว่าทุกอย่างเป็นปัจจุบัน"
|
||||
},
|
||||
"header": {
|
||||
"title": "บันทึกและคิว",
|
||||
"description": "ตรวจสอบบันทึกเซิร์ฟเวอร์ คิวงานตัวตรวจสอบ และการวินิจฉัยรันไทม์ในที่เดียว"
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "สร้างช่วงเวลาบำรุงรักษา!",
|
||||
"checks": "Mark your maintenance periods,Eliminate any misunderstandings,Stop sending alerts in maintenance windows",
|
||||
"title": "ช่วงเวลาบำรุงรักษาใช้เพื่อ:"
|
||||
"title": "ไม่มีช่วงเวลาบำรุงรักษาที่กำหนด",
|
||||
"description": "กำหนดเวลาหยุดทำงานเพื่อระงับการแจ้งเตือน และให้ทีมและผู้ใช้รู้ถึงสิ่งที่จะเกิดขึ้น"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "ช่วงเวลาบำรุงรักษา",
|
||||
"description": "กำหนดเวลาหยุดทำงานเพื่อระงับการแจ้งเตือน และให้ทีมและผู้ใช้รู้ถึงสิ่งที่จะเกิดขึ้น"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "สร้างช่องทาง",
|
||||
"checks": "Alert teams about downtime or performance issues,Let engineers know when incidents happen,Keep administrators informed of system changes",
|
||||
"title": "ช่องทางการแจ้งเตือนใช้เพื่อ:"
|
||||
"title": "ยังไม่มีช่องทางการแจ้งเตือน",
|
||||
"description": "เชื่อมต่อ Slack, Discord, อีเมล, webhooks และอื่น ๆ เพื่อให้คนที่ถูกต้องรู้เกี่ยวกับเหตุการณ์ทันทีที่เกิดขึ้น"
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "Chat ID",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "การตั้งค่า Pushover",
|
||||
"description": "ป้อนโทเค็นแอปและคีย์ผู้ใช้ Pushover ของคุณ",
|
||||
"optionAppToken": "โทเค็นแอป",
|
||||
"placeholderAppToken": "ป้อนโทเค็นแอป",
|
||||
"optionUserKey": "คีย์ผู้ใช้",
|
||||
"placeholderUserKey": "ป้อนคีย์ผู้ใช้"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "การตั้งค่า Twilio",
|
||||
"description": "ป้อนข้อมูลรับรองบัญชี Twilio เพื่อส่ง SMS",
|
||||
"optionAccountSid": "SID บัญชี",
|
||||
"placeholderAccountSid": "ป้อน SID บัญชี",
|
||||
"optionAuthToken": "โทเค็นการรับรอง",
|
||||
"placeholderAuthToken": "ป้อนโทเค็นการรับรอง",
|
||||
"optionFromNumber": "หมายเลขผู้ส่ง",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "หมายเลขผู้รับ",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "ปลายทาง"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "การแจ้งเตือน",
|
||||
"description": "เชื่อมต่อ Slack, Discord, อีเมล, webhooks และอื่น ๆ เพื่อให้คนที่ถูกต้องรู้เกี่ยวกับเหตุการณ์ทันทีที่เกิดขึ้น"
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "สร้างมอนิเตอร์!",
|
||||
"checks": "Report on the user experience of a page,Help analyze webpage speed,Give suggestions on how the page can be improved",
|
||||
"title": "มอนิเตอร์ PageSpeed ใช้เพื่อ:"
|
||||
"title": "ยังไม่มีตัวตรวจสอบ PageSpeed",
|
||||
"description": "ติดตาม Core Web Vitals และคะแนน Lighthouse เพื่อจับความถดถอยก่อนที่ผู้ใช้จะสังเกตเห็น"
|
||||
},
|
||||
"header": {
|
||||
"title": "ตัวตรวจสอบ PageSpeed",
|
||||
"description": "ติดตาม Core Web Vitals และคะแนน Lighthouse เพื่อจับความถดถอยก่อนที่ผู้ใช้จะสังเกตเห็น"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "กรุณาแก้ไขข้อผิดพลาดการตรวจสอบต่อไปนี้:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "การตั้งค่า",
|
||||
"description": "กำหนดค่า SMTP, การผสานรวม, การเก็บรักษา และพฤติกรรมแอปทั่วโลก"
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "ลบหน้าสถานะสำเร็จ",
|
||||
"fallback": {
|
||||
"title": "หน้าสถานะใช้เพื่อ:",
|
||||
"checks": "Communicate system status to users and stakeholders,Display real-time uptime information publicly,Build trust with transparent service monitoring,Reduce support requests during incidents",
|
||||
"actionButton": "สร้างหน้าสถานะ!"
|
||||
"title": "ยังไม่มีหน้าสถานะ",
|
||||
"actionButton": "สร้างหน้าสถานะ!",
|
||||
"description": "เผยแพร่หน้าสาธารณะที่แสดง uptime แบบเรียลไทม์และประวัติเหตุการณ์ให้กับลูกค้าและผู้มีส่วนได้ส่วนเสีย"
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "แผนที่ความร้อน",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "ระบบทั้งหมดล่ม",
|
||||
"allUp": "ระบบทั้งหมดทำงานปกติ",
|
||||
"degraded": "บางระบบกำลังประสบปัญหา",
|
||||
"unknown": "ไม่สามารถระบุสถานะระบบได้"
|
||||
"unknown": "ไม่สามารถระบุสถานะระบบได้",
|
||||
"allBreached": "ทุกระบบเกินขีดจำกัด",
|
||||
"allMaintenance": "ทุกระบบอยู่ระหว่างการบำรุงรักษา",
|
||||
"allPaused": "ทุกระบบถูกหยุดชั่วคราว",
|
||||
"allInitializing": "ทุกระบบกำลังเริ่มต้น",
|
||||
"breachedAndDown": "บางระบบเกินขีดจำกัดและขัดข้อง",
|
||||
"breached": "บางระบบเกินขีดจำกัด",
|
||||
"maintenanceAndDown": "บางระบบขัดข้องระหว่างการบำรุงรักษา",
|
||||
"maintenance": "บางระบบอยู่ระหว่างการบำรุงรักษา",
|
||||
"partiallyPaused": "บางระบบถูกหยุดชั่วคราว",
|
||||
"initializing": "บางระบบกำลังเริ่มต้น",
|
||||
"noMonitors": "ยังไม่มีการกำหนดค่ามอนิเตอร์"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "หน้าสถานะ",
|
||||
"description": "เผยแพร่หน้าสาธารณะที่แสดง uptime แบบเรียลไทม์และประวัติเหตุการณ์ให้กับลูกค้าและผู้มีส่วนได้ส่วนเสีย"
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "สร้างมอนิเตอร์!",
|
||||
"checks": "Check if websites or servers are online & responsive,Alert teams about downtime or performance issues,Monitor HTTP endpoints, pings, containers & ports,Track historical uptime and reliability trends",
|
||||
"title": "มอนิเตอร์อัปไทม์ใช้เพื่อ:"
|
||||
"title": "ยังไม่มีตัวตรวจสอบ uptime",
|
||||
"description": "ติดตาม HTTP endpoints, ping, คอนเทนเนอร์ และพอร์ต — รับการแจ้งเตือนทันทีที่บางอย่างล่ม"
|
||||
},
|
||||
"header": {
|
||||
"title": "ตัวตรวจสอบ uptime",
|
||||
"description": "ติดตาม HTTP endpoints, ping, คอนเทนเนอร์ และพอร์ต — รับการแจ้งเตือนทันทีที่บางอย่างล่ม"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+143
-21
@@ -35,7 +35,7 @@
|
||||
"sendInvite": "Davet gönder",
|
||||
"test": "Test",
|
||||
"testNotifications": "Bildirimleri test et",
|
||||
"toggleTheme": "",
|
||||
"toggleTheme": "Açık / koyu temayı değiştir",
|
||||
"flushQueue": "Kuyruğu temizle",
|
||||
"notFound": "Ana panele git",
|
||||
"resetPassword": "Parolayı sıfırla",
|
||||
@@ -86,7 +86,7 @@
|
||||
"name": {
|
||||
"option": {
|
||||
"firstName": {
|
||||
"label": "",
|
||||
"label": "Ad",
|
||||
"placeholder": "Jordan"
|
||||
},
|
||||
"lastName": {
|
||||
@@ -155,13 +155,13 @@
|
||||
"serverUnreachable": "Sunucuya ulaşılamıyor",
|
||||
"retry": "Tekrar dene",
|
||||
"retrying": "Yeniden deneniyor...",
|
||||
"reconnected": ""
|
||||
"reconnected": "Bağlantı yeniden kuruldu"
|
||||
},
|
||||
"sidebar": {
|
||||
"menu": {
|
||||
"uptime": "",
|
||||
"uptime": "Çalışma süresi",
|
||||
"pagespeed": "Sayfa hızı",
|
||||
"infrastructure": "",
|
||||
"infrastructure": "Altyapı",
|
||||
"notifications": "Bildirimler",
|
||||
"checks": "Kontroller",
|
||||
"incidents": "Olaylar",
|
||||
@@ -199,6 +199,14 @@
|
||||
"starPrompt": {
|
||||
"title": "Checkmate'e yıldız verin",
|
||||
"description": "En son sürümleri görün ve GitHub'da topluluğun büyümesine katkıda bulunun"
|
||||
},
|
||||
"pageHeader": {
|
||||
"links": {
|
||||
"support": "Destek",
|
||||
"discussions": "Tartışmalar",
|
||||
"docs": "Dokümantasyon",
|
||||
"changelog": "Değişiklik günlüğü"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
@@ -278,10 +286,23 @@
|
||||
"placeholder": "Bir rol seçin"
|
||||
},
|
||||
"linkLabel": "Davet bağlantısı"
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Henüz takım üyesi yok",
|
||||
"description": "Ekip arkadaşlarınızı e-posta ile davet edin veya doğrudan ekleyin. Katıldıklarında, rolleriyle birlikte burada görünecekler."
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Hesap",
|
||||
"description": "Profilinizi, parolanızı, ekibinizi ve çalışma alanı tercihlerinizi yönetin."
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"brandPanel": {
|
||||
"eyebrow": "Açık kaynaklı altyapı izleme",
|
||||
"tagline": "Sunucularınızın her hareketini izleyin.",
|
||||
"description": "Sistemlerinizin çalışma süresini, yanıt hızını ve yaşanan kesintileri tek bir panelden anlık takip edin. Kendi sunucunuzda çalışır, verileriniz sizde kalır."
|
||||
},
|
||||
"common": {
|
||||
"passwordRules": {
|
||||
"length": {
|
||||
@@ -343,7 +364,8 @@
|
||||
"register": {
|
||||
"title": "Checkmate'e tekrar hoş geldiniz!",
|
||||
"subtitle": "Başlamak için kaydolun",
|
||||
"submit": "Kaydol"
|
||||
"submit": "Kaydol",
|
||||
"setupNotice": "Bu sayfa yalnızca ilk kurulum sırasında kullanılabilir. Süper yönetici kaydedildikten sonra, ek kullanıcılar takım ayarlarından davet edilebilir."
|
||||
},
|
||||
"forgotPassword": {
|
||||
"title": "Parolanızı mı unuttunuz?",
|
||||
@@ -378,6 +400,14 @@
|
||||
"statusCode": "Durum kodu",
|
||||
"location": "Konum"
|
||||
}
|
||||
},
|
||||
"fallback": {
|
||||
"title": "Henüz kontrol yok",
|
||||
"description": "Bir izleyici oluşturduğunuzda, her durum kontrolü ve yanıt süresi burada bir kontrol olarak görünecek."
|
||||
},
|
||||
"header": {
|
||||
"title": "Kontroller",
|
||||
"description": "Checkmate'in izleyicilerinize karşı çalıştırdığı her sondaj, durum kodu ve yanıt süresiyle birlikte burada görünür."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
@@ -397,7 +427,8 @@
|
||||
"activeFor": "Aktif süresi",
|
||||
"certificateExpiry": "Sertifika bitiş tarihi",
|
||||
"lastCheck": "Son kontrol",
|
||||
"lastResponseTime": "Son yanıt süresi"
|
||||
"lastResponseTime": "Son yanıt süresi",
|
||||
"serviceIsDown": "Servis çalışmıyor"
|
||||
},
|
||||
"status": {
|
||||
"down": "çevrimdışı",
|
||||
@@ -640,6 +671,10 @@
|
||||
}
|
||||
},
|
||||
"incidents": {
|
||||
"fallback": {
|
||||
"title": "Olay yok — tüm sistemler sağlıklı",
|
||||
"description": "Bir izleyici devre dışı kaldığında veya kurtarıldığında, olay zamanlama, izleyici detayları ve çözüm geçmişiyle birlikte burada görünecek."
|
||||
},
|
||||
"dialog": {
|
||||
"resolveIncident": {
|
||||
"title": "Olayı çöz",
|
||||
@@ -720,6 +755,10 @@
|
||||
"active": "Aktif",
|
||||
"resolved": "Çözüldü"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Olaylar",
|
||||
"description": "Bir izleyici devre dışı kaldığında veya kurtarıldığında, olaylar zamanlama, izleyici detayları ve çözüm geçmişiyle birlikte burada görünür."
|
||||
}
|
||||
},
|
||||
"infrastructure": {
|
||||
@@ -774,11 +813,19 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Monitör oluşturun!",
|
||||
"checks": "Sunucularınızın performansını takip edin,Darboğazları belirleyin ve kullanımı optimize edin,Gerçek zamanlı izleme ile güvenilirliği sağlayın",
|
||||
"title": "Bir altyapı monitörü şunlar için kullanılır:"
|
||||
"title": "Henüz altyapı izleyicisi yok",
|
||||
"description": "Sunucu performansını izleyin, darboğazları belirleyin ve gerçek zamanlı altyapı izleme ile güvenilirliği sağlayın."
|
||||
},
|
||||
"header": {
|
||||
"title": "Altyapı izleyicileri",
|
||||
"description": "Sunucu performansını izleyin, darboğazları belirleyin ve gerçek zamanlı altyapı izleme ile güvenilirliği sağlayın."
|
||||
}
|
||||
},
|
||||
"logs": {
|
||||
"fallback": {
|
||||
"title": "Henüz günlük yok",
|
||||
"description": "Sunucu etkinliği, uyarılar ve hatalar Checkmate çalıştıkça burada görünecek."
|
||||
},
|
||||
"tabs": {
|
||||
"diagnostics": "Teşhis",
|
||||
"logs": "Sunucu günlükleri",
|
||||
@@ -788,7 +835,9 @@
|
||||
"label": "Günlük seviyesi"
|
||||
},
|
||||
"jobQueue": "İş kuyruğu",
|
||||
"jobQueueExplainer": "<highlight>Vurgulanan satırlar</highlight> şu anda bir işçi tarafından işlenmekte olan işlerdir.",
|
||||
"failedJobs": "Başarısız işler",
|
||||
"failedJobsExplainer": "Monitöre göre son başarısızlıklar — son başarısızlık zamanı, başarısızlık sayısı ve nedeni.",
|
||||
"noLogs": "Günlük bulunamadı",
|
||||
"metrics": {
|
||||
"jobs": "İşler",
|
||||
@@ -815,6 +864,16 @@
|
||||
"usedSPercentage": "% CPU tarafından kullanılan (1s)",
|
||||
"total": "Toplam",
|
||||
"used": "Kullanılan"
|
||||
},
|
||||
"sections": {
|
||||
"runtimeStats": {
|
||||
"title": "Çalışma istatistikleri",
|
||||
"description": "Node.js süreci ve ana makinenin anlık görüntüsü. 5 saniyede bir güncellenir."
|
||||
},
|
||||
"memoryCpu": {
|
||||
"title": "Bellek ve CPU",
|
||||
"description": "Sürecin ayrılmış belleğini ve ana makinenin CPU'sunu nasıl kullandığı."
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
@@ -833,13 +892,21 @@
|
||||
"lastFailedAt": "Son başarısızlık zamanı",
|
||||
"failReason": "Başarısızlık nedeni"
|
||||
}
|
||||
},
|
||||
"queueFallback": {
|
||||
"title": "Kuyrukta iş yok",
|
||||
"description": "Zamanlanmış veya çalışan izleyici kontrolleri burada görünür. Boş bir kuyruk her şeyin güncel olduğu anlamına gelir."
|
||||
},
|
||||
"header": {
|
||||
"title": "Günlükler ve kuyruk",
|
||||
"description": "Sunucu günlüklerini, izleyici iş kuyruğunu ve çalışma zamanı tanılarını tek bir yerde inceleyin."
|
||||
}
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"fallback": {
|
||||
"actionButton": "Bakım penceresi oluşturun!",
|
||||
"checks": "Bakım dönemlerinizi işaretleyin,Yanlış anlamaları ortadan kaldırın,Bakım pencerelerinde uyarı göndermeyi durdurun",
|
||||
"title": "Bakım penceresi şunlar için kullanılır:"
|
||||
"title": "Planlanmış bakım penceresi yok",
|
||||
"description": "Planlı kesintileri zamanlayın; uyarılar bastırılsın, ekibiniz ve kullanıcılarınız ne bekleyeceklerini bilsin."
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -891,13 +958,17 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Bakım pencereleri",
|
||||
"description": "Planlı kesintileri zamanlayın; uyarılar bastırılsın, ekibiniz ve kullanıcılarınız ne bekleyeceklerini bilsin."
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"fallback": {
|
||||
"actionButton": "Kanal oluştur",
|
||||
"checks": "Kesinti veya performans sorunları hakkında ekipleri uyarın,Olaylar meydana geldiğinde mühendisleri bilgilendirin,Yöneticileri sistem değişiklikleri hakkında haberdar edin",
|
||||
"title": "Bildirim kanalları şunlar için kullanılır:"
|
||||
"title": "Henüz bildirim kanalı yok",
|
||||
"description": "Slack, Discord, e-posta, webhook ve daha fazlasını bağlayın — olaylar olur olmaz doğru kişilere haber verilir."
|
||||
},
|
||||
"form": {
|
||||
"accessToken": {
|
||||
@@ -947,12 +1018,36 @@
|
||||
"placeholderBotToken": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
||||
"optionChatId": "Sohbet ID",
|
||||
"placeholderChatId": "-1001234567890"
|
||||
},
|
||||
"pushover": {
|
||||
"title": "Pushover yapılandırması",
|
||||
"description": "Pushover uygulama belirtecinizi ve kullanıcı anahtarınızı girin.",
|
||||
"optionAppToken": "Uygulama belirteci",
|
||||
"placeholderAppToken": "Uygulama belirtecini girin",
|
||||
"optionUserKey": "Kullanıcı anahtarı",
|
||||
"placeholderUserKey": "Kullanıcı anahtarını girin"
|
||||
},
|
||||
"twilio": {
|
||||
"title": "Twilio yapılandırması",
|
||||
"description": "SMS göndermek için Twilio hesap kimlik bilgilerinizi girin.",
|
||||
"optionAccountSid": "Hesap SID",
|
||||
"placeholderAccountSid": "Hesap SID girin",
|
||||
"optionAuthToken": "Kimlik doğrulama belirteci",
|
||||
"placeholderAuthToken": "Kimlik doğrulama belirtecini girin",
|
||||
"optionFromNumber": "Gönderen numara",
|
||||
"placeholderFromNumber": "+1234567890",
|
||||
"optionToNumber": "Alıcı numara",
|
||||
"placeholderToNumber": "+1234567890"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
"destination": "Hedef"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Bildirimler",
|
||||
"description": "Slack, Discord, e-posta, webhook ve daha fazlasını bağlayın — olaylar olur olmaz doğru kişilere haber verilir."
|
||||
}
|
||||
},
|
||||
"pageSpeed": {
|
||||
@@ -979,8 +1074,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Monitör oluşturun!",
|
||||
"checks": "Bir sayfanın kullanıcı deneyimini raporlayın,Web sayfası hızını analiz etmeye yardımcı olun,Sayfanın nasıl iyileştirilebileceğine dair öneriler sunun",
|
||||
"title": "Bir PageSpeed monitörü şunlar için kullanılır:"
|
||||
"title": "Henüz PageSpeed izleyicisi yok",
|
||||
"description": "Core Web Vitals ve Lighthouse puanlarını zaman içinde izleyerek kullanıcılarınız fark etmeden gerilemeleri yakalayın."
|
||||
},
|
||||
"header": {
|
||||
"title": "PageSpeed izleyicileri",
|
||||
"description": "Core Web Vitals ve Lighthouse puanlarını zaman içinde izleyerek kullanıcılarınız fark etmeden gerilemeleri yakalayın."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -1158,14 +1257,18 @@
|
||||
"validation": {
|
||||
"errorMessage": "Lütfen aşağıdaki doğrulama hatalarını düzeltin:"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Ayarlar",
|
||||
"description": "SMTP, entegrasyonlar, saklama ve genel uygulama davranışını yapılandırın."
|
||||
}
|
||||
},
|
||||
"statusPages": {
|
||||
"deleteSuccess": "Durum sayfası başarıyla silindi",
|
||||
"fallback": {
|
||||
"title": "Bir durum sayfası şunlar için kullanılır:",
|
||||
"checks": "Kullanıcılara ve paydaşlara sistem durumunu iletin,Gerçek zamanlı çalışma süresi bilgilerini herkese açık olarak görüntüleyin,Şeffaf hizmet izleme ile güven oluşturun,Olaylar sırasında destek taleplerini azaltın",
|
||||
"actionButton": "Durum sayfası oluşturun!"
|
||||
"title": "Henüz durum sayfası yok",
|
||||
"actionButton": "Durum sayfası oluşturun!",
|
||||
"description": "Müşterilerinize ve paydaşlarınıza gerçek zamanlı çalışma süresi ve olay geçmişini gösteren herkese açık bir sayfa yayınlayın."
|
||||
},
|
||||
"monitorsList": {
|
||||
"chartTypeHeatmap": "Isı haritası",
|
||||
@@ -1190,7 +1293,18 @@
|
||||
"allDown": "Tüm sistemler çevrimdışı",
|
||||
"allUp": "Tüm sistemler çalışıyor",
|
||||
"degraded": "Bazı sistemlerde sorun yaşanıyor",
|
||||
"unknown": "Sistem durumu belirlenemiyor"
|
||||
"unknown": "Sistem durumu belirlenemiyor",
|
||||
"allBreached": "Tüm sistemler eşik değerlerini aştı",
|
||||
"allMaintenance": "Tüm sistemler bakımda",
|
||||
"allPaused": "Tüm sistemler duraklatıldı",
|
||||
"allInitializing": "Tüm sistemler başlatılıyor",
|
||||
"breachedAndDown": "Bazı sistemler eşik değerlerini aştı ve çalışmıyor",
|
||||
"breached": "Bazı sistemler eşik değerlerini aştı",
|
||||
"maintenanceAndDown": "Bazı sistemler bakım sırasında çalışmıyor",
|
||||
"maintenance": "Bazı sistemler bakımda",
|
||||
"partiallyPaused": "Bazı sistemler duraklatıldı",
|
||||
"initializing": "Bazı sistemler başlatılıyor",
|
||||
"noMonitors": "Hiç monitör yapılandırılmadı"
|
||||
},
|
||||
"table": {
|
||||
"headers": {
|
||||
@@ -1282,6 +1396,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Durum sayfaları",
|
||||
"description": "Müşterilerinize ve paydaşlarınıza gerçek zamanlı çalışma süresi ve olay geçmişini gösteren herkese açık sayfalar yayınlayın."
|
||||
}
|
||||
},
|
||||
"uptime": {
|
||||
@@ -1297,8 +1415,12 @@
|
||||
},
|
||||
"fallback": {
|
||||
"actionButton": "Monitör oluşturun!",
|
||||
"checks": "Web sitelerinin veya sunucuların çevrimiçi ve yanıt verip vermediğini kontrol edin,Kesinti veya performans sorunları hakkında ekipleri uyarın,HTTP uç noktalarını, ping'leri, container'ları ve portları izleyin,Geçmiş çalışma süresi ve güvenilirlik trendlerini takip edin",
|
||||
"title": "Bir çalışma süresi monitörü şunlar için kullanılır:"
|
||||
"title": "Henüz çalışma süresi izleyicisi yok",
|
||||
"description": "HTTP uç noktalarını, ping'leri, konteynerleri ve portları izleyin — bir şey kapandığında anında uyarı alın."
|
||||
},
|
||||
"header": {
|
||||
"title": "Çalışma süresi izleyicileri",
|
||||
"description": "HTTP uç noktalarını, ping'leri, konteynerleri ve portları izleyin — bir şey kapandığında anında uyarı alın."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loaded 100 of 268 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user