Commit Graph
9005 Commits
Author SHA1 Message Date
gorkem-bwl 8fbbb1dd4b Revert "refactor(email): set From at transport level instead of per-message"
This reverts commit baa4d693ae.
2026-04-29 15:42:02 -04:00
gorkem-bwl baa4d693ae refactor(email): set From at transport level instead of per-message
The /settings transport preview shows `from` inside the createTransport
JSON, but the implementation was passing it per-message via sendMail.
Switch to passing it as part of the transport config so what the
preview shows matches what is actually built — no behavioural change
for outgoing emails since nodemailer treats transport-level `from` as
the default for every sendMail call.
2026-04-29 15:38:22 -04:00
gorkem-bwl e11553c218 feat(settings): restore From-header preview block under SMTP transport JSON
Brings back the second pre-block I dropped when consolidating the
preview. The transport JSON shows what's handed to nodemailer
createTransport; the From-header block shows the rendered envelope
recipients will see — they answer different questions and both belong.

Conditioned on systemEmailAddress so empty configs don't render an
empty pre.
2026-04-29 15:33:15 -04:00
gorkem-bwl e71892d0bc feat(smtp): add optional sender display name to SMTP configuration
Closes #3600. Previously the From header on test emails and notifications
showed only the raw email address. Adds an optional "Sender name" field
so emails appear from a friendly name like "Checkmate notifications"
<user@example.org>.

## Behaviour
- Field is optional. When empty/null/whitespace, the From header falls
  back to the raw email address — identical to current behaviour, no
  regression for existing installs.
- When set, the email service hands nodemailer { name, address } as the
  message from field. Nodemailer handles RFC-5322 encoding (quotes,
  commas, non-ASCII) so the display name is safe for any input.
- Unsetting works: clearing the input transforms the value to null in
  the Zod parse step, and the settings repository already turns null
  values into a $unset operation.
- Both client and server Zod schemas trim and empty-string-to-null,
  preventing whitespace-only display names from being stored.

## Surfaces
- AppSettings schema, Settings type, EmailTransportConfig pick, server
  Zod validation, client Zod validation, client form defaults, and the
  Settings page form all carry the new systemEmailDisplayName field.
- The transport preview pre-block on /settings now includes a `from`
  key showing exactly what the email service hands nodemailer — the
  string when no display name is set, or { name, address } when it is.
- en.json carries the new label and placeholder. Other locales fall
  back until translated (16 locales pending — separate follow-up).

## Conventions conformance (per docs/frontend-conventions.md)
- The pre-block I touched had three rule #1 violations (sx p,
  borderRadius, backgroundColor); hoisted those to native props using
  theme.shape.borderRadius. Other rule #1 violations elsewhere on this
  page are pre-existing and intentionally left alone.
- No new sx-with-native-equivalents introduced.
- No color="text.X" shorthand introduced.
- No theme module import introduced.
2026-04-29 15:30:16 -04:00
Alexander Holliday 8ca62db317 Merge pull request #3603 from bluewave-labs/chore/bump-version
bump version
2026-04-29 11:51:00 -07:00
Alex Holliday 3bb767b780 bump version 2026-04-29 11:50:28 -07:00
Alexander Holliday 20d27cb984 Merge pull request #3568 from bluewave-labs/feat/status-page-themes-backend
feat(status-page): add theme and themeMode fields (backend)
2026-04-29 11:45:50 -07:00
Alex Holliday 0322a96090 update settings service tests 2026-04-29 11:41:22 -07:00
Alex Holliday 3dbad1743a resolve conflicts 2026-04-29 11:39:08 -07:00
Alex Holliday f4c3ee16db Merge branch 'develop' into feat/status-page-themes-backend 2026-04-29 11:35:55 -07:00
Alexander Holliday a7d5a84206 Merge pull request #3569 from bluewave-labs/feat/status-page-themes-frontend
feat(status-page): four selectable themes for the public status page
2026-04-29 11:35:23 -07:00
Alex Holliday e86734cee9 resolve conflcits 2026-04-29 11:28:57 -07:00
Alex Holliday cc84c37a2d remove planning docs 2026-04-29 11:22:20 -07:00
Alex Holliday e85e9dc2d4 remove duplicated time util 2026-04-29 11:15:33 -07:00
Alex Holliday 1398ab6721 remove dead code 2026-04-29 11:12:35 -07:00
Alex Holliday d32ea7f8c3 remove dead code 2026-04-29 11:07:34 -07:00
Alex Holliday edeed00be6 fix unnecessary cast, remove dead keys 2026-04-29 10:56:57 -07:00
Gorkem Cetin 4c7e96122f Merge pull request #3599 from bluewave-labs/feat/frontend-conventions-eslint
docs(client): document frontend conventions and enforce via ESLint
2026-04-29 13:56:23 -04:00
Alex Holliday 45c02e0f7f unsafe lookup fix 2026-04-29 10:51:40 -07:00
gorkem-bwl aa7051095a docs(client): document frontend conventions and enforce via ESLint
Capture the five recurring code-review patterns from the recent PR series
(#3591–#3596) as enforceable rules so they don't have to be raised again
in review.

## Conventions
- Prefer MUI native props over `sx` (e.g. color={...}, mt={...}, width={...}).
- Use the full theme path for colors: theme.palette.text.secondary, never
  the "text.secondary" shorthand string. The shorthand is invisible to
  grep, which makes future audits and refactors miss callsites.
- No hardcoded numeric or string literals — use LAYOUT, typographyLevels,
  theme.shape.borderRadius, theme.palette tokens.
- Use useTheme() inside components; don't import { theme } from
  @/Utils/Theme/Theme (factory output, not a live mode-aware instance).
- Pair runtime tuples with derived types so they can't drift.

## Files
- docs/frontend-conventions.md — long-form doc with before/after examples
  drawn from the actual review fixes, plus a pre-PR checklist.
- CLAUDE.md — short summary in the Code Conventions section pointing to
  the doc, so it's loaded into agent context at session start.

## ESLint enforcement
- client/.eslintrc.cjs — four no-restricted-syntax selectors for each rule:
  - color="…" / bgcolor="…" / borderColor="…" with a dotted shorthand value
  - sx={{ key: ... }} where key has a native equivalent, only on hoistable
    components (Box, Stack, Typography, Grid, Container, Paper, Card*,
    Divider, Link, Chip) — Dialog/Drawer/Menu etc. only accept sx.
  - import { theme } from "@/Utils/Theme/Theme"
  - Typography fontSize={13} (the body default — drop the prop).
- TypeScript files are now actually parsed: added @typescript-eslint/parser
  and @typescript-eslint/eslint-plugin and a TS override that extends the
  React plugin configs. Several @typescript-eslint/recommended rules
  disabled to avoid noise on the existing codebase.
- client/package.json — lint script now covers .ts/.tsx; new lint-strict
  script for CI use once the codebase is conformant; --max-warnings 0
  removed from `lint` so existing-code warnings don't block the workflow.

## Surface
Running `npm run lint` after this change reports ~280 warnings against
the existing codebase, almost all from rule #1 (sx-vs-native). These are
intentionally warnings, not errors — they surface the work without
blocking. Each warning links to the rule number in the conventions doc
so the reasoning is one click away.
2026-04-29 13:49:58 -04:00
Alex Holliday fcb4fbf277 fix optional types 2026-04-29 10:35:35 -07:00
Alex Holliday 74a12754b6 fix controller architecture 2026-04-29 10:33:46 -07:00
Alexander Holliday fe8213f8bb Merge pull request #3596 from bluewave-labs/feat/settings-remove-monitors-modal
feat(settings): explanatory body in Remove monitors confirmation modal
2026-04-29 10:03:15 -07:00
Alex Holliday cf5691e250 fix build error 2026-04-29 10:01:43 -07:00
Alex Holliday f3b4b908fd Merge branch 'develop' into feat/settings-remove-monitors-modal 2026-04-29 10:00:01 -07:00
Alexander Holliday f58456961b Merge pull request #3595 from bluewave-labs/feat/infrastructure-network-empty-state
feat(infrastructure): show notice when network charts have zero traffic
2026-04-29 09:57:49 -07:00
Alex Holliday 91bdc662ca Merge branch 'develop' into feat/infrastructure-network-empty-state 2026-04-29 09:56:55 -07:00
Alexander Holliday 53e04e6af2 Merge pull request #3594 from bluewave-labs/feat/incidents-page-polish
feat(incidents): consistent typography, icons, and layout across the page
2026-04-29 09:56:27 -07:00
Alex Holliday 301942d0eb normalize 2026-04-29 09:56:01 -07:00
Alex Holliday 29bb1615f5 Merge branch 'develop' into feat/incidents-page-polish 2026-04-29 09:51:06 -07:00
Alexander Holliday afc3ad237f Merge pull request #3593 from bluewave-labs/feat/account-team-modals
feat(account): side-by-side name and password fields in Add Member modal
2026-04-29 09:50:34 -07:00
Alex Holliday e0ac040063 Merge branch 'develop' into feat/account-team-modals 2026-04-29 09:49:23 -07:00
Alexander Holliday f895125145 Merge pull request #3592 from bluewave-labs/refactor/button-input-styling
refactor(inputs): softer button hover, sx-forwarding TextInput, themed FieldLabel
2026-04-29 09:47:31 -07:00
Alex Holliday 63031e938e normalize 2026-04-29 09:47:11 -07:00
Alex Holliday 4b82129199 Merge branch 'develop' into refactor/button-input-styling 2026-04-29 09:46:54 -07:00
Alexander Holliday ccd176ba0b Merge pull request #3591 from bluewave-labs/refactor/dialog-component
refactor(dialog): standard modal layout, NoticeBanner design-element, softer Cancel
2026-04-29 09:43:12 -07:00
Alex Holliday 2dd9218910 normailze dialog and basepage 2026-04-29 09:42:49 -07:00
Alex Holliday 5792ca624e normalize NoticeBanner 2026-04-29 09:37:37 -07:00
gorkem-bwl 5716b5eea4 feat(settings): explanatory body in Remove monitors confirmation modal
The remove-all-monitors confirmation dialog only had a one-line title
and an empty body, which looked awkward and didn't communicate what was
actually about to be deleted alongside the monitors themselves.

- Adds a paragraph explaining that check history, incidents, scheduled
  maintenance windows, and dependent status pages will also be removed,
  with an inline tip to export monitors first to keep a backup.
- The Confirm button now uses confirmColor='error' to make the
  destructive action visually distinct, with a localized
  'Remove monitors' label.
- Translated to all 16 locales, with terminology aligned to each
  locale's existing usage (e.g. zh-CN/zh-TW use 监控/監控 to match the
  existing button label, vi uses 'trình giám sát', etc.).
2026-04-28 23:58:13 -04:00
gorkem-bwl c89dbebe98 feat(infrastructure): show notice when network charts have zero traffic
When Capture runs inside a container (typical for Docker Desktop), the
only visible interfaces are loopback, so every bytes_sent/bytes_recv
counter is zero and the charts render as flat lines without any
explanation. Users couldn't tell whether Capture was unreachable, the
monitor was broken, or there was just genuinely no traffic.

Detect the case where checks exist (chart configs were built) but every
interface across every check reports zero bytesSentPerSecond and
deltaBytesRecv, and render a NoticeBanner above the chart grid
explaining it and suggesting Capture be run on the host.

Adds pages.infrastructure.charts.labels.netNoTraffic to all 16 locales.
2026-04-28 23:57:14 -04:00
gorkem-bwl 5d5d1dbb23 feat(incidents): consistent typography, icons, and layout across the page
- All uppercase headers (Active Incidents, Latest Incidents, Incident
  Statistics, Resolved Incidents, summary card titles, details card
  sections) now use the existing 'eyebrow' typography variant. That's
  the same style used on the Logs page and lives in Theme.ts so future
  tweaks land in one place.
- Latest Incidents and Incident Statistics rows now share a minHeight
  so both cards line up vertically; Latest Incidents items dropped
  their extra dividers and Box wrappers.
- Body text in the summary cards (and the details dialog) uses
  variant=body1 (13px) consistently — previously a mix of body1/body2
  and unspecified Typography.
- All lucide icons in CardSummary go through the design-system <Icon>
  wrapper so they share the project's strokeWidth=1.5 default rather
  than lucide's default 2.
- ControlsIncidentFilter: replaced the missing
  pages.incidents.filters.clearFilters key (which was rendering as
  raw text) with the existing common.buttons.clearFilters.
- CardDetails: extracted local SectionHeading and Cell helpers; switched
  the cards' bare <Typography> cells to variant=body1 + variant=eyebrow
  for headings; dropped redundant title-dividers (eyebrow style already
  separates visually).
2026-04-28 23:56:10 -04:00
gorkem-bwl 93505f006c feat(account): side-by-side name and password fields in Add Member modal
- AddTeamMemberDialog: First name / Last name now share a row, and
  Password / Confirm password share a row. Each field uses sx={flex:1}
  so the row totals match the width of the email/role rows below.
- InviteTeamMemberDialog: drop the redundant mt={theme.spacing(...)}
  workaround on the form Stack (the new Dialog component provides this
  spacing).
- Constants conformance: spacing literals replaced with LAYOUT.XS.
2026-04-28 23:55:27 -04:00
gorkem-bwl a6204b7bf5 Merge branch 'refactor/button-input-styling' into feat/account-team-modals 2026-04-28 23:54:48 -04:00
gorkem-bwl 9c21d71c44 refactor(inputs): softer button hover, sx-forwarding TextInput, themed FieldLabel
- Button.tsx: contained variant's hover now uses HOVER.DARKEN=0.06
  instead of MUI's default 16%, which was visibly heavy on the green
  primary buttons across the app. Also fixes a subtle bug where the
  earlier hover sx merge order silently dropped the boxShadow:'none'
  reset. Added a HOVER token group to constants.ts so the darken value
  has a single source of truth.
- TextInput.tsx: forward the caller's sx to the wrapper Stack when a
  fieldLabel is present (previously it was applied to the inner
  TextField, so flex:1 etc. didn't propagate to the visible width).
  Inner sx now also explicitly width:100% so wrapped inputs don't
  collapse to content width when their parent is a flex row.
- FieldLabel.tsx: drop the hardcoded fontSize:'14px' and use
  variant=body1 (=13px from theme) to match the rest of the app's
  body typography.
2026-04-28 23:54:39 -04:00
gorkem-bwl fef3f2c294 refactor(dialog): standard modal layout, NoticeBanner design-element, softer Cancel
Dialog component:
- Title bar gets a subtle background tint + bottom border. Title is
  variant=h2 weight=600. Description tucks under the title with
  variant=body1 secondary color (replaces MUI's DialogContentText).
- Action bar gets a matching subtle tint + top border. Cancel is now
  outlined (was contained-error, which made every modal's Cancel button
  look destructive). Confirm keeps its color (primary by default,
  caller can pass error for destructive flows).
- Content area sits between with its own breathing room baked in, so
  callers no longer need mt={theme.spacing(...)} workarounds.
- The cancelColor prop is removed; sites that genuinely need a
  destructive Cancel can use confirmColor='error' on the Confirm button
  instead.

NoticeBanner design-element:
- Extracted from the inline alert pattern in PageSpeedKeyPriorityFallback
  into a reusable component with severity=info|warning|error.
- Refactored PageSpeedKeyPriorityFallback to use it.

DialogResolution.tsx: drop the now-removed cancelColor prop and the
mt-Box wrapper that's no longer needed (Dialog provides the spacing).
2026-04-28 23:53:59 -04:00
Gorkem Cetin a617bd340a Merge pull request #3590 from bluewave-labs/feat/game-monitor-helper-link
feat(create-monitor): explain server-side query setup for game monitors
2026-04-28 18:05:41 -04:00
gorkem-bwl 23061e31d1 i18n(create-monitor): translate game description for the remaining 9 locales
Fills in machine translations for ar, cs, fi, fr, ja, pt-BR, tr, uk, vi
so every locale now ships a native translation of the game-monitor
description (including the new server-query setup sentence and the
<gamedigLink> placeholder).
2026-04-28 18:02:57 -04:00
gorkem-bwl 34b1a9cdc2 feat(create-monitor): explain server-side query setup for game monitors
The game monitor type relies on each game's native query protocol — many
require a config file change on the game server (e.g. Minecraft Java
needs `enable-query=true` in `server.properties`). Without that, the
monitor silently fails to reach the server.

Append a sentence to the game-type general settings description that:

- tells the user some games need server-side queries enabled
- points them to the GameDig supported-games list for protocol details

Implementation:

- Use <Trans> with a `gamedigLink` slot so the link renders inline
- Loosen ConfigBox `subtitle` from `string` to `React.ReactNode` so the
  subtitle can host the <Trans> output
- Update all 16 locale files. Six (de, es, ru, th, zh-CN, zh-TW) get a
  full translation of the new sentence; nine empty ones (ar, cs, fi, fr,
  ja, pt-BR, tr, uk, vi) fall back to the English string per the locale
  gap policy
2026-04-28 17:55:24 -04:00
gorkem-bwl bab65770ce refactor(status-page): simplify renderer lookup, extract route prefix, memoize wrapper style
Four small follow-ups from a code review pass:

1. Drop the redundant `?? THEMED_RENDERERS[DEFAULT_STATUS_PAGE_THEME]`
   fallback in Status/index.tsx — the map is now a total Record, so the
   first lookup cannot return undefined.
2. Extract the literal "/status/public" into PUBLIC_STATUS_PAGE_PREFIX in
   Types/StatusPage.ts and reuse from the three runtime call sites
   (Status/index.tsx, HeaderStatusPageControls.tsx, StatusPagesTable.tsx).
   The Routes/index.tsx route definition keeps its string literal — the
   route table is otherwise all literals and the prefix only matters when
   it's interpolated.
3. Delete two narrating comments above the public/admin branches in
   Status/index.tsx — the JSX is self-describing.
4. Move the inline `style` object construction in StatusPageThemeProvider
   into the existing useMemo so the wrapper div receives a stable style
   reference. The previous spread defeated the surrounding memoization on
   every render.
2026-04-28 16:52:16 -04:00
gorkem-bwl ed3645c3d0 refactor(status-page): drop legacy single-design renderer and CSS overrides
The 4 themed renderers (refined, modern, bold, editorial) cover every
StatusPageTheme value and the model defaults to "refined", so the legacy
fallback path in Status/index.tsx was unreachable in practice.

Removing it lets us delete:

- theme-overrides.css (the only remaining CSS file in StatusPage)
- StatusBar / MonitorsList / InfrastructureMetrics (only the legacy
  fallback consumed them)
- The .sp-* className hooks that wired CSS rules into the components

Pure sx via the per-theme styles.ts recipes is now the single source of
truth for every status page surface. Net diff is -801 / +42.

Status/index.tsx now resolves a renderer from the theme map (falling back
to the default theme) and keeps the public-route and admin-preview
branches it already had.
2026-04-28 16:38:35 -04:00