Commit Graph
1656 Commits
Author SHA1 Message Date
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
Alex Holliday 45c02e0f7f unsafe lookup fix 2026-04-29 10:51:40 -07:00
Alex Holliday fcb4fbf277 fix optional types 2026-04-29 10:35:35 -07: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
gorkem-bwl ab9e722caa refactor(status-page): consolidate font stacks and pill recipes
Second /simplify pass picked up:
- pillHardware in refined and modern hardcoded blue hex codes (#60a5fa, #1d4ed8, #2563eb) while bold and editorial already used the green token system. Switch refined and modern to tokens.up / tokens.upSoft so all four themes are consistent and the public status page no longer leaks blue
- pill and pillHardware in refined and modern duplicated the shared 6 typography fields (fontSize, textTransform, letterSpacing, padding, borderRadius, fontWeight). Extract a pillBase constant per theme and spread, leaving only the colour deltas on each
- The 4 themes each defined their own font-stack constants. Consolidate them in themes/shared/fontStacks.ts (SANS_STACK, BOLD_SANS_STACK, SERIF_STACK, EDITORIAL_SECONDARY_SANS_STACK, MONO_STACK) and import. Drops 6 duplicated literal stacks
- modern dark-mode card hover used the light-mode shadow as a fallback. Add darkShadowHover and pick it up via cardHoverShadow when isDark
- refined and editorial styles factories silence their unused isDark parameter with `void isDark` instead of an underscore prefix; bold and modern still use it actively
2026-04-27 18:52:53 -04:00
gorkem-bwl 4f8f2f1422 refactor(status-page): tighten the bold/modern/editorial conversion
Apply review feedback:
- Editorial chartSwitch: drop the per-button isFirst flag and put the divider on the parent via "& > button + button { borderLeft }"; chartSwitchButton(active) now matches bold/modern's signature
- Drop the empty company: {} entries in bold/modern and the wrapper span around the company name; the parent brand row already styles it
- Editorial styles factory: keep the (tokens, isDark) signature for cross-theme uniformity but acknowledge the unused isDark with a void-statement instead of an underscore prefix
2026-04-27 18:45:45 -04:00
gorkem-bwl c6c50063d8 refactor(status-page): convert bold, modern and editorial themes to MUI sx
Finishes the migration started for refined. Each theme now consumes the same pattern:

- A typed *Styles interface that names every entry the page consumes (no `as Function` casts at the call site)
- A *Styles factory that takes (tokens, isDark) and returns sx recipes derived from existing tokens.ts plus the shared toneColor/toneSoft helpers in shared/overallStatus
- A useMemo around the factory call so MUI's sx processor sees referential equality across renders that don't change tokens
- modern.css's keyframes (pulse + staggered fade-in + reduced-motion guard) ported via @mui/system keyframes inside the modern styles factory
- bold.css's hero glow + conic logo + pseudo-elements ported as inline sx via "&::before" / "& > *" selectors
- editorial.css's serif typography + hairline dividers + flat rectangular badges ported as plain sx with the serif/sans family stacks named at module scope

Drop the four .css files (~1789 lines) along with the className= attributes and the import "./*.css" lines in each StatusPage component.

The shared themed components (ThemedHeatmap, ThemedHistogram, ThemedInfrastructure) lose their legacy classPrefix branch entirely now that no theme uses it. The dual-API gate is gone; there is one path.

Verified: tsc --noEmit clean, prettier clean.

Note: theme-overrides.css remains for the legacy non-themed status page components (StatusBar, MonitorsList, HeaderStatusPageControls). That's separate scope from the four-theme work the reviewer flagged; can be migrated in a follow-up.
2026-04-27 18:39:42 -04:00
gorkem-bwl b95d8886b9 refactor(status-page): tighten the refined-theme conversion
Apply review feedback:
- Type the styles factory's return as a named RefinedStyles interface so the consumer no longer needs `as Function` / `as any` casts on factory entries
- Lift toneColor / toneSoft to shared/overallStatus alongside the existing OverallTone type — the next three themes will need the same mapping
- Reuse heatLevel() in the legacy classPrefix branch of ThemedInfrastructure so both API paths share one threshold table
- Memoize the styles map in RefinedStatusPage so MUI's sx processor sees referential equality across renders that don't actually change tokens
- Make the dual-API gate in ThemedHeatmap / ThemedHistogram require ALL relevant sx props together so a partial migration can't silently fall back to the legacy class path
2026-04-27 18:30:04 -04:00
gorkem-bwl 163f5ec1ec refactor(status-page): convert refined theme to MUI sx + theme tokens
The reviewer's feedback on this PR is that the themes ship hardcoded class names against per-theme CSS files instead of following the project's MUI sx + theme.spacing()/palette pattern. This commit handles the refined theme as a proof of concept; the other three follow.

What changed
- New src/Pages/StatusPage/Status/themes/refined/styles.ts: a single function (tokens, isDark) -> sx recipes that mirror every rule in the deleted refined.css. All values are derived from the tokens already declared in tokens.ts so the colour/spacing source of truth doesn't change.
- RefinedStatusPage.tsx: drops the className= attributes and the import "./refined.css" in favour of sx={styles.x} drawn from the recipe map. Hardcoded class strings gone.
- refined.css: deleted (was 420 lines).
- Shared themed components (ThemedHeatmap, ThemedHistogram, ThemedInfrastructure): grew an opt-in sx-based API alongside the existing classPrefix one. The new API is what refined uses; bold / modern / editorial keep working unchanged on the legacy classPrefix path until they are migrated, after which the legacy code path is removed.

Verified
- tsc --noEmit clean
- prettier clean
- Pre-existing vite build error on this branch (flag-icons resolve, unrelated) is untouched

Next
- Convert the bold, modern and editorial themes the same way and remove the legacy classPrefix branch from the shared components.
2026-04-27 18:21:31 -04:00
gorkem-bwl 944ee74a1d feat(status-page): four selectable themes for the public status page
Adds four fully-designed visual themes for the public status page
(refined | modern | bold | editorial) with a light/dark mode selector,
admin preview in a mock browser frame, and a shared theme provider
that keeps the component tree unified while letting each theme own
its visual identity.

## Selectable themes
- Refined — clean, flat cards, soft shadows, colored status dot.
- Modern — flat surfaces with a pulsing status dot and staggered
  fade-in cards.
- Bold — conic-gradient logo, 34px hero title with a check disc,
  subtle dual-radial glow on dark mode, accent-green hover border.
- Editorial — serif headings, narrow newspaper column, 'Service
  Report' eyebrow + title, flat rectangular badges and dateline.

## Architecture
- Single `StatusPageThemeProvider` hosts CSS custom-property tokens
  per theme and resolves light/dark based on admin-forced mode,
  falling back to `prefers-color-scheme` with a matchMedia listener.
- Each theme owns only its `*StatusPage.tsx` + scoped CSS file.
  The heatmap, histogram, and infrastructure renderers are shared
  across all four themes (parameterized by a `classPrefix`) to avoid
  the 12-file duplication the initial draft had.
- Renderer lookup table in `Status/index.tsx` replaces a 4-way
  ternary chain; unknown themes fall through to the legacy renderer.
- `resolveOverallStatus`, `statusBadgeKey`, `monoFirstChar`, and
  `monitorBadgeTone` are extracted to `themes/shared/overallStatus.tsx`.

## Admin UX
- `ThemePicker` uses the project's `RadioWithDescription` and
  `Select` components — one radio card per theme plus an Auto/
  Light-only/Dark-only mode dropdown.
- `BrowserFrame` wraps the preview in the admin panel with a mock
  chrome (traffic lights + URL bar) that adopts the status page's
  theme tokens. Edge-to-edge fill with no gray bleed.
- Public route renders the theme directly on the viewport with the
  document body painted to the theme background, reverted on unmount.

## Performance & polish
- Histogram's derived stats (padded array, max, avg, peak) are
  memoized on `checks`; `max` is reused for `peak` instead of
  computing twice.
- Editorial's dateline is wrapped in `useMemo` so the 10s poll
  doesn't rerender "April 23, 2026" as a changing string.
- Provider's `setSystemMode` reconciliation uses the updater form
  to avoid an extra render when the value is unchanged.
- `monoFirstChar` no longer uses a non-null assertion.

## Form plumbing
- `useStatusPageForm` defaults include `theme` + `themeMode`.
- `Validation/statusPage.ts` accepts both as optional zod enums.
- `Pages/StatusPage/Create/index.tsx` appends both to FormData on
  create and update.

## CLAUDE.md
- Dev port note: local client runs on 10001 (5173 is used by a
  different local project); server `CLIENT_HOST` is set to match.
2026-04-23 22:51:40 -04:00
Alex Holliday 559288fceb bump version 2026-04-23 10:14:05 -07:00
Alex Holliday cbd82e29af bump version 2026-04-23 09:49:34 -07:00
Alex Holliday 5f12459bfd explicit import 2026-04-20 11:48:48 -07:00
Alex Holliday 27e866ba08 use lazy get 2026-04-20 11:47:43 -07:00
Alex Holliday f7a2b2af54 Merge branch 'develop' into fix/hide-register-tip-on-login 2026-04-20 11:28:25 -07:00
Alexander Holliday 984a611d19 Merge pull request #3534 from egeoztass/feat/twilio-sms-notification
feat: add Twilio SMS notification channel
2026-04-20 10:54:12 -07:00
gorkem-bwl 39011e2e33 style: apply prettier formatting 2026-04-20 13:53:50 -04:00
gorkem-bwl 4998fe4c94 fix: hide register tip on login and redirect to setup when no super admin (#3556)
## Changes
- Removed the "Register here" link from the login page — it misled users into thinking public registration was open.
- Added redirect from /login to /register when no super admin exists (initial setup).
- Added an info alert on the register page clarifying the page is only for initial setup; additional users are invited from team settings. Hidden for the invite-token flow.
- Extracted shared useSuperAdminRedirect hook to dedupe identical fetch/redirect logic across Login and Register.

## Benefits
- Clearer UX: login page no longer suggests self-registration is available post-setup.
- Correct routing on fresh installs: users land on the registration page instead of a login page they can't use.
2026-04-20 13:50:36 -04:00
egeoztassandClaude Opus 4.6 d5d6797f91 fix: use dedicated Twilio fields and add service switch case tests
- Added `accountSid` and `twilioPhoneNumber` fields to Notification
  type, MongoDB model, and frontend type instead of reusing
  `address` and `homeserverUrl`
- Updated provider, validation, form hook, and form UI to use new fields
- Added Pushover and Twilio to notificationsService routing tests
  (both handleNotifications and sendTestNotification)
- All 59 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 23:11:11 +03:00
Alexander Holliday fa6aef1e86 Merge pull request #3518 from ZeinebMegaadi/fix/showing-down-for-down-monitors
Fix: added "down" display on down monitors instead of "Active for:..."
2026-04-17 10:17:34 -07:00
ZeinebMegaadi 26077151ef fix: added maintenance state 2026-04-16 20:54:09 +01:00
egeoztassandClaude Opus 4.6 9210259511 feat: add Twilio SMS notification channel
Adds Twilio SMS as a new notification channel, allowing users to
receive SMS alerts via the Twilio API.

Backend: provider using HTTP Basic Auth, type registration, validation,
service wiring. Uses existing fields: address (Account SID),
accessToken (Auth Token), homeserverUrl (From number), phone (To number).
Frontend: form UI with 4 fields, validation, i18n keys.
Tests: 18 provider tests + updated service test constructor.

Closes #3095

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 21:46:40 +03:00
Alexander Holliday e9a0914fad Merge pull request #3530 from egeoztass/feat/pushover-notification
feat: add Pushover notification channel
2026-04-16 11:21:43 -07:00
SkyKingPX 5920b92869 Run npm format 2026-04-16 19:55:17 +02:00
ZeinebMegaadi 58532d1ff6 fix(monitors): handle initializing and breached states in stat box 2026-04-16 18:09:05 +01:00
SkyKingPX 0d163e7100 Change Breached to exceeded thresholds 2026-04-16 18:56:06 +02:00
egeoztassandClaude Opus 4.6 cc1b6df8f2 style: run prettier on notification create page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 16:55:30 +03:00
egeoztassandClaude Opus 4.6 97353bc7d2 feat: add Pushover notification channel
Adds Pushover as a new notification channel, allowing users to receive
push notifications on their devices via the Pushover API.

Backend: provider, type registration, validation, service wiring
Frontend: form UI with app token and user key fields, validation, i18n
Tests: full unit test suite (15 tests, 100% coverage on provider)

Closes #3445

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 16:25:24 +03:00
SkyKing_PX 675ec40836 Merge branch 'bluewave-labs:develop' into feat/improved-status-bar-messages 2026-04-16 13:40:10 +02:00
SkyKingPX 7b164e4df5 Make requested changes 2026-04-16 13:37:54 +02:00
Alex Holliday be3b7c2e86 add demo role to list of roles 2026-04-15 13:54:05 -07:00
Alex Holliday 564b356115 tighten streak time coniditional 2026-04-15 11:06:30 -07:00
ZeinebMegaadi b482e871a3 updated fix for same issue 2026-04-15 16:12:10 +01:00
ZeinebMegaadi f6222014b7 Fix: correct Active for display on down monitors 2026-04-15 14:51:12 +01:00
SkyKingPX a8339c0169 Improve status bar messages on public status pages 2026-04-14 19:32:05 +02:00
Alex Holliday 22498756cd add remaining zh-tw strings 2026-04-07 09:46:07 -07:00
gorkem-bwl 96f9360280 style: format migration script with prettier 2026-04-03 23:43:34 -04:00
gorkem-bwl eb4a92c84f fix: restructure and translate all i18n locale files
All 15 non-English locale files had a structural mismatch with en.json:
- en.json used nested keys (common.buttons.cancel)
- Other locales used flat keys (cancel, DeleteAccountButton)
- Result: 0.3% effective translation coverage at runtime

## Changes

Migration script (client/scripts/migrate-locales.ts):
- Restructures all locale files to match en.json's nested key structure
- Recovers existing translations via safe key-matching strategies
- Backs up originals to locales/backup/

Translation of all 15 languages:
- ar (94.6%), cs (91.6%), de (89.4%), es (92.6%), fi (94.2%)
- fr (86.7%), ja (93.3%), pt-BR (91.0%), ru (93.0%), th (93.4%)
- tr (91.9%), uk (94.3%), vi (92.5%), zh-CN (94.0%), zh-TW (94.2%)

Keys intentionally left in English are technical terms (HTTP, CPU,
Docker, gRPC, etc.), placeholder examples, and brand names.

en.json was NOT modified.
2026-04-03 23:35:14 -04:00
LeC-D 04dfff4ebd fix(notifications): remove redundant defaultValue prop and fix incident URL in telegram provider
- Remove redundant 'defaultValue' prop on Telegram chat ID Controller in create/index.tsx;
  the form already initialises via 'defaultValues: defaults' at the useForm level, making
  the per-Controller prop unnecessary and inconsistent with the reviewer's expectation.
- Fix 'View Incident' URL in telegram.ts: was pointing to the infrastructure details page
  (/infrastructure/:id) instead of the incidents page (/incidents/:id).
2026-03-27 14:19:27 -04:00
LeC-D 13a7ae82e3 fix(notifications): remove type casts with exhaustive type narrowing in useNotificationForm
Replace the loose NotificationDefaults intermediate type and 'as NotificationFormData'
cast with an exhaustive buildDefaults() helper that narrows each branch of the
discriminated union explicitly. TypeScript now infers the return type correctly from
the discriminated union without any casts, satisfying strong typing for all channels
(email, slack, discord, webhook, pager_duty, teams, matrix, telegram).
2026-03-26 14:07:50 -04:00
Leandre Chamberland-Dozois 4c94a7c21e fix: resolve TypeScript build errors in notification form types 2026-03-25 19:13:37 -04:00
LeC-D 40968c370b refactor(notifications): hoist default values, remove else block in useNotificationForm
Per @ajhollid review: define defaults up-front with a NotificationDefaults type
and eliminate the trailing else branch entirely. The if/else-if blocks only
override when the type is matrix or telegram.
2026-03-25 18:06:26 -04:00
LeC-DandClaude Opus 4.6 a864bc0c05 fix: run format and fix build errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:52:48 -04:00
LeC-D fe242b1977 fix: replace nested ternaries and remove type casts per review
- useNotificationForm: replace nested ternary with if/else if/else block
- TelegramProvider: type error as unknown and access properties safely
  via instanceof checks instead of casting to HTTPError
2026-03-25 14:03:49 -04:00