diff --git a/client/.eslintrc.cjs b/client/.eslintrc.cjs index 7d6029d4b..86d523a6f 100644 --- a/client/.eslintrc.cjs +++ b/client/.eslintrc.cjs @@ -16,4 +16,8 @@ module.exports = { "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], "react/no-unescaped-entities": "off", }, + globals: { + __APP_VERSION__: "readonly", + process: "readonly", + }, }; diff --git a/client/src/Components/MonitorCreateHeader/index.jsx b/client/src/Components/MonitorCreateHeader/index.jsx index f2b6bbce4..b3b50681c 100644 --- a/client/src/Components/MonitorCreateHeader/index.jsx +++ b/client/src/Components/MonitorCreateHeader/index.jsx @@ -29,7 +29,7 @@ const CreateMonitorHeader = ({ isAdmin, label, isLoading = true, path, bulkPath > {label || t("createNew")} - {bulkPath && } + {/* {bulkPath && } */} ); }; diff --git a/client/src/Components/TabPanels/Account/TeamPanel.jsx b/client/src/Components/TabPanels/Account/TeamPanel.jsx index 341f84ba7..45578cc6c 100644 --- a/client/src/Components/TabPanels/Account/TeamPanel.jsx +++ b/client/src/Components/TabPanels/Account/TeamPanel.jsx @@ -168,7 +168,7 @@ const TeamPanel = () => { }); } catch (error) { createToast({ - body: error.message || "Unknown error.", + body: error?.response?.data?.msg || error.message || "Unknown error.", }); } finally { setIsSendingInvite(false); @@ -268,7 +268,7 @@ const TeamPanel = () => { value={toInvite.email} onChange={handleChange} error={errors.email ? true : false} - helperText={errors.email} + helperText={t(errors.email)} /> { component="h1" variant="h2" > - {t("settingsAppearance")} + {t("settingsPage.uiSettings.title")} + + + {t("settingsPage.uiSettings.description")} - {t("settingsAppearanceDescription")} diff --git a/client/src/Pages/Settings/index.jsx b/client/src/Pages/Settings/index.jsx index 0cd954e52..dae6bd680 100644 --- a/client/src/Pages/Settings/index.jsx +++ b/client/src/Pages/Settings/index.jsx @@ -157,7 +157,7 @@ const Settings = () => { return ( - Settings + {t("settingsPage.title")} { sx={{ px: theme.spacing(12), py: theme.spacing(8) }} onClick={handleSave} > - {t("settingsSave")} + {t("settingsPage.saveButtonLabel")} diff --git a/client/src/Pages/Uptime/Details/index.jsx b/client/src/Pages/Uptime/Details/index.jsx index 5f36ee7e5..c72a5756f 100644 --- a/client/src/Pages/Uptime/Details/index.jsx +++ b/client/src/Pages/Uptime/Details/index.jsx @@ -111,6 +111,7 @@ const UptimeDetails = () => { return ( + { monitor={monitor} triggerUpdate={triggerUpdate} /> + + + {t("distributedUptimeDetailsNoMonitorHistory")} diff --git a/client/src/Utils/Theme/constants.js b/client/src/Utils/Theme/constants.js index 48dcdfd85..1b905bb79 100644 --- a/client/src/Utils/Theme/constants.js +++ b/client/src/Utils/Theme/constants.js @@ -85,6 +85,7 @@ const semanticColors = { const newColors = { offWhite: "#FEFEFE", offBlack: "#131315", + gray0: "#FDFDFD", gray10: "#F4F4FF", gray100: "#F3F3F3", gray200: "#EFEFEF", @@ -178,7 +179,7 @@ const newSemanticColors = { }, primaryBackground: { main: { - light: newColors.gray10, + light: newColors.gray0, dark: "#000000", }, }, diff --git a/client/src/Utils/Theme/globalTheme.js b/client/src/Utils/Theme/globalTheme.js index ae014432d..eb827a907 100644 --- a/client/src/Utils/Theme/globalTheme.js +++ b/client/src/Utils/Theme/globalTheme.js @@ -36,6 +36,11 @@ const baseTheme = (palette) => ({ color: palette.primary.contrastTextTertiary, fontWeight: 400, }, + label: { + fontSize: "var(--env-var-font-size-medium)", + color: palette.primary.contrastTextSecondary, + fontWeight: 500, + }, }, /* TODO change to 4 */ spacing: 2, diff --git a/client/src/Utils/i18n.js b/client/src/Utils/i18n.js index 4468917a2..030091d48 100644 --- a/client/src/Utils/i18n.js +++ b/client/src/Utils/i18n.js @@ -24,6 +24,7 @@ i18n.use(initReactI18next).init({ interpolation: { escapeValue: false, }, + returnEmptyString: false, }); export default i18n; diff --git a/client/src/locales/ar.json b/client/src/locales/ar.json index 06789abb0..81a2bb05f 100644 --- a/client/src/locales/ar.json +++ b/client/src/locales/ar.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "", "settingsDemoMonitors": "", "settingsDemoMonitorsDescription": "", - "settingsAddDemoMonitors": "", "settingsAddDemoMonitorsButton": "", - "settingsRemoveAllMonitors": "", "settingsRemoveAllMonitorsButton": "", "settingsRemoveAllMonitorsDialogTitle": "", "settingsRemoveAllMonitorsDialogConfirm": "", diff --git a/client/src/locales/cs.json b/client/src/locales/cs.json index 110d9a508..4e1170ee7 100644 --- a/client/src/locales/cs.json +++ b/client/src/locales/cs.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "", "settingsDemoMonitors": "", "settingsDemoMonitorsDescription": "", - "settingsAddDemoMonitors": "", "settingsAddDemoMonitorsButton": "", - "settingsRemoveAllMonitors": "", "settingsRemoveAllMonitorsButton": "", "settingsRemoveAllMonitorsDialogTitle": "", "settingsRemoveAllMonitorsDialogConfirm": "", diff --git a/client/src/locales/de.json b/client/src/locales/de.json index 5561188a0..e33adab68 100644 --- a/client/src/locales/de.json +++ b/client/src/locales/de.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "", "settingsDemoMonitors": "", "settingsDemoMonitorsDescription": "", - "settingsAddDemoMonitors": "", "settingsAddDemoMonitorsButton": "", - "settingsRemoveAllMonitors": "", "settingsRemoveAllMonitorsButton": "", "settingsRemoveAllMonitorsDialogTitle": "", "settingsRemoveAllMonitorsDialogConfirm": "", diff --git a/client/src/locales/en.json b/client/src/locales/en.json index b57bb1e15..b3cc23dca 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -1,594 +1,29 @@ { - "submit": "Submit", - "title": "Title", - "distributedStatusHeaderText": "Real-time, real-device coverage", - "distributedStatusSubHeaderText": "Powered by millions devices worldwide, view a system performance by global region, country or city", - "settingsGeneralSettings": "General settings", - "settingsDisplayTimezone": "Display timezone", - "settingsDisplayTimezoneDescription": "Select the timezone used to display dates and times throughout the application.", - "settingsAppearance": "Appearance", - "settingsAppearanceDescription": "Switch between light and dark mode, or change user interface language", - "settingsThemeMode": "Theme Mode", - "settingsLanguage": "Language", - "settingsEnabled": "Enabled", - "settingsDisabled": "Disabled", - "settingsHistoryAndMonitoring": "History of monitoring", - "settingsHistoryAndMonitoringDescription": "Define how long you want to retain historical data. You can also clear all existing data.", - "settingsTTLLabel": "The days you want to keep monitoring history.", - "settingsTTLOptionalLabel": "0 for infinite", - "settingsClearAllStats": "Clear all stats. This is irreversible.", - "settingsClearAllStatsButton": "Clear all stats", - "settingsClearAllStatsDialogTitle": "Do you want to clear all stats?", - "settingsClearAllStatsDialogDescription": "Once removed, the monitoring history and stats cannot be retrieved.", - "settingsClearAllStatsDialogConfirm": "Yes, clear all stats", - "settingsDemoMonitors": "Demo monitors", - "settingsDemoMonitorsDescription": "Add sample monitors for demonstration purposes.", - "settingsAddDemoMonitors": "Adding demo monitors", - "settingsAddDemoMonitorsButton": "Add demo monitors", - "settingsRemoveAllMonitors": "Removing all monitors", - "settingsRemoveAllMonitorsButton": "Remove all monitors", - "settingsRemoveAllMonitorsDialogTitle": "Do you want to remove all monitors?", - "settingsRemoveAllMonitorsDialogConfirm": "Yes, remove all monitors", - "settingsAbout": "About", - "settingsDevelopedBy": "Developed by Bluewave Labs.", - "settingsSave": "Save", - "settingsSuccessSaved": "Settings saved successfully", - "settingsFailedToSave": "Failed to save settings", - "settingsStatsCleared": "Stats cleared successfully", - "settingsFailedToClearStats": "Failed to clear stats", - "settingsDemoMonitorsAdded": "Successfully added demo monitors", - "settingsFailedToAddDemoMonitors": "Failed to add demo monitors", - "settingsMonitorsDeleted": "Successfully deleted all monitors", - "settingsFailedToDeleteMonitors": "Failed to delete all monitors", - "starPromptTitle": "Star Checkmate", - "starPromptDescription": "See the latest releases and help grow the community on GitHub", - "https": "HTTPS", - "http": "HTTP", - "monitor": "monitor", - "aboutus": "About Us", - "now": "Now", - "delete": "Delete", - "configure": "Configure", - "responseTime": "Response time", - "ms": "ms", - "bar": "Bar", - "area": "Area", - "country": "COUNTRY", - "city": "CITY", - "response": "RESPONSE", - "monitorStatusUp": "Monitor {name} ({url}) is now UP and responding", - "monitorStatusDown": "Monitor {name} ({url}) is DOWN and not responding", - "webhookSendSuccess": "Webhook notification sent successfully", - "webhookSendError": "Error sending webhook notification to {platform}", - "webhookUnsupportedPlatform": "Unsupported platform: {platform}", - "distributedRightCategoryTitle": "Monitor", - "distributedStatusServerMonitors": "Server Monitors", - "distributedStatusServerMonitorsDescription": "Monitor status of related servers", - "distributedUptimeCreateSelectURL": "Here you can select the URL of the host, together with the type of monitor.", - "distributedUptimeCreateChecks": "Checks to perform", - "distributedUptimeCreateChecksDescription": "You can always add or remove checks after adding your site.", - "distributedUptimeCreateIncidentNotification": "Incident notifications", - "distributedUptimeCreateIncidentDescription": "When there is an incident, notify users.", - "distributedUptimeCreateAdvancedSettings": "Advanced settings", - "distributedUptimeDetailsNoMonitorHistory": "There is no check history for this monitor yet.", - "distributedUptimeDetailsStatusHeaderUptime": "Uptime:", - "distributedUptimeDetailsStatusHeaderLastUpdate": "Last updated", - "notifications": { - "enableNotifications": "Enable {{platform}} notifications", - "testNotification": "Test notification", - "addOrEditNotifications": "Add or edit notifications", - "slack": { - "label": "Slack", - "description": "To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.", - "webhookLabel": "Webhook URL", - "webhookPlaceholder": "https://hooks.slack.com/services/...", - "webhookRequired": "Slack webhook URL is required" - }, - "discord": { - "label": "Discord", - "description": "To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord's incoming Webhooks feature.", - "webhookLabel": "Discord Webhook URL", - "webhookPlaceholder": "https://discord.com/api/webhooks/...", - "webhookRequired": "Discord webhook URL is required" - }, - "telegram": { - "label": "Telegram", - "description": "To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.", - "tokenLabel": "Your bot token", - "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", - "chatIdLabel": "Your Chat ID", - "chatIdPlaceholder": "-1001234567890", - "fieldsRequired": "Telegram token and chat ID are required" - }, - "webhook": { - "label": "Webhooks", - "description": "You can set up a custom webhook to receive notifications when incidents occur.", - "urlLabel": "Webhook URL", - "urlPlaceholder": "https://your-server.com/webhook", - "urlRequired": "Webhook URL is required" - }, - "testNotificationDevelop": "Test notification 2", - "integrationButton": "Notification Integration", - "testSuccess": "Test notification sent successfully!", - "testFailed": "Failed to send test notification", - "unsupportedType": "Unsupported notification type", - "networkError": "Network error occurred", - "fallback": { - "title": "notification channel", - "checks": [ - "Alert teams about downtime or performance issues", - "Let engineers know when incidents happen", - "Keep administrators informed of system changes" - ] - }, - "createButton": "Create notification channel", - "createTitle": "Notification channel", - "create": { - "success": "Notification created successfully", - "failed": "Failed to create notification" - }, - "fetch": { - "success": "Notifications fetched successfully", - "failed": "Failed to fetch notifications" - }, - "delete": { - "success": "Notification deleted successfully", - "failed": "Failed to delete notification" - }, - "edit": { - "success": "Notification updated successfully", - "failed": "Failed to update notification" - }, - "test": { - "success": "Test notification sent successfully", - "failed": "Failed to send test notification" - } - }, - "testLocale": "testLocale", - "add": "Add", - "monitors": "monitors", - "distributedUptimeStatusCreateStatusPage": "status page", - "distributedUptimeStatusCreateStatusPageAccess": "Access", - "distributedUptimeStatusCreateStatusPageReady": "If your status page is ready, you can mark it as published.", - "distributedUptimeStatusBasicInfoHeader": "Basic Information", - "distributedUptimeStatusBasicInfoDescription": "Define company name and the subdomain that your status page points to.", - "distributedUptimeStatusLogoHeader": "Logo", - "distributedUptimeStatusLogoDescription": "Upload a logo for your status page", - "distributedUptimeStatusLogoUploadButton": "Upload logo", - "distributedUptimeStatusStandardMonitorsHeader": "Standard Monitors", - "distributedUptimeStatusStandardMonitorsDescription": "Attach standard monitors to your status page.", - "distributedUptimeStatusCreateYour": "Create your", - "distributedUptimeStatusEditYour": "Edit your", - "distributedUptimeStatusPublishedLabel": "Published and visible to the public", - "distributedUptimeStatusCompanyNameLabel": "Company name", - "distributedUptimeStatusPageAddressLabel": "Your status page address", - "distributedUptimeStatus30Days": "30 days", - "distributedUptimeStatus60Days": "60 days", - "distributedUptimeStatus90Days": "90 days", - "distributedUptimeStatusPageNotSetUp": "A status page is not set up.", - "distributedUptimeStatusContactAdmin": "Please contact your administrator", - "distributedUptimeStatusPageNotPublic": "This status page is not public.", - "distributedUptimeStatusPageDeleteDialog": "Do you want to delete this status page?", - "distributedUptimeStatusPageDeleteConfirm": "Yes, delete status page", - "distributedUptimeStatusPageDeleteDescription": "Once deleted, your status page cannot be retrieved.", - "distributedUptimeStatusDevices": "Devices", - "distributedUptimeStatusUpt": "UPT", - "distributedUptimeStatusUptBurned": "UPT Burned", - "distributedUptimeStatusUptLogo": "Upt Logo", - "incidentsTableNoIncidents": "No incidents recorded", - "incidentsTablePaginationLabel": "incidents", - "incidentsTableMonitorName": "Monitor Name", - "incidentsTableStatus": "Status", - "incidentsTableDateTime": "Date & Time", - "incidentsTableStatusCode": "Status Code", - "incidentsTableMessage": "Message", - "incidentsOptionsHeader": "Incidents for:", - "incidentsOptionsHeaderFilterBy": "Filter by:", - "incidentsOptionsHeaderFilterAll": "All", - "incidentsOptionsHeaderFilterDown": "Down", - "incidentsOptionsHeaderFilterCannotResolve": "Cannot resolve", - "incidentsOptionsHeaderShow": "Show:", - "incidentsOptionsHeaderLastHour": "Last hour", - "incidentsOptionsHeaderLastDay": "Last day", - "incidentsOptionsHeaderLastWeek": "Last week", - "incidentsOptionsPlaceholderAllServers": "All servers", - "infrastructureCreateYour": "Create your", - "infrastructureCreateGeneralSettingsDescription": "Here you can select the URL of the host, together with the friendly name and authorization secret to connect to the server agent.", - "infrastructureServerRequirement": "The server you are monitoring must be running the", - "infrastructureCustomizeAlerts": "Customize alerts", - "infrastructureAlertNotificationDescription": "Send a notification to user(s) when thresholds exceed a specified percentage.", - "infrastructureCreateMonitor": "Create Infrastructure Monitor", - "infrastructureProtocol": "Protocol", - "infrastructureServerUrlLabel": "Server URL", - "infrastructureDisplayNameLabel": "Display name", - "infrastructureAuthorizationSecretLabel": "Authorization secret", - "gb": "GB", - "mb": "MB", - "mem": "Mem", - "memoryUsage": "Memory usage", - "cpu": "CPU", - "cpuUsage": "CPU usage", - "cpuTemperature": "CPU Temperature", - "diskUsage": "Disk Usage", - "used": "Used", - "total": "Total", - "cores": "Cores", - "frequency": "Frequency", - "status": "Status", - "cpuPhysical": "CPU (Physical)", - "cpuLogical": "CPU (Logical)", - "cpuFrequency": "CPU Frequency", - "avgCpuTemperature": "Average CPU Temperature", - "memory": "Memory", - "disk": "Disk", - "uptime": "Uptime", - "os": "OS", - "host": "Host", - "actions": "Actions", - "integrations": "Integrations", - "integrationsPrism": "Connect Prism to your favorite service.", - "integrationsSlack": "Slack", - "integrationsSlackInfo": "Connect with Slack and see incidents in a channel", - "integrationsDiscord": "Discord", - "integrationsDiscordInfo": "Connect with Discord and view incidents directly in a channel", - "integrationsZapier": "Zapier", - "integrationsZapierInfo": "Send all incidents to Zapier, and then see them everywhere", - "commonSave": "Save", - "createYour": "Create your", - "createMonitor": "Create monitor", - "pause": "Pause", - "resume": "Resume", - "editing": "Editing...", - "url": "URL", - "access": "Access", - "timezone": "Timezone", - "features": "Features", - "administrator": "Administrator?", - "loginHere": "Login here", - "displayName": "Display name", - "urlMonitor": "URL to monitor", - "portToMonitor": "Port to monitor", - "websiteMonitoring": "Website monitoring", - "websiteMonitoringDescription": "Use HTTP(s) to monitor your website or API endpoint.", - "pingMonitoring": "Ping monitoring", - "pingMonitoringDescription": "Check whether your server is available or not.", - "dockerContainerMonitoring": "Docker container monitoring", - "dockerContainerMonitoringDescription": "Check whether your Docker container is running or not.", - "portMonitoring": "Port monitoring", - "portMonitoringDescription": "Check whether your port is open or not.", - "createMaintenanceWindow": "Create maintenance window", - "createMaintenance": "Create maintenance", - "editMaintenance": "Edit maintenance", - "maintenanceWindowName": "Maintenance Window Name", - "friendlyNameInput": "Friendly name", - "friendlyNamePlaceholder": "Maintenance at __ : __ for ___ minutes", - "maintenanceRepeat": "Maintenance Repeat", - "maintenance": "maintenance", - "duration": "Duration", - "addMonitors": "Add monitors", - "window": "window", - "cancel": "Cancel", - "message": "Message", - "low": "low", - "high": "high", - "statusCode": "Status code", - "date&Time": "Date & Time", - "type": "Type", - "statusPageName": "Status page name", - "publicURL": "Public URL", - "repeat": "Repeat", - "edit": "Edit", - "createA": "Create a", - "remove": "Remove", - "maintenanceWindowDescription": "Your pings won't be sent during this time frame", - "startTime": "Start time", - "timeZoneInfo": "All dates and times are in GMT+0 time zone.", - "monitorsToApply": "Monitors to apply maintenance window to", - "nextWindow": "Next window", - "notFoundButton": "Go to the main dashboard", - "pageSpeedConfigureSettingsDescription": "Here you can select the URL of the host, together with the type of monitor.", - "monitorDisplayName": "Monitor display name", - "whenNewIncident": "When there is a new incident,", - "notifySMS": "Notify via SMS (coming soon)", - "notifyEmails": "Also notify via email to multiple addresses (coming soon)", - "seperateEmails": "You can separate multiple emails with a comma", - "checkFrequency": "Check frequency", - "matchMethod": "Match Method", - "expectedValue": "Expected value", - "deleteDialogTitle": "Do you really want to delete this monitor?", - "deleteDialogDescription": "Once deleted, this monitor cannot be retrieved.", - "pageSpeedMonitor": "PageSpeed monitor", - "shown": "Shown", - "ago": "ago", - "companyName": "Company name", - "pageSpeedDetailsPerformanceReport": "Values are estimated and may vary.", - "pageSpeedDetailsPerformanceReportCalculator": "See calculator", - "checkingEvery": "Checking every", - "statusPageCreateSettings": "If your status page is ready, you can mark it as published.", - "basicInformation": "Basic Information", - "statusPageCreateBasicInfoDescription": "Define company name and the subdomain that your status page points to.", - "statusPageCreateSelectTimeZoneDescription": "Select the timezone that your status page will be displayed in.", - "statusPageCreateAppearanceDescription": "Define the default look and feel of your public status page.", - "statusPageCreateSettingsCheckboxLabel": "Published and visible to the public", - "statusPageCreateBasicInfoStatusPageAddress": "Your status page address", - "statusPageCreateTabsContent": "Status page servers", - "statusPageCreateTabsContentDescription": "You can add any number of servers that you monitor to your status page. You can also reorder them for the best viewing experience.", - "statusPageCreateTabsContentFeaturesDescription": "Show more details on the status page", - "showCharts": "Show charts", - "showUptimePercentage": "Show uptime percentage", - "showAdminLoginLink": "Show \"Administrator? Login Here\" link on the status page", - "removeLogo": "Remove Logo", - "statusPageStatus": "A public status page is not set up.", - "statusPageStatusContactAdmin": "Please contact to your administrator", - "statusPageStatusNotPublic": "This status page is not public.", - "statusPageStatusNoPage": "There's no status page here.", - "statusPageStatusServiceStatus": "Service status", - "deleteStatusPage": "Do you want to delete this status page?", - "deleteStatusPageConfirm": "Yes, delete status page", - "deleteStatusPageDescription": "Once deleted, your status page cannot be retrieved.", - "uptimeCreate": "The expected value is used to match against response result, and the match determines the status.", - "uptimeCreateJsonPath": "This expression will be evaluated against the reponse JSON data and the result will be used to match against the expected value. See", - "uptimeCreateJsonPathQuery": "for query language documentation.", - "maintenanceTableActionMenuDialogTitle": "Do you really want to remove this maintenance window?", - "infrastructureEditYour": "Edit your", - "infrastructureEditMonitor": "Save Infrastructure Monitor", - "infrastructureMonitorCreated": "Infrastructure monitor created successfully!", - "infrastructureMonitorUpdated": "Infrastructure monitor updated successfully!", - "errorInvalidTypeId": "Invalid notification type provided", - "errorInvalidFieldId": "Invalid field ID provided", - "inviteNoTokenFound": "No invite token found", - "pageSpeedWarning": "Warning: You haven't added a Google PageSpeed API key yet. Without it, the PageSpeed monitor won't function.", - "pageSpeedLearnMoreLink": "Click here", - "pageSpeedAddApiKey": "to add your API key.", - "update": "Update", - "invalidFileFormat": "Unsupported file format!", - "invalidFileSize": "File size is too large!", "ClickUpload": "Click to upload", + "DeleteAccountButton": "Remove account", + "DeleteAccountTitle": "Remove account", + "DeleteAccountWarning": "Removing your account means you won't be able to sign in again and all your data will be removed. This isn't reversible.", + "DeleteDescriptionText": "This will remove the account and all associated data from the server. This isn't reversible.", + "DeleteWarningTitle": "Really remove this account?", "DragandDrop": "drag and drop", - "MaxSize": "Maximum Size", - "SupportedFormats": "Supported formats", + "EmailDescriptionText": "This is your current email address — it cannot be changed.", "FirstName": "First name", "LastName": "Last name", - "EmailDescriptionText": "This is your current email address — it cannot be changed.", - "YourPhoto": "Profile photo", + "MaxSize": "Maximum Size", "PhotoDescriptionText": "This photo will be displayed in your profile page.", - "save": "Save", - "DeleteDescriptionText": "This will remove the account and all associated data from the server. This isn't reversible.", - "DeleteAccountWarning": "Removing your account means you won't be able to sign in again and all your data will be removed. This isn't reversible.", - "DeleteWarningTitle": "Really remove this account?", - "bulkImport": { - "title": "Bulk Import", - "selectFileTips": "Select CSV file to upload", - "selectFileDescription": "You can download our or sample", - "selectFile": "Select File", - "parsingFailed": "Parsing failed", - "uploadSuccess": "Monitors created successfully!", - "validationFailed": "Validation failed", - "noFileSelected": "No file selected", - "fallbackPage": "Import a file to upload a list of servers in bulk" - }, - "settingsSystemReset": "System reset", - "settingsSystemResetDescription": "Remove all monitors from your system.", - "DeleteAccountTitle": "Remove account", - "DeleteAccountButton": "Remove account", - "publicLink": "Public link", - "maskedPageSpeedKeyPlaceholder": "*************************************", - "pageSpeedApiKeyFieldTitle": "Google PageSpeed API key", - "pageSpeedApiKeyFieldLabel": "PageSpeed API key", - "pageSpeedApiKeyFieldDescription": "Enter your Google PageSpeed API key to enable pagespeed monitoring. Click Reset to update the key.", - "pageSpeedApiKeyFieldResetLabel": "API key is set. Click Reset to change it.", - "reset": "Reset", - "ignoreTLSError": "Ignore TLS/SSL error", - "tlsErrorIgnored": "TLS/SSL errors ignored", - "ignoreTLSErrorDescription": "Ignore TLS/SSL errors and continue checking the website's availability", - "createNew": "Create new", - "greeting": { - "prepend": "Hey there", - "append": "The afternoon is your playground—let's make it epic!", - "overview": "Here's an overview of your {{type}} monitors." - }, - "roles": { - "superAdmin": "Super admin", - "admin": "Admin", - "teamMember": "Team member", - "demoUser": "Demo user" - }, - "teamPanel": { - "teamMembers": "Team members", - "filter": { - "all": "All", - "member": "Member" - }, - "inviteTeamMember": "Invite a team member", - "inviteNewTeamMember": "Invite new team member", - "inviteDescription": "When you add a new team member, they will get access to all monitors.", - "email": "Email", - "selectRole": "Select role", - "inviteLink": "Invite link", - "cancel": "Cancel", - "noMembers": "There are no team members with this role", - "getToken": "Get token", - "emailToken": "E-mail token", - "table": { - "name": "Name", - "email": "Email", - "role": "Role", - "created": "Created" - } - }, - "monitorState": { - "paused": "Paused", - "resumed": "Resumed", - "active": "Active" - }, - "menu": { - "uptime": "Uptime", - "pagespeed": "Pagespeed", - "infrastructure": "Infrastructure", - "incidents": "Incidents", - "statusPages": "Status pages", - "maintenance": "Maintenance", - "integrations": "Integrations", - "logs": "Logs", - "settings": "Settings", - "support": "Support", - "discussions": "Discussions", - "docs": "Docs", - "changelog": "Changelog", - "profile": "Profile", - "password": "Password", - "team": "Team", - "logOut": "Log out", - "notifications": "Notifications" - }, - "settingsEmail": "Email", - "settingsEmailDescription": "Configure the email settings for your system. This is used to send notifications and alerts.", - "settingsEmailHost": "Email host - Hostname or IP address to connect to", - "settingsEmailPort": "Email port - Port to connect to", - "settingsEmailAddress": "Email address - Used for authentication", - "settingsEmailPassword": "Email password - Password for authentication", - "settingsEmailUser": "Email user - Username for authentication, overrides email address if specified", - "settingsEmailFieldResetLabel": "Password is set. Click Reset to change it.", - "settingsEmailTransportLinkDescription": "This builds an SMTP transport for NodeMailer", - "settingsEmailTransportLinkText": "See specifications here", - "state": "State", - "statusBreadCrumbsStatusPages": "Status Pages", - "statusBreadCrumbsDetails": "Details", - "settingsThemeModeLight": "Light", - "settingsThemeModeDark": "Dark", - "settingsClearAllStatsDialogCancel": "Cancel", - "commonSaving": "Saving...", - "navControls": "Controls", - "incidentsPageTitle": "Incidents", - "passwordPanel": { - "passwordChangedSuccess": "Your password was changed successfully.", - "passwordInputIncorrect": "Your password input was incorrect.", - "currentPassword": "Current password", - "enterCurrentPassword": "Enter your current password", - "newPassword": "New password", - "enterNewPassword": "Enter your new password", - "confirmNewPassword": "Confirm new password", - "passwordRequirements": "New password must contain at least 8 characters and must have at least one uppercase letter, one lowercase letter, one number and one special character.", - "saving": "Saving..." - }, - "settingsEmailConnectionHost": "Email connection host - Hostname to use in the HELO/EHLO greeting", - "emailSent": "Email sent successfully", - "failedToSendEmail": "Failed to send email", - "settingsTestEmail": "Send test e-mail", - "settingsTestEmailSuccess": "Test email sent successfully", - "settingsTestEmailFailed": "Failed to send test email", - "settingsTestEmailFailedWithReason": "Failed to send test email: {{reason}}", - "settingsTestEmailUnknownError": "Unknown error", - "settingsEmailRequiredFields": "Email address, host, port and password are required", - "statusMsg": { - "paused": "Monitoring is paused.", - "up": "Your site is up.", - "down": "Your site is down.", - "pending": "Pending..." - }, - "settingsURLTitle": "Monitor IP/URL on Status Page", - "settingsURLDescription": "Display the IP address or URL of monitor on the public Status page. If it's disabled, only the monitor name will be shown to protect sensitive information.", - "settingsURLSelectTitle": "Display IP/URL on status page", - "settingsURLEnabled": "Enabled", - "settingURLDisabled": "Disabled", - "uptimeGeneralInstructions": { - "http": "Enter the URL or IP to monitor (e.g., https://example.com/ or 192.168.1.100) and add a clear display name that appears on the dashboard.", - "ping": "Enter the IP address or hostname to ping (e.g., 192.168.1.100 or example.com) and add a clear display name that appears on the dashboard.", - "docker": "Enter the Docker ID of your container. Docker IDs must be the full 64 char Docker ID. You can run docker inspect to get the full container ID.", - "port": "Enter the URL or IP of the server, the port number and a clear display name that appears on the dashboard." - }, - "common": { - "appName": "Checkmate", - "monitoringAgentName": "Capture", - "buttons": { - "toggleTheme": "Toggles light & dark" - }, - "toasts": { - "networkError": "Network error", - "checkConnection": "Please check your connection", - "unknownError": "Unknown error" - } - }, + "SupportedFormats": "Supported formats", + "YourPhoto": "Profile photo", + "aboutus": "About Us", + "access": "Access", + "actions": "Actions", + "add": "Add", + "addMonitors": "Add monitors", + "administrator": "Administrator?", + "advancedMatching": "Advanced matching", + "ago": "ago", + "area": "Area", "auth": { "common": { - "navigation": { - "continue": "Continue", - "back": "Back" - }, - "inputs": { - "email": { - "label": "Email", - "placeholder": "jordan.ellis@domain.com", - "errors": { - "empty": "To continue, please enter your email address", - "invalid": "Please recheck validity of entered email address" - } - }, - "password": { - "label": "Password", - "rules": { - "length": { - "beginning": "Must be at least", - "highlighted": "8 characters long" - }, - "special": { - "beginning": "Must contain at least", - "highlighted": "one special character" - }, - "number": { - "beginning": "Must contain at least", - "highlighted": "one number" - }, - "uppercase": { - "beginning": "Must contain at least", - "highlighted": "one upper character" - }, - "lowercase": { - "beginning": "Must contain at least", - "highlighted": "one lower character" - }, - "match": { - "beginning": "Confirm password and password", - "highlighted": "must match" - } - }, - "errors": { - "empty": "Please enter your password", - "length": "Password must be at least 8 characters long", - "uppercase": "Password must contain at least 1 uppercase letter", - "lowercase": "Password must contain at least 1 lowercase letter", - "number": "Password must contain at least 1 number", - "special": "Password must contain at least 1 special character", - "incorrect": "The password you provided does not match our records" - } - }, - "passwordConfirm": { - "label": "Confirm password", - "placeholder": "Re-enter password to confirm", - "errors": { - "empty": "Please enter your password again for confirmation (helps with typos)", - "different": "Entered passwords don't match, so one of them is probably mistyped" - } - }, - "firstName": { - "label": "Name", - "placeholder": "Jordan", - "errors": { - "empty": "Please enter your name", - "length": "Name must be less than 50 characters", - "pattern": "Name must contain only letters, spaces, apostrophes, or hyphens" - } - }, - "lastName": { - "label": "Surname", - "placeholder": "Ellis", - "errors": { - "empty": "Please enter your surname", - "length": "Surname must be less than 50 characters", - "pattern": "Surname must contain only letters, spaces, apostrophes, or hyphens" - } - } - }, "errors": { "validation": "Error validating data." }, @@ -598,40 +33,139 @@ "incorrect": "The password you provided does not match our records" } } + }, + "inputs": { + "email": { + "errors": { + "empty": "To continue, please enter your email address", + "invalid": "Please recheck validity of entered email address" + }, + "label": "Email", + "placeholder": "jordan.ellis@domain.com" + }, + "firstName": { + "errors": { + "empty": "Please enter your name", + "length": "Name must be less than 50 characters", + "pattern": "Name must contain only letters, spaces, apostrophes, or hyphens" + }, + "label": "Name", + "placeholder": "Jordan" + }, + "lastName": { + "errors": { + "empty": "Please enter your surname", + "length": "Surname must be less than 50 characters", + "pattern": "Surname must contain only letters, spaces, apostrophes, or hyphens" + }, + "label": "Surname", + "placeholder": "Ellis" + }, + "password": { + "errors": { + "empty": "Please enter your password", + "incorrect": "The password you provided does not match our records", + "length": "Password must be at least 8 characters long", + "lowercase": "Password must contain at least 1 lowercase letter", + "number": "Password must contain at least 1 number", + "special": "Password must contain at least 1 special character", + "uppercase": "Password must contain at least 1 uppercase letter" + }, + "label": "Password", + "rules": { + "length": { + "beginning": "Must be at least", + "highlighted": "8 characters long" + }, + "lowercase": { + "beginning": "Must contain at least", + "highlighted": "one lower character" + }, + "match": { + "beginning": "Confirm password and password", + "highlighted": "must match" + }, + "number": { + "beginning": "Must contain at least", + "highlighted": "one number" + }, + "special": { + "beginning": "Must contain at least", + "highlighted": "one special character" + }, + "uppercase": { + "beginning": "Must contain at least", + "highlighted": "one upper character" + } + } + }, + "passwordConfirm": { + "errors": { + "different": "Entered passwords don't match, so one of them is probably mistyped", + "empty": "Please enter your password again for confirmation (helps with typos)" + }, + "label": "Confirm password", + "placeholder": "Re-enter password to confirm" + } + }, + "navigation": { + "back": "Back", + "continue": "Continue" + } + }, + "forgotPassword": { + "buttons": { + "openEmail": "Open email app", + "resetPassword": "Reset password" + }, + "heading": "Forgot password?", + "imageAlts": { + "email": "Email icon", + "lock": "Lock icon", + "passwordConfirm": "Password confirm icon", + "passwordKey": "Password key icon" + }, + "links": { + "login": "Go back to Log In", + "resend": "Didn't receive the email? Click to resend" + }, + "subheadings": { + "stepFour": "Your password has been successfully reset. Click below to log in magically.", + "stepOne": "No worries, we'll send you reset instructions.", + "stepThree": "Your new password must be different from previously used passwords.", + "stepTwo": "We sent a password reset link to " + }, + "toasts": { + "emailNotFound": "Email not found.", + "error": "Unable to reset password. Please try again later or contact support.", + "redirect": "Redirecting in ...", + "sent": "Instructions sent to .", + "success": "Your password was reset successfully." } }, "login": { - "heading": "Log In", - "subheadings": { - "stepOne": "Enter your email", - "stepTwo": "Enter your password" - }, - "links": { - "forgotPassword": "Forgot password?", - "register": "Do not have an account?", - "forgotPasswordLink": "Reset password", - "registerLink": "Register here" - }, - "toasts": { - "success": "Welcome back! You're successfully logged in.", - "incorrectPassword": "Incorrect password" - }, "errors": { "password": { "incorrect": "The password you provided does not match our records" } + }, + "heading": "Log In", + "links": { + "forgotPassword": "Forgot password?", + "forgotPasswordLink": "Reset password", + "register": "Do not have an account?", + "registerLink": "Register here" + }, + "subheadings": { + "stepOne": "Enter your email", + "stepTwo": "Enter your password" + }, + "toasts": { + "incorrectPassword": "Incorrect password", + "success": "Welcome back! You're successfully logged in." } }, "registration": { - "heading": { - "superAdmin": "Create super admin", - "user": "Sign Up" - }, - "subheadings": { - "stepOne": "Enter your personal details", - "stepTwo": "Enter your email", - "stepThree": "Create your password" - }, "description": { "superAdmin": "Create your super admin account to get started", "user": "Sign up as a user and ask super admin for access to your monitors" @@ -640,183 +174,666 @@ "superAdmin": "Create super admin account", "user": "Sign up regular user" }, - "termsAndPolicies": "By creating an account, you agree to our Terms of Service and Privacy Policy.", + "heading": { + "superAdmin": "Create super admin", + "user": "Sign Up" + }, "links": { "login": "Already have an account? Log In" }, + "subheadings": { + "stepOne": "Enter your personal details", + "stepThree": "Create your password", + "stepTwo": "Enter your email" + }, + "termsAndPolicies": "By creating an account, you agree to our Terms of Service and Privacy Policy.", "toasts": { "success": "Welcome! Your account was created successfully." } - }, - "forgotPassword": { - "heading": "Forgot password?", - "subheadings": { - "stepOne": "No worries, we'll send you reset instructions.", - "stepTwo": "We sent a password reset link to ", - "stepThree": "Your new password must be different from previously used passwords.", - "stepFour": "Your password has been successfully reset. Click below to log in magically." - }, - "buttons": { - "openEmail": "Open email app", - "resetPassword": "Reset password" - }, - "imageAlts": { - "passwordKey": "Password key icon", - "email": "Email icon", - "lock": "Lock icon", - "passwordConfirm": "Password confirm icon" - }, - "links": { - "login": "Go back to Log In", - "resend": "Didn't receive the email? Click to resend" - }, - "toasts": { - "sent": "Instructions sent to .", - "emailNotFound": "Email not found.", - "redirect": "Redirecting in ...", - "success": "Your password was reset successfully.", - "error": "Unable to reset password. Please try again later or contact support." - } } }, + "avgCpuTemperature": "Average CPU Temperature", + "bar": "Bar", + "basicInformation": "Basic Information", + "bulkImport": { + "fallbackPage": "Import a file to upload a list of servers in bulk", + "noFileSelected": "No file selected", + "parsingFailed": "Parsing failed", + "selectFile": "Select File", + "selectFileDescription": "You can download our or sample", + "selectFileTips": "Select CSV file to upload", + "title": "Bulk Import", + "uploadSuccess": "Monitors created successfully!", + "validationFailed": "Validation failed" + }, + "cancel": "Cancel", + "checkFrequency": "Check frequency", + "checkingEvery": "Checking every", + "city": "CITY", + "common": { + "appName": "Checkmate", + "buttons": { + "toggleTheme": "Toggles light & dark" + }, + "monitoringAgentName": "Capture", + "toasts": { + "checkConnection": "Please check your connection", + "networkError": "Network error", + "unknownError": "Unknown error" + } + }, + "commonSave": "Save", + "commonSaving": "Saving...", + "companyName": "Company name", + "configure": "Configure", + "cores": "Cores", + "country": "COUNTRY", + "cpu": "CPU", + "cpuFrequency": "CPU Frequency", + "cpuLogical": "CPU (Logical)", + "cpuPhysical": "CPU (Physical)", + "cpuTemperature": "CPU Temperature", + "cpuUsage": "CPU usage", + "createA": "Create a", + "createMaintenance": "Create maintenance", + "createMaintenanceWindow": "Create maintenance window", + "createMonitor": "Create monitor", + "createNew": "Create new", + "createNotifications": { + "discordSettings": { + "description": "Configure your Discord webhook here", + "title": "Discord", + "webhookLabel": "Discord Webhook URL", + "webhookPlaceholder": "https://your-server.com/webhook" + }, + "emailSettings": { + "description": "Destination email addresses.", + "emailLabel": "Email address", + "emailPlaceholder": "e.g. john@example.com", + "title": "Email" + }, + "nameSettings": { + "description": "A descriptive name for your integration.", + "nameLabel": "Name", + "namePlaceholder": "e.g. Slack notifications", + "title": "Name" + }, + "pagerdutySettings": { + "description": "Configure your PagerDuty integration here", + "integrationKeyLabel": "Integration key", + "integrationKeyPlaceholder": "1234567890", + "title": "PagerDuty" + }, + "slackSettings": { + "description": "Configure your Slack webhook here", + "title": "Slack", + "webhookLabel": "Slack webhook URL", + "webhookPlaceholder": "https://hooks.slack.com/services/..." + }, + "title": "Create notification channel", + "typeSettings": { + "description": "Select the type of notification channel you want to create.", + "title": "Type", + "typeLabel": "Type" + }, + "webhookSettings": { + "description": "Configure your webhook here", + "title": "Webhook", + "webhookLabel": "Webhook URL", + "webhookPlaceholder": "https://your-server.com/webhook" + } + }, + "createYour": "Create your", + "date&Time": "Date & Time", + "delete": "Delete", + "deleteDialogDescription": "Once deleted, this monitor cannot be retrieved.", + "deleteDialogTitle": "Do you really want to delete this monitor?", + "deleteStatusPage": "Do you want to delete this status page?", + "deleteStatusPageConfirm": "Yes, delete status page", + "deleteStatusPageDescription": "Once deleted, your status page cannot be retrieved.", + "disk": "Disk", + "diskUsage": "Disk Usage", + "displayName": "Display name", + "distributedRightCategoryTitle": "Monitor", + "distributedStatusHeaderText": "Real-time, real-device coverage", + "distributedStatusServerMonitors": "Server Monitors", + "distributedStatusServerMonitorsDescription": "Monitor status of related servers", + "distributedStatusSubHeaderText": "Powered by millions devices worldwide, view a system performance by global region, country or city", + "distributedUptimeCreateAdvancedSettings": "Advanced settings", + "distributedUptimeCreateChecks": "Checks to perform", + "distributedUptimeCreateChecksDescription": "You can always add or remove checks after adding your site.", + "distributedUptimeCreateIncidentDescription": "When there is an incident, notify users.", + "distributedUptimeCreateIncidentNotification": "Incident notifications", + "distributedUptimeCreateSelectURL": "Here you can select the URL of the host, together with the type of monitor.", + "distributedUptimeDetailsNoMonitorHistory": "There is no check history for this monitor yet.", + "distributedUptimeDetailsStatusHeaderLastUpdate": "Last updated", + "distributedUptimeDetailsStatusHeaderUptime": "Uptime:", + "distributedUptimeStatus30Days": "30 days", + "distributedUptimeStatus60Days": "60 days", + "distributedUptimeStatus90Days": "90 days", + "distributedUptimeStatusBasicInfoDescription": "Define company name and the subdomain that your status page points to.", + "distributedUptimeStatusBasicInfoHeader": "Basic Information", + "distributedUptimeStatusCompanyNameLabel": "Company name", + "distributedUptimeStatusContactAdmin": "Please contact your administrator", + "distributedUptimeStatusCreateStatusPage": "status page", + "distributedUptimeStatusCreateStatusPageAccess": "Access", + "distributedUptimeStatusCreateStatusPageReady": "If your status page is ready, you can mark it as published.", + "distributedUptimeStatusCreateYour": "Create your", + "distributedUptimeStatusDevices": "Devices", + "distributedUptimeStatusEditYour": "Edit your", + "distributedUptimeStatusLogoDescription": "Upload a logo for your status page", + "distributedUptimeStatusLogoHeader": "Logo", + "distributedUptimeStatusLogoUploadButton": "Upload logo", + "distributedUptimeStatusPageAddressLabel": "Your status page address", + "distributedUptimeStatusPageDeleteConfirm": "Yes, delete status page", + "distributedUptimeStatusPageDeleteDescription": "Once deleted, your status page cannot be retrieved.", + "distributedUptimeStatusPageDeleteDialog": "Do you want to delete this status page?", + "distributedUptimeStatusPageNotPublic": "This status page is not public.", + "distributedUptimeStatusPageNotSetUp": "A status page is not set up.", + "distributedUptimeStatusPublishedLabel": "Published and visible to the public", + "distributedUptimeStatusStandardMonitorsDescription": "Attach standard monitors to your status page.", + "distributedUptimeStatusStandardMonitorsHeader": "Standard Monitors", + "distributedUptimeStatusUpt": "UPT", + "distributedUptimeStatusUptBurned": "UPT Burned", + "distributedUptimeStatusUptLogo": "Upt Logo", + "dockerContainerMonitoring": "Docker container monitoring", + "dockerContainerMonitoringDescription": "Check whether your Docker container is running or not.", + "duration": "Duration", + "edit": "Edit", + "editMaintenance": "Edit maintenance", + "editing": "Editing...", + "emailSent": "Email sent successfully", + "errorInvalidFieldId": "Invalid field ID provided", + "errorInvalidTypeId": "Invalid notification type provided", "errorPages": { "serverUnreachable": { - "toasts": { - "reconnected": "Successfully reconnected to the server.", - "stillUnreachable": "Server is still unreachable. Please try again later." - }, "alertBox": "Server Connection Error", "description": "We're unable to connect to the server. Please check your internet connection or verify your deployment configuration if the problem persists.", "retryButton": { "default": "Retry connection", "processing": "Connecting..." + }, + "toasts": { + "reconnected": "Successfully reconnected to the server.", + "stillUnreachable": "Server is still unreachable. Please try again later." } } }, - "createNotifications": { - "title": "Create notification channel", - "nameSettings": { - "title": "Name", - "description": "A descriptive name for your integration.", - "nameLabel": "Name", - "namePlaceholder": "e.g. Slack notifications" - }, - "typeSettings": { - "title": "Type", - "description": "Select the type of notification channel you want to create.", - "typeLabel": "Type" - }, - "emailSettings": { - "title": "Email", - "description": "Destination email addresses.", - "emailLabel": "Email address", - "emailPlaceholder": "e.g. john@example.com" - }, - "slackSettings": { - "title": "Slack", - "description": "Configure your Slack webhook here", - "webhookLabel": "Slack webhook URL", - "webhookPlaceholder": "https://hooks.slack.com/services/..." - }, - "pagerdutySettings": { - "title": "PagerDuty", - "description": "Configure your PagerDuty integration here", - "integrationKeyLabel": "Integration key", - "integrationKeyPlaceholder": "1234567890" - }, - "discordSettings": { - "title": "Discord", - "description": "Configure your Discord webhook here", - "webhookLabel": "Discord Webhook URL", - "webhookPlaceholder": "https://your-server.com/webhook" - }, - "webhookSettings": { - "title": "Webhook", - "description": "Configure your webhook here", - "webhookLabel": "Webhook URL", - "webhookPlaceholder": "https://your-server.com/webhook" - } + "expectedValue": "Expected value", + "export": { + "failed": "Failed to export monitors", + "success": "Monitors exported successfully!", + "title": "Export Monitors" }, - "notificationConfig": { - "title": "Notifications", - "description": "Select the notifications channels you want to use" + "failedToSendEmail": "Failed to send email", + "features": "Features", + "frequency": "Frequency", + "friendlyNameInput": "Friendly name", + "friendlyNamePlaceholder": "Maintenance at __ : __ for ___ minutes", + "gb": "GB", + "greeting": { + "append": "The afternoon is your playground—let's make it epic!", + "overview": "Here's an overview of your {{type}} monitors.", + "prepend": "Hey there" }, - "monitorStatus": { - "checkingEvery": "Checking every {{interval}}", - "withCaptureAgent": "with Capture agent {{version}}", - "up": "up", - "down": "down", - "paused": "paused" - }, - "advancedMatching": "Advanced matching", - "settingsEmailTLSServername": "TLS Servername - Optional Hostname for TLS Validation when host is an IP", - "settingsEmailIgnoreTLS": "Ignore TLS - Disable STARTTLS", - "settingsEmailRequireTLS": "Require TLS - Force STARTTLS", - "settingsEmailRejectUnauthorized": "Reject Unauthorized", - "settingsEmailSecure": "Secure - Use SSL", - "settingsEmailPool": "Pool - Enable connection pooling", - "sendTestNotifications": "Send test notifications", - "selectAll": "Select all", + "high": "high", + "host": "Host", + "http": "HTTP", + "https": "HTTPS", + "ignoreTLSError": "Ignore TLS/SSL error", + "ignoreTLSErrorDescription": "Ignore TLS/SSL errors and continue checking the website's availability", + "incidentsOptionsHeader": "Incidents for:", + "incidentsOptionsHeaderFilterAll": "All", + "incidentsOptionsHeaderFilterBy": "Filter by:", + "incidentsOptionsHeaderFilterCannotResolve": "Cannot resolve", + "incidentsOptionsHeaderFilterDown": "Down", + "incidentsOptionsHeaderLastDay": "Last day", + "incidentsOptionsHeaderLastHour": "Last hour", + "incidentsOptionsHeaderLastWeek": "Last week", + "incidentsOptionsHeaderShow": "Show:", + "incidentsOptionsPlaceholderAllServers": "All servers", + "incidentsPageTitle": "Incidents", + "incidentsTableDateTime": "Date & Time", + "incidentsTableMessage": "Message", + "incidentsTableMonitorName": "Monitor Name", + "incidentsTableNoIncidents": "No incidents recorded", + "incidentsTablePaginationLabel": "incidents", + "incidentsTableStatus": "Status", + "incidentsTableStatusCode": "Status Code", + "infrastructureAlertNotificationDescription": "Send a notification to user(s) when thresholds exceed a specified percentage.", + "infrastructureAuthorizationSecretLabel": "Authorization secret", + "infrastructureCreateGeneralSettingsDescription": "Here you can select the URL of the host, together with the friendly name and authorization secret to connect to the server agent.", + "infrastructureCreateMonitor": "Create Infrastructure Monitor", + "infrastructureCreateYour": "Create your", + "infrastructureCustomizeAlerts": "Customize alerts", + "infrastructureDisplayNameLabel": "Display name", + "infrastructureEditMonitor": "Save Infrastructure Monitor", + "infrastructureEditYour": "Edit your", + "infrastructureMonitorCreated": "Infrastructure monitor created successfully!", + "infrastructureMonitorUpdated": "Infrastructure monitor updated successfully!", + "infrastructureProtocol": "Protocol", + "infrastructureServerRequirement": "The server you are monitoring must be running the", + "infrastructureServerUrlLabel": "Server URL", + "integrations": "Integrations", + "integrationsDiscord": "Discord", + "integrationsDiscordInfo": "Connect with Discord and view incidents directly in a channel", + "integrationsPrism": "Connect Prism to your favorite service.", + "integrationsSlack": "Slack", + "integrationsSlackInfo": "Connect with Slack and see incidents in a channel", + "integrationsZapier": "Zapier", + "integrationsZapierInfo": "Send all incidents to Zapier, and then see them everywhere", + "invalidFileFormat": "Unsupported file format!", + "invalidFileSize": "File size is too large!", + "inviteNoTokenFound": "No invite token found", + "loginHere": "Login here", "logsPage": { - "title": "Logs", "description": "This page shows the latest 1000 lines of logs from the Checkmate server", - "tabs": { - "queue": "Job queue", - "logs": "Server logs" - }, - "toast": { - "fetchLogsSuccess": "Logs fetched successfully" - }, "logLevelSelect": { "title": "Log level", "values": { "all": "All", - "info": "Info", - "warn": "Warn", + "debug": "Debug", "error": "Error", - "debug": "Debug" + "info": "Info", + "warn": "Warn" } + }, + "tabs": { + "logs": "Server logs", + "queue": "Job queue" + }, + "title": "Logs", + "toast": { + "fetchLogsSuccess": "Logs fetched successfully" } }, + "low": "low", + "maintenance": "maintenance", + "maintenanceRepeat": "Maintenance Repeat", + "maintenanceTableActionMenuDialogTitle": "Do you really want to remove this maintenance window?", + "maintenanceWindowDescription": "Your pings won't be sent during this time frame", + "maintenanceWindowName": "Maintenance Window Name", + "maskedPageSpeedKeyPlaceholder": "*************************************", + "matchMethod": "Match Method", + "mb": "MB", + "mem": "Mem", + "memory": "Memory", + "memoryUsage": "Memory usage", + "menu": { + "changelog": "Changelog", + "discussions": "Discussions", + "docs": "Docs", + "incidents": "Incidents", + "infrastructure": "Infrastructure", + "integrations": "Integrations", + "logOut": "Log out", + "logs": "Logs", + "maintenance": "Maintenance", + "notifications": "Notifications", + "pagespeed": "Pagespeed", + "password": "Password", + "profile": "Profile", + "settings": "Settings", + "statusPages": "Status pages", + "support": "Support", + "team": "Team", + "uptime": "Uptime" + }, + "message": "Message", + "monitor": "monitor", + "monitorActions": { + "export": "Export Monitors", + "import": "Import Monitors", + "title": "Export/Import" + }, + "monitorDisplayName": "Monitor display name", + "monitorState": { + "active": "Active", + "paused": "Paused", + "resumed": "Resumed" + }, + "monitorStatus": { + "checkingEvery": "Checking every {{interval}}", + "down": "down", + "paused": "paused", + "up": "up", + "withCaptureAgent": "with Capture agent {{version}}" + }, + "monitorStatusDown": "Monitor {name} ({url}) is DOWN and not responding", + "monitorStatusUp": "Monitor {name} ({url}) is now UP and responding", + "monitors": "monitors", + "monitorsToApply": "Monitors to apply maintenance window to", + "ms": "ms", + "navControls": "Controls", + "nextWindow": "Next window", + "notFoundButton": "Go to the main dashboard", + "notificationConfig": { + "description": "Select the notifications channels you want to use", + "title": "Notifications" + }, + "notifications": { + "addOrEditNotifications": "Add or edit notifications", + "create": { + "failed": "Failed to create notification", + "success": "Notification created successfully" + }, + "createButton": "Create notification channel", + "createTitle": "Notification channel", + "delete": { + "failed": "Failed to delete notification", + "success": "Notification deleted successfully" + }, + "discord": { + "description": "To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord's incoming Webhooks feature.", + "label": "Discord", + "webhookLabel": "Discord Webhook URL", + "webhookPlaceholder": "https://discord.com/api/webhooks/...", + "webhookRequired": "Discord webhook URL is required" + }, + "edit": { + "failed": "Failed to update notification", + "success": "Notification updated successfully" + }, + "enableNotifications": "Enable {{platform}} notifications", + "fallback": { + "checks": [ + "Alert teams about downtime or performance issues", + "Let engineers know when incidents happen", + "Keep administrators informed of system changes" + ], + "title": "notification channel" + }, + "fetch": { + "failed": "Failed to fetch notifications", + "success": "Notifications fetched successfully" + }, + "integrationButton": "Notification Integration", + "networkError": "Network error occurred", + "slack": { + "description": "To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.", + "label": "Slack", + "webhookLabel": "Webhook URL", + "webhookPlaceholder": "https://hooks.slack.com/services/...", + "webhookRequired": "Slack webhook URL is required" + }, + "telegram": { + "chatIdLabel": "Your Chat ID", + "chatIdPlaceholder": "-1001234567890", + "description": "To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.", + "fieldsRequired": "Telegram token and chat ID are required", + "label": "Telegram", + "tokenLabel": "Your bot token", + "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" + }, + "test": { + "failed": "Failed to send test notification", + "success": "Test notification sent successfully" + }, + "testFailed": "Failed to send test notification", + "testNotification": "Test notification", + "testNotificationDevelop": "Test notification 2", + "testSuccess": "Test notification sent successfully!", + "unsupportedType": "Unsupported notification type", + "webhook": { + "description": "You can set up a custom webhook to receive notifications when incidents occur.", + "label": "Webhooks", + "urlLabel": "Webhook URL", + "urlPlaceholder": "https://your-server.com/webhook", + "urlRequired": "Webhook URL is required" + } + }, + "notifyEmails": "Also notify via email to multiple addresses (coming soon)", + "notifySMS": "Notify via SMS (coming soon)", + "now": "Now", + "os": "OS", + "pageSpeedAddApiKey": "to add your API key.", + "pageSpeedConfigureSettingsDescription": "Here you can select the URL of the host, together with the type of monitor.", + "pageSpeedDetailsPerformanceReport": "Values are estimated and may vary.", + "pageSpeedDetailsPerformanceReportCalculator": "See calculator", + "pageSpeedLearnMoreLink": "Click here", + "pageSpeedMonitor": "PageSpeed monitor", + "pageSpeedWarning": "Warning: You haven't added a Google PageSpeed API key yet. Without it, the PageSpeed monitor won't function.", + "passwordPanel": { + "confirmNewPassword": "Confirm new password", + "currentPassword": "Current password", + "enterCurrentPassword": "Enter your current password", + "enterNewPassword": "Enter your new password", + "newPassword": "New password", + "passwordChangedSuccess": "Your password was changed successfully.", + "passwordInputIncorrect": "Your password input was incorrect.", + "passwordRequirements": "New password must contain at least 8 characters and must have at least one uppercase letter, one lowercase letter, one number and one special character.", + "saving": "Saving..." + }, + "pause": "Pause", + "pingMonitoring": "Ping monitoring", + "pingMonitoringDescription": "Check whether your server is available or not.", + "portMonitoring": "Port monitoring", + "portMonitoringDescription": "Check whether your port is open or not.", + "portToMonitor": "Port to monitor", + "publicLink": "Public link", + "publicURL": "Public URL", "queuePage": { - "title": "Queue", - "refreshButton": "Refresh", - "flushButton": "Flush queue", - "jobTable": { - "title": "Jobs currently in queue", - "idHeader": "Monitor ID", - "urlHeader": "URL", - "typeHeader": "Type", - "activeHeader": "Active", - "lockedAtHeader": "Locked at", - "runCountHeader": "Run count", - "failCountHeader": "Fail count", - "lastRunHeader": "Last run at", - "lastFinishedAtHeader": "Last finished at", - "lastRunTookHeader": "Last run took" - }, - "metricsTable": { - "title": "Queue metrics", - "metricHeader": "Metric", - "valueHeader": "Value" - }, "failedJobTable": { - "title": "Failed jobs", + "failCountHeader": "Fail count", + "failReasonHeader": "Fail reason", + "failedAtHeader": "Last failed at", "monitorIdHeader": "Monitor ID", "monitorUrlHeader": "Monitor URL", + "title": "Failed jobs" + }, + "flushButton": "Flush queue", + "jobTable": { + "activeHeader": "Active", "failCountHeader": "Fail count", - "failedAtHeader": "Last failed at", - "failReasonHeader": "Fail reason" + "idHeader": "Monitor ID", + "lastFinishedAtHeader": "Last finished at", + "lastRunHeader": "Last run at", + "lastRunTookHeader": "Last run took", + "lockedAtHeader": "Locked at", + "runCountHeader": "Run count", + "title": "Jobs currently in queue", + "typeHeader": "Type", + "urlHeader": "URL" + }, + "metricsTable": { + "metricHeader": "Metric", + "title": "Queue metrics", + "valueHeader": "Value" + }, + "refreshButton": "Refresh", + "title": "Queue" + }, + "remove": "Remove", + "removeLogo": "Remove Logo", + "repeat": "Repeat", + "reset": "Reset", + "response": "RESPONSE", + "responseTime": "Response time", + "resume": "Resume", + "roles": { + "admin": "Admin", + "demoUser": "Demo user", + "superAdmin": "Super admin", + "teamMember": "Team member" + }, + "save": "Save", + "selectAll": "Select all", + "sendTestNotifications": "Send test notifications", + "seperateEmails": "You can separate multiple emails with a comma", + "settingsDisabled": "Disabled", + "settingsEmailUser": "Email user - Username for authentication, overrides email address if specified", + "settingsFailedToAddDemoMonitors": "Failed to add demo monitors", + "settingsFailedToClearStats": "Failed to clear stats", + "settingsFailedToDeleteMonitors": "Failed to delete all monitors", + "settingsFailedToSave": "Failed to save settings", + "settingsMonitorsDeleted": "Successfully deleted all monitors", + "settingsPage": { + "aboutSettings": { + "labelDevelopedBy": "Developed by Bluewave Labs", + "labelVersion": "Version", + "title": "About" + }, + "demoMonitorsSettings": { + "buttonAddMonitors": "Add demo monitors", + "description": "Add sample monitors for demonstration purposes.", + "title": "Demo monitors" + }, + "emailSettings": { + "buttonSendTestEmail": "Send test e-mail", + "description": "Configure the email settings for your system. This is used to send notifications and alerts.", + "descriptionTransport": "This builds an SMTP transport for NodeMailer", + "labelAddress": "Email address - Used for authentication", + "labelConnectionHost": "Email connection host - Hostname to use in the HELO/EHLO greeting", + "labelHost": "Email host - Hostname or IP address to connect to", + "labelIgnoreTLS": "Disable STARTTLS: Don't use TLS even if the server supports it", + "labelPassword": "Email password - Password for authentication", + "labelPasswordSet": "Password is set. Click Reset to change it.", + "labelPool": "Enable connection pooling: Reuse existing connections to improve performance", + "labelPort": "Email port - Port to connect to", + "labelRejectUnauthorized": "Reject invalid certificates: Reject connections with self-signed or untrusted certificates", + "labelRequireTLS": "Force STARTTLS: Require TLS upgrade, fail if not supported", + "labelSecure": "Use SSL (recommended): Encrypt the connection using SSL/TLS", + "labelTLSServername": "TLS Servername - Optional Hostname for TLS Validation when host is an IP", + "labelUser": "Email user - Username for authentication, overrides email address if specified", + "linkTransport": "See specifications here", + "placeholderUser": "Leave empty if not required", + "title": "Email" + }, + "pageSpeedSettings": { + "description": "Enter your Google PageSpeed API key to enable Google PageSpeed monitoring. Click Reset to update the key.", + "labelApiKeySet": "API key is set. Click Reset to change it.", + "labelApiKey": "PageSpeed API key", + "title": "Google PageSpeed API key" + }, + "saveButtonLabel": "Save", + "statsSettings": { + "clearAllStatsButton": "Clear all stats", + "clearAllStatsDescription": "Clear all stats. This is irreversible.", + "clearAllStatsDialogConfirm": "Yes, clear all stats", + "clearAllStatsDialogDescription": "Once removed, the monitoring history and stats cannot be retrieved.", + "clearAllStatsDialogTitle": "Do you want to clear all stats?", + "description": "Define how long you want to retain historical data. You can also clear all existing data.", + "labelTTL": "The days you want to keep monitoring history.", + "labelTTLOptional": "0 for infinite", + "title": "Monitor history" + }, + "systemResetSettings": { + "buttonRemoveAllMonitors": "Remove all monitors", + "description": "Remove all monitors from your system.", + "dialogConfirm": "Yes, remove all monitors", + "dialogDescription": "Once removed, the monitors cannot be retrieved.", + "dialogTitle": "Do you want to remove all monitors?", + "title": "System reset" + }, + "timezoneSettings": { + "description": "Select the timezone used to display dates and times throughout the application.", + "label": "Display timezone", + "title": "Display timezone" + }, + "title": "Settings", + "uiSettings": { + "description": "Switch between light and dark mode, or change user interface language.", + "labelLanguage": "Language", + "labelTheme": "Theme mode", + "title": "Appearance" + }, + "urlSettings": { + "description": "Display the IP address or URL of monitor on the public Status page. If it's disabled, only the monitor name will be shown to protect sensitive information.", + "label": "Display IP/URL on status page", + "selectDisabled": "Disabled", + "selectEnabled": "Enabled", + "title": "Monitor IP/URL on Status Page" } }, - "export": { - "title": "Export Monitors", - "success": "Monitors exported successfully!", - "failed": "Failed to export monitors" + "settingsStatsCleared": "Stats cleared successfully", + "settingsSuccessSaved": "Settings saved successfully", + "settingsTestEmailFailed": "Failed to send test email", + "settingsTestEmailFailedWithReason": "Failed to send test email: {{reason}}", + "settingsTestEmailSuccess": "Test email sent successfully", + "settingsTestEmailUnknownError": "Unknown error", + "showAdminLoginLink": "Show \"Administrator? Login Here\" link on the status page", + "showCharts": "Show charts", + "showUptimePercentage": "Show uptime percentage", + "shown": "Shown", + "starPromptDescription": "See the latest releases and help grow the community on GitHub", + "starPromptTitle": "Star Checkmate", + "startTime": "Start time", + "state": "State", + "status": "Status", + "statusBreadCrumbsDetails": "Details", + "statusBreadCrumbsStatusPages": "Status Pages", + "statusCode": "Status code", + "statusMsg": { + "down": "Your site is down.", + "paused": "Monitoring is paused.", + "pending": "Pending...", + "up": "Your site is up." }, - "monitorActions": { - "title": "Export/Import", - "import": "Import Monitors", - "export": "Export Monitors" - } + "statusPageCreateAppearanceDescription": "Define the default look and feel of your public status page.", + "statusPageCreateBasicInfoDescription": "Define company name and the subdomain that your status page points to.", + "statusPageCreateBasicInfoStatusPageAddress": "Your status page address", + "statusPageCreateSelectTimeZoneDescription": "Select the timezone that your status page will be displayed in.", + "statusPageCreateSettings": "If your status page is ready, you can mark it as published.", + "statusPageCreateSettingsCheckboxLabel": "Published and visible to the public", + "statusPageCreateTabsContent": "Status page servers", + "statusPageCreateTabsContentDescription": "You can add any number of servers that you monitor to your status page. You can also reorder them for the best viewing experience.", + "statusPageCreateTabsContentFeaturesDescription": "Show more details on the status page", + "statusPageName": "Status page name", + "statusPageStatus": "A public status page is not set up.", + "statusPageStatusContactAdmin": "Please contact to your administrator", + "statusPageStatusNoPage": "There's no status page here.", + "statusPageStatusNotPublic": "This status page is not public.", + "statusPageStatusServiceStatus": "Service status", + "submit": "Submit", + "teamPanel": { + "cancel": "Cancel", + "email": "Email", + "emailToken": "E-mail token", + "filter": { + "all": "All", + "member": "Member" + }, + "getToken": "Get token", + "inviteDescription": "When you add a new team member, they will get access to all monitors.", + "inviteLink": "Invite link", + "inviteNewTeamMember": "Invite new team member", + "inviteTeamMember": "Invite a team member", + "noMembers": "There are no team members with this role", + "selectRole": "Select role", + "table": { + "created": "Created", + "email": "Email", + "name": "Name", + "role": "Role" + }, + "teamMembers": "Team members" + }, + "testLocale": "testLocale", + "timeZoneInfo": "All dates and times are in GMT+0 time zone.", + "timezone": "Timezone", + "title": "Title", + "tlsErrorIgnored": "TLS/SSL errors ignored", + "total": "Total", + "type": "Type", + "update": "Update", + "uptime": "Uptime", + "uptimeCreate": "The expected value is used to match against response result, and the match determines the status.", + "uptimeCreateJsonPath": "This expression will be evaluated against the reponse JSON data and the result will be used to match against the expected value. See", + "uptimeCreateJsonPathQuery": "for query language documentation.", + "uptimeGeneralInstructions": { + "docker": "Enter the Docker ID of your container. Docker IDs must be the full 64 char Docker ID. You can run docker inspect to get the full container ID.", + "http": "Enter the URL or IP to monitor (e.g., https://example.com/ or 192.168.1.100) and add a clear display name that appears on the dashboard.", + "ping": "Enter the IP address or hostname to ping (e.g., 192.168.1.100 or example.com) and add a clear display name that appears on the dashboard.", + "port": "Enter the URL or IP of the server, the port number and a clear display name that appears on the dashboard." + }, + "url": "URL", + "urlMonitor": "URL to monitor", + "used": "Used", + "webhookSendError": "Error sending webhook notification to {platform}", + "webhookSendSuccess": "Webhook notification sent successfully", + "webhookUnsupportedPlatform": "Unsupported platform: {platform}", + "websiteMonitoring": "Website monitoring", + "websiteMonitoringDescription": "Use HTTP(s) to monitor your website or API endpoint.", + "whenNewIncident": "When there is a new incident,", + "window": "window" } diff --git a/client/src/locales/es.json b/client/src/locales/es.json index b23a57ed3..3579117ae 100644 --- a/client/src/locales/es.json +++ b/client/src/locales/es.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "", "settingsDemoMonitors": "", "settingsDemoMonitorsDescription": "", - "settingsAddDemoMonitors": "", "settingsAddDemoMonitorsButton": "", - "settingsRemoveAllMonitors": "", "settingsRemoveAllMonitorsButton": "", "settingsRemoveAllMonitorsDialogTitle": "", "settingsRemoveAllMonitorsDialogConfirm": "", diff --git a/client/src/locales/fi.json b/client/src/locales/fi.json index 44b56516b..d92fcf8db 100644 --- a/client/src/locales/fi.json +++ b/client/src/locales/fi.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "", "settingsDemoMonitors": "", "settingsDemoMonitorsDescription": "", - "settingsAddDemoMonitors": "", "settingsAddDemoMonitorsButton": "", - "settingsRemoveAllMonitors": "", "settingsRemoveAllMonitorsButton": "", "settingsRemoveAllMonitorsDialogTitle": "", "settingsRemoveAllMonitorsDialogConfirm": "", diff --git a/client/src/locales/fr.json b/client/src/locales/fr.json index 0f218d1c6..729296216 100644 --- a/client/src/locales/fr.json +++ b/client/src/locales/fr.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "Oui, effacer les stats", "settingsDemoMonitors": "", "settingsDemoMonitorsDescription": "", - "settingsAddDemoMonitors": "", "settingsAddDemoMonitorsButton": "", - "settingsRemoveAllMonitors": "", "settingsRemoveAllMonitorsButton": "", "settingsRemoveAllMonitorsDialogTitle": "", "settingsRemoveAllMonitorsDialogConfirm": "", diff --git a/client/src/locales/pt-BR.json b/client/src/locales/pt-BR.json index 38b08adaf..fa6197bb3 100644 --- a/client/src/locales/pt-BR.json +++ b/client/src/locales/pt-BR.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "Sim, limpar todas as estatísticas", "settingsDemoMonitors": "Monitores de demonstração", "settingsDemoMonitorsDescription": "Adicione monitores de genéricos para fins de demonstração.", - "settingsAddDemoMonitors": "Adicionando monitores de demonstração", "settingsAddDemoMonitorsButton": "Adicionar monitores de demonstração", - "settingsRemoveAllMonitors": "Removendo todos os monitores", "settingsRemoveAllMonitorsButton": "Remover todos os monitores", "settingsRemoveAllMonitorsDialogTitle": "Você deseja remover todos os monitores?", "settingsRemoveAllMonitorsDialogConfirm": "Sim, remova todos os monitores", diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json index 65a4fe4a0..908bc73e7 100644 --- a/client/src/locales/ru.json +++ b/client/src/locales/ru.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "Да, очистить всю статистику", "settingsDemoMonitors": "Демо мониторы", "settingsDemoMonitorsDescription": "Здесь вы можете добавлять и удалять демонстрационные мониторы.", - "settingsAddDemoMonitors": "Добавьте демонстрационные мониторы", "settingsAddDemoMonitorsButton": "Добавьте демонстрационные мониторы", - "settingsRemoveAllMonitors": "Удалить все демонстрационные мониторы", "settingsRemoveAllMonitorsButton": "Удалить все демонстрационные мониторы", "settingsRemoveAllMonitorsDialogTitle": "Хотите удалить все мониторы?", "settingsRemoveAllMonitorsDialogConfirm": "Да, очистить все мониторы", diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index ed03d7e6c..c9e224d63 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "Evet, tüm istatistikleri temizle", "settingsDemoMonitors": "Demo monitörler", "settingsDemoMonitorsDescription": "Burada demo monitörler ekleyebilir ve kaldırabilirsiniz.", - "settingsAddDemoMonitors": "Demo monitörler ekle", "settingsAddDemoMonitorsButton": "Demo monitörler ekle", - "settingsRemoveAllMonitors": "Tüm monitörleri kaldır", "settingsRemoveAllMonitorsButton": "Tüm monitörleri kaldır", "settingsRemoveAllMonitorsDialogTitle": "Tüm monitörleri kaldırmak istiyor musunuz?", "settingsRemoveAllMonitorsDialogConfirm": "Evet, tüm monitörleri temizle", diff --git a/client/src/locales/zh-TW.json b/client/src/locales/zh-TW.json index 5f9409f6a..9dfd6effb 100644 --- a/client/src/locales/zh-TW.json +++ b/client/src/locales/zh-TW.json @@ -23,9 +23,7 @@ "settingsClearAllStatsDialogConfirm": "", "settingsDemoMonitors": "", "settingsDemoMonitorsDescription": "", - "settingsAddDemoMonitors": "", "settingsAddDemoMonitorsButton": "", - "settingsRemoveAllMonitors": "", "settingsRemoveAllMonitorsButton": "", "settingsRemoveAllMonitorsDialogTitle": "", "settingsRemoveAllMonitorsDialogConfirm": "", diff --git a/client/vite.config.js b/client/vite.config.js index dc84ce055..96151c0b3 100644 --- a/client/vite.config.js +++ b/client/vite.config.js @@ -1,12 +1,27 @@ -import { defineConfig } from "vite"; +import { defineConfig, loadEnv } from "vite"; import react from "@vitejs/plugin-react"; import svgr from "vite-plugin-svgr"; +import { execSync } from "child_process"; -// https://vitejs.dev/config/ -export default defineConfig({ - base: "/", - plugins: [svgr(), react()], - optimizeDeps: { - include: ["@mui/material/Tooltip", "@emotion/styled"], - }, +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), ""); + let version; + try { + version = + env.VITE_APP_VERSION || + execSync("git describe --tags --abbrev=0").toString().trim(); + } catch (error) { + version = "unknown"; + } + + return { + base: "/", + plugins: [svgr(), react()], + optimizeDeps: { + include: ["@mui/material/Tooltip", "@emotion/styled"], + }, + define: { + __APP_VERSION__: JSON.stringify(version), + }, + }; }); diff --git a/docker/.gitignore b/docker/.gitignore index 81ba730c9..9a6df883a 100755 --- a/docker/.gitignore +++ b/docker/.gitignore @@ -10,4 +10,5 @@ prod/redis/data/* dist/docker-compose-test.yaml /dist-mono/mongo/data/* /dist-mono/redis/data/* +/dist-arm/mongo/data/* *.env diff --git a/docker/dist-arm/docker-compose.yaml b/docker/dist-arm/docker-compose.yaml index f66640f71..921d3b8c1 100644 --- a/docker/dist-arm/docker-compose.yaml +++ b/docker/dist-arm/docker-compose.yaml @@ -1,6 +1,6 @@ services: server: - image: ghcr.io/bluewave-labs/checkmate:backend-dist-mono-multiarch + image: ghcr.io/bluewave-labs/checkmate-backend-mono-multiarch:latest restart: always ports: - "52345:52345" @@ -12,16 +12,7 @@ services: - CLIENT_HOST=http://localhost - JWT_SECRET=my_secret depends_on: - - redis - mongodb - redis: - image: redis:7 - container_name: checkmate-redis - ports: - - "6379:6379" - volumes: - - ./redis/data:/data - restart: unless-stopped mongodb: image: mongo:4.4.18 container_name: checkmate-mongodb diff --git a/docker/dist-mono/docker-compose.yaml b/docker/dist-mono/docker-compose.yaml index fd5d54ddc..0dd97aafb 100755 --- a/docker/dist-mono/docker-compose.yaml +++ b/docker/dist-mono/docker-compose.yaml @@ -12,19 +12,7 @@ services: - CLIENT_HOST=http://localhost - JWT_SECRET=my_secret depends_on: - - redis - mongodb - redis: - image: ghcr.io/bluewave-labs/checkmate-redis:latest - restart: always - volumes: - - ./redis/data:/data - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 30s - timeout: 10s - retries: 5 - start_period: 5s mongodb: image: ghcr.io/bluewave-labs/checkmate-mongo:latest restart: always diff --git a/docker/dist/docker-compose.yaml b/docker/dist/docker-compose.yaml index 580f21e97..ff2f1b7ea 100755 --- a/docker/dist/docker-compose.yaml +++ b/docker/dist/docker-compose.yaml @@ -16,7 +16,6 @@ services: ports: - "52345:52345" depends_on: - - redis - mongodb environment: - DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db?replicaSet=rs0 @@ -25,17 +24,6 @@ services: - JWT_SECRET=my_secret # volumes: # - /var/run/docker.sock:/var/run/docker.sock:ro - redis: - image: ghcr.io/bluewave-labs/checkmate-redis:latest - restart: always - volumes: - - ./redis/data:/data - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 30s - timeout: 10s - retries: 5 - start_period: 5s mongodb: image: ghcr.io/bluewave-labs/checkmate-mongo:latest restart: always diff --git a/server/controllers/authController.js b/server/controllers/authController.js index df4034aef..1d8c2af0e 100755 --- a/server/controllers/authController.js +++ b/server/controllers/authController.js @@ -82,7 +82,7 @@ class AuthController { } const newUser = await this.db.insertUser({ ...req.body }, req.file); - logger.info({ + this.logger.info({ message: this.stringService.authCreateUser, service: SERVICE_NAME, details: newUser._id, @@ -111,7 +111,7 @@ class AuthController { }); }); } catch (error) { - logger.warn({ + this.logger.warn({ message: error.message, service: SERVICE_NAME, method: "registerUser", @@ -412,8 +412,7 @@ class AuthController { // 1. Find all the monitors associated with the team ID if superadmin const result = await this.db.getMonitorsByTeamId({ - query: {}, - params: { teamId: user.teamId.toString() }, + teamId: user.teamId.toString(), }); if (user.role.includes("superadmin")) { @@ -424,13 +423,6 @@ class AuthController { await this.jobQueue.deleteJob(monitor); }) )); - - // 3. Delete team - await this.db.deleteTeam(user.teamId); - // 4. Delete all other team members - await this.db.deleteAllOtherUsers(); - // 5. Delete each monitor - await this.db.deleteMonitorsByUserId(user._id); } // 6. Delete the user by id await this.db.deleteUser(user._id); diff --git a/server/controllers/inviteController.js b/server/controllers/inviteController.js index 3b2212769..3799c58b9 100755 --- a/server/controllers/inviteController.js +++ b/server/controllers/inviteController.js @@ -77,11 +77,16 @@ class InviteController { name: firstname, link: `${clientHost}/register/${inviteToken.token}`, }); - await this.emailService.sendEmail( + const result = await this.emailService.sendEmail( req.body.email, "Welcome to Uptime Monitor", html ); + if (!result) { + return res.error({ + msg: "Failed to send invite e-mail... Please verify your settings.", + }); + } } catch (error) { logger.warn({ message: error.message, diff --git a/server/db/models/User.js b/server/db/models/User.js index 74ee1166e..f180cfb86 100755 --- a/server/db/models/User.js +++ b/server/db/models/User.js @@ -1,6 +1,9 @@ import mongoose from "mongoose"; import bcrypt from "bcryptjs"; import logger from "../../utils/logger.js"; +import Monitor from "./Monitor.js"; +import Team from "./Team.js"; +import Notification from "./Notification.js"; const UserSchema = mongoose.Schema( { @@ -74,6 +77,25 @@ UserSchema.pre("findOneAndUpdate", function (next) { next(); }); +UserSchema.pre("findOneAndDelete", async function (next) { + try { + const userToDelete = await this.model.findOne(this.getFilter()); + if (!userToDelete) return next(); + if (userToDelete.role.includes("superadmin")) { + await Team.deleteOne({ _id: userToDelete.teamId }); + await Monitor.deleteMany({ userId: userToDelete._id }); + await this.model.deleteMany({ + teamId: userToDelete.teamId, + _id: { $ne: userToDelete._id }, + }); + await Notification.deleteMany({ teamId: userToDelete.teamId }); + } + next(); + } catch (error) { + next(error); + } +}); + UserSchema.methods.comparePassword = async function (submittedPassword) { const res = await bcrypt.compare(submittedPassword, this.password); return res; diff --git a/server/middleware/verifyOwnership.js b/server/middleware/verifyOwnership.js index 011b178a4..2040d54ee 100755 --- a/server/middleware/verifyOwnership.js +++ b/server/middleware/verifyOwnership.js @@ -1,15 +1,20 @@ import logger from "../utils/logger.js"; import ServiceRegistry from "../service/serviceRegistry.js"; import StringService from "../service/stringService.js"; +import { ObjectId } from "mongodb"; + const SERVICE_NAME = "verifyOwnership"; const verifyOwnership = (Model, paramName) => { const stringService = ServiceRegistry.get(StringService.SERVICE_NAME); return async (req, res, next) => { const userId = req.user._id; - const documentId = req.params[paramName]; + let documentId = req.params[paramName]; try { + if (typeof documentId === "string") { + documentId = ObjectId.createFromHexString(documentId); + } const doc = await Model.findById(documentId); //If the document is not found, return a 404 error if (!doc) { diff --git a/server/service/emailService.js b/server/service/emailService.js index 89bd4d50f..433fd0871 100755 --- a/server/service/emailService.js +++ b/server/service/emailService.js @@ -137,6 +137,17 @@ class EmailService { }; this.transporter = this.nodemailer.createTransport(emailConfig); + try { + await this.transporter.verify(); + } catch (error) { + this.logger.warn({ + message: "Email transporter verification failed", + service: SERVICE_NAME, + method: "verifyTransporter", + }); + return false; + } + try { const info = await this.transporter.sendMail({ to: to, diff --git a/server/service/stringService.js b/server/service/stringService.js index 499aa769f..6f9ad8cd8 100755 --- a/server/service/stringService.js +++ b/server/service/stringService.js @@ -436,6 +436,18 @@ class StringService { get testEmailSubject() { return this.translationService.getTranslation("testEmailSubject"); } + + get verifyOwnerNotFound() { + return this.translationService.getTranslation("verifyOwnerNotFound"); + } + + get verifyOwnerUnauthorized() { + return this.translationService.getTranslation("verifyOwnerUnauthorized"); + } + + get dbUserNotFound() { + return this.translationService.getTranslation("dbUserNotFound"); + } } export default StringService; diff --git a/server/utils/logger.js b/server/utils/logger.js index 0864176c5..49b875d96 100755 --- a/server/utils/logger.js +++ b/server/utils/logger.js @@ -76,7 +76,7 @@ class Logger { info(config) { const logEntry = this.buildLogEntry("info", config); this.cacheLog(logEntry); - this.logger.info(config.message, logEntry); + this.logger.info(logEntry); } /** @@ -90,7 +90,7 @@ class Logger { warn(config) { const logEntry = this.buildLogEntry("warn", config); this.cacheLog(logEntry); - this.logger.warn(config.message, logEntry); + this.logger.warn(logEntry); } /** @@ -104,7 +104,7 @@ class Logger { error(config) { const logEntry = this.buildLogEntry("error", config); this.cacheLog(logEntry); - this.logger.error(config.message, logEntry); + this.logger.error(logEntry); } /** * Logs a debug message. @@ -117,7 +117,7 @@ class Logger { debug(config) { const logEntry = this.buildLogEntry("debug", config); this.cacheLog(logEntry); - this.logger.debug(config.message, logEntry); + this.logger.debug(logEntry); } cacheLog(entry) {