Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f757a44
Merge pull request #103 from CyberDrain/dev
github-actions[bot] Jul 29, 2026
b49e04a
Merge pull request #115 from CyberDrain/dev
github-actions[bot] Jul 29, 2026
274880f
Merge pull request #132 from CyberDrain/dev
github-actions[bot] Jul 30, 2026
7043fe4
Merge pull request #215 from CyberDrain/dev
github-actions[bot] Aug 7, 2026
5cc73a4
Update package.json
KelvinTegelaar Aug 7, 2026
69dc25e
Merge pull request #216 from CyberDrain/dev
github-actions[bot] Aug 7, 2026
aeba101
Update package.json
KelvinTegelaar Aug 7, 2026
8b893e8
Merge pull request #217 from CyberDrain/dev
github-actions[bot] Aug 8, 2026
efd9702
fix: Downgrade Node and jsdom versions in package.json
JohnDuprey Aug 8, 2026
bba17ff
Merge pull request #243 from CyberDrain/dev
github-actions[bot] Aug 10, 2026
3966d88
Update Node.js and jsdom version requirements
JohnDuprey Aug 10, 2026
2091449
Merge pull request #273 from CyberDrain/dev
github-actions[bot] Aug 12, 2026
c6faef7
fix: Downgrade Node and jsdom versions in package.json
JohnDuprey Aug 12, 2026
775c8c7
Merge pull request #295 from CyberDrain/dev
github-actions[bot] Aug 14, 2026
a1b6204
Downgrade Node.js and jsdom versions
JohnDuprey Aug 14, 2026
c79e59f
Merge pull request #352 from CyberDrain/dev
github-actions[bot] Aug 21, 2026
c6d3734
Update package.json dependencies and Node version
KelvinTegelaar Aug 21, 2026
754de69
Merge pull request #366 from CyberDrain/dev
github-actions[bot] Aug 24, 2026
b123894
Downgrade Node and jsdom versions in package.json
JohnDuprey Aug 24, 2026
ed46799
Merge pull request #506 from CyberDrain/dev
github-actions[bot] Sep 7, 2026
7eea3a1
Merge pull request #525 from CyberDrain/dev
github-actions[bot] Sep 8, 2026
da74591
Update Node.js and jsdom version requirements
JohnDuprey Sep 8, 2026
f1b4797
Merge pull request #582 from CyberDrain/dev
github-actions[bot] Sep 11, 2026
645f0c5
Merge pull request #607 from CyberDrain/dev
github-actions[bot] Sep 14, 2026
e406c4f
Downgrade Node and jsdom versions in package.json
JohnDuprey Sep 14, 2026
bfc14ed
ci: add Azure Static Web Apps workflow file
KelvinTegelaar Sep 22, 2026
9ce9443
Update CI/CD workflow to trigger on 'dev' branch
JohnDuprey Sep 22, 2026
b0fb1e1
Merge pull request #723 from CyberDrain/dev
github-actions[bot] Sep 27, 2026
3a5d1be
Update package.json
KelvinTegelaar Sep 27, 2026
4bc6dc1
Merge pull request #759 from CyberDrain/dev
github-actions[bot] Sep 28, 2026
2e93956
Downgrade Node and jsdom versions in package.json
JohnDuprey Sep 28, 2026
316a891
Add main branch to Azure Static Web Apps workflow
JohnDuprey Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
32 changes: 32 additions & 0 deletions .github/workflows/azure-static-web-apps-red-stone-0d8c5ed03.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Azure Static Web Apps CI/CD

on:
push:
branches:
- dev
- main

jobs:
build_and_deploy_job:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
runs-on: ubuntu-latest
name: Build and Deploy Job
steps:
- uses: actions/checkout@v3
with:
submodules: true
lfs: false
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_RED_STONE_0D8C5ED03 }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
action: "upload"
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: "/" # App source code path
api_location: "" # Api source code path - optional
output_location: "/out" # Built app content directory - optional
###### End of Repository/Build Configurations ######

82 changes: 82 additions & 0 deletions .storybook/main.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'

const dirname = path.dirname(fileURLToPath(import.meta.url))

/** @type { import('@storybook/react-vite').StorybookConfig } */
const config = {
stories: ['../tests/**/*.mdx', '../tests/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-a11y',
'@storybook/addon-docs',
'@storybook/addon-themes',
'@storybook/addon-vitest',
'msw-storybook-addon',
],
features: {
sidebarOnboardingChecklist: false,
},
core: {
disableWhatsNewNotifications: true,
},
framework: '@storybook/react-vite',
async viteFinal(config) {
return {
...config,
plugins: [
...(config.plugins || []),
{
// Real Microsoft auth can't run in Storybook (MSAL popups, device codes),
// so every import of CIPPM365OAuthButton resolves to a mock that reports
// instant auth success. Relative imports can't be object-alias'd, hence a
// resolveId hook instead of an entry in resolve.alias below.
name: 'cipp-mock-m365-oauth-button',
enforce: 'pre',
resolveId(source) {
if (source.endsWith('CippComponents/CIPPM365OAuthButton')) {
return path.resolve(dirname, '../tests/mocks/cipp-m365-oauth-button.jsx')
}
},
},
],
resolve: {
...config.resolve,
// CIPP is a Next.js app but uses @storybook/react-vite because @storybook/nextjs
// doesn't work with this project. These aliases replace Next.js modules with
// lightweight mocks so components render without a Next.js runtime.
alias: {
...config.resolve?.alias,
'next/dynamic': path.resolve(dirname, '../tests/mocks/next-dynamic.jsx'),
'next/router': path.resolve(dirname, '../tests/mocks/next-router.js'),
'next/navigation': path.resolve(dirname, '../tests/mocks/next-navigation.js'),
'next/head': path.resolve(dirname, '../tests/mocks/next-head.js'),
'next/image': path.resolve(dirname, '../tests/mocks/next-image.js'),
'next/link': path.resolve(dirname, '../tests/mocks/next-link.js'),
},
},
define: {
...(config.define || {}),
// Next.js components reference process.env and global, these don't exist in a
// pure Vite browser context, so we shim them to avoid ReferenceErrors.
'process.env': '{}',
global: 'window',
},
build: {
...config.build,
rollupOptions: {
...config.build?.rollupOptions,
onwarn(warning, warn) {
// Suppress "use client" directive warnings from React Server Components-aware
// libraries (e.g. @mui/material). These directives are harmless in Storybook
// since everything runs client-side, but Rollup treats them as errors.
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') return
warn(warning)
},
},
},
}
},
staticDirs: ['../public'],
}

export default config
107 changes: 107 additions & 0 deletions .storybook/preview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react'
import { ThemeProvider } from '@mui/material/styles'
import CssBaseline from '@mui/material/CssBaseline'
import { withThemeFromJSXProvider } from '@storybook/addon-themes'
import { Provider } from 'react-redux'
import { configureStore } from '@reduxjs/toolkit'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { setupWorker } from 'msw/browser'
import { mswLoader } from 'msw-storybook-addon/csf3'
import { LocalizationProvider } from '@mui/x-date-pickers'
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'
import TimeAgo from 'javascript-time-ago'
import en from 'javascript-time-ago/locale/en.json'
import { createTheme } from '../src/theme'
import { SettingsContext } from '../src/contexts/settings-context'
import { handlers } from '../tests/mocks/handlers'
// require.context polyfill must load in the storybook dev server too, the vitest
// setup files don't run there
import '../tests/mocks/require-context'

const mockSettings = {
currentTenant: 'testdomain.com',
currentTheme: { value: 'light', label: 'light' },
paletteMode: 'light',
direction: 'ltr',
pinNav: true,
showDevtools: false,
handleUpdate: () => {},
handleReset: () => {},
isCustom: false,
}

TimeAgo.addDefaultLocale(en)

const darkTheme = createTheme({
colorPreset: 'orange',
direction: 'ltr',
paletteMode: 'dark',
contrast: 'high',
})

const lightTheme = createTheme({
colorPreset: 'orange',
direction: 'ltr',
paletteMode: 'light',
contrast: 'high',
})

const mockStore = configureStore({
reducer: {
toasts: (state = { toasts: [] }) => state,
},
})

/** @type { import('@storybook/react').Preview } */
const preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
msw: {
handlers,
},
},
// custom setup instead of the addon default: 'bypass' silences MSW warnings for
// unhandled requests (Vite module imports, static assets, unmocked /api routes),
// 'quiet' suppresses console logging for handled requests
loaders: [
mswLoader(async () => {
const worker = setupWorker()
await worker.start({ onUnhandledRequest: 'bypass', quiet: true })
return worker
}),
],
decorators: [
withThemeFromJSXProvider({
themes: {
light: lightTheme,
dark: darkTheme,
},
defaultTheme: 'light',
Provider: ThemeProvider,
GlobalStyles: CssBaseline,
}),
(Story) => {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
})
return (
<Provider store={mockStore}>
<QueryClientProvider client={queryClient}>
<SettingsContext.Provider value={mockSettings}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Story />
</LocalizationProvider>
</SettingsContext.Provider>
</QueryClientProvider>
</Provider>
)
},
],
}

export default preview
6 changes: 6 additions & 0 deletions .storybook/vitest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { configure } from 'storybook/test'
import '../tests/mocks/require-context'

// coverage instrumentation and vite 8's slower module serving push lazy chunks
// and fetches past the 1s default (and past 10s when the full suite runs)
configure({ asyncUtilTimeout: 30000 })
10 changes: 10 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ const eslintConfig = defineConfig([
maximum: 10,
},
],
// JSX must live in .jsx files: vite 8's oxc transform (vitest/storybook)
// decides JSX handling purely by file extension
'react/jsx-filename-extension': ['error', { extensions: ['.jsx'] }],
},
},
{
// csf meta is an anonymous default export by convention
files: ['tests/**/*.stories.jsx', '.storybook/**'],
rules: {
'import/no-anonymous-default-export': 'off',
},
},
// Override default ignores of eslint-config-next.
Expand Down
1 change: 0 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const config = {
webpackMemoryOptimizations: true,
preloadEntriesOnStart: false,
turbopackFileSystemCacheForDev: false,
turbopackMemoryLimit: 4096,
},
images: {
unoptimized: true,
Expand Down
Loading
Loading