Skip to content

Commit 81e8cbf

Browse files
Merge branch 'KelvinTegelaar:main' into main
2 parents 4d12396 + efd9702 commit 81e8cbf

571 files changed

Lines changed: 44063 additions & 10305 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.storybook/main.mjs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import path from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
4+
const dirname = path.dirname(fileURLToPath(import.meta.url))
5+
6+
/** @type { import('@storybook/react-vite').StorybookConfig } */
7+
const config = {
8+
stories: ['../tests/**/*.mdx', '../tests/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
9+
addons: [
10+
'@storybook/addon-a11y',
11+
'@storybook/addon-docs',
12+
'@storybook/addon-themes',
13+
'@storybook/addon-vitest',
14+
'msw-storybook-addon',
15+
],
16+
features: {
17+
sidebarOnboardingChecklist: false,
18+
},
19+
core: {
20+
disableWhatsNewNotifications: true,
21+
},
22+
framework: '@storybook/react-vite',
23+
async viteFinal(config) {
24+
return {
25+
...config,
26+
plugins: [
27+
...(config.plugins || []),
28+
{
29+
// Real Microsoft auth can't run in Storybook (MSAL popups, device codes),
30+
// so every import of CIPPM365OAuthButton resolves to a mock that reports
31+
// instant auth success. Relative imports can't be object-alias'd, hence a
32+
// resolveId hook instead of an entry in resolve.alias below.
33+
name: 'cipp-mock-m365-oauth-button',
34+
enforce: 'pre',
35+
resolveId(source) {
36+
if (source.endsWith('CippComponents/CIPPM365OAuthButton')) {
37+
return path.resolve(dirname, '../tests/mocks/cipp-m365-oauth-button.jsx')
38+
}
39+
},
40+
},
41+
],
42+
resolve: {
43+
...config.resolve,
44+
// CIPP is a Next.js app but uses @storybook/react-vite because @storybook/nextjs
45+
// doesn't work with this project. These aliases replace Next.js modules with
46+
// lightweight mocks so components render without a Next.js runtime.
47+
alias: {
48+
...config.resolve?.alias,
49+
// stub for mui-tiptap's uninstalled required peer @tiptap/extension-image
50+
'@tiptap/extension-image': path.resolve(
51+
dirname,
52+
'../tests/mocks/tiptap-extension-image.js',
53+
),
54+
'next/dynamic': path.resolve(dirname, '../tests/mocks/next-dynamic.js'),
55+
'next/router': path.resolve(dirname, '../tests/mocks/next-router.js'),
56+
'next/navigation': path.resolve(dirname, '../tests/mocks/next-navigation.js'),
57+
'next/head': path.resolve(dirname, '../tests/mocks/next-head.js'),
58+
'next/image': path.resolve(dirname, '../tests/mocks/next-image.js'),
59+
'next/link': path.resolve(dirname, '../tests/mocks/next-link.js'),
60+
},
61+
},
62+
define: {
63+
...(config.define || {}),
64+
// Next.js components reference process.env and global, these don't exist in a
65+
// pure Vite browser context, so we shim them to avoid ReferenceErrors.
66+
'process.env': '{}',
67+
global: 'window',
68+
},
69+
esbuild: {
70+
...config.esbuild,
71+
// The codebase uses .js files with JSX syntax. Vite's default esbuild loader
72+
// only handles JSX in .jsx files, so we override the loader for all .js files.
73+
jsx: 'automatic',
74+
jsxImportSource: 'react',
75+
loader: 'jsx',
76+
include: /(src|tests|\.storybook)\/.*\.(js|jsx)$/,
77+
exclude: [],
78+
},
79+
build: {
80+
...config.build,
81+
rollupOptions: {
82+
...config.build?.rollupOptions,
83+
onwarn(warning, warn) {
84+
// Suppress "use client" directive warnings from React Server Components-aware
85+
// libraries (e.g. @mui/material). These directives are harmless in Storybook
86+
// since everything runs client-side, but Rollup treats them as errors.
87+
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') return
88+
warn(warning)
89+
},
90+
},
91+
},
92+
optimizeDeps: {
93+
...config.optimizeDeps,
94+
// Same JSX-in-.js fix as above, but for Vite's dependency pre-bundling step
95+
// (esbuild runs separately for optimizeDeps vs transform).
96+
esbuildOptions: {
97+
...config.optimizeDeps?.esbuildOptions,
98+
jsx: 'automatic',
99+
jsxImportSource: 'react',
100+
loader: {
101+
'.js': 'jsx',
102+
'.jsx': 'jsx',
103+
},
104+
},
105+
},
106+
}
107+
},
108+
staticDirs: ['../public'],
109+
}
110+
111+
export default config

.storybook/preview.jsx

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import React from 'react'
2+
import { ThemeProvider } from '@mui/material/styles'
3+
import CssBaseline from '@mui/material/CssBaseline'
4+
import { withThemeFromJSXProvider } from '@storybook/addon-themes'
5+
import { Provider } from 'react-redux'
6+
import { configureStore } from '@reduxjs/toolkit'
7+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
8+
import { setupWorker } from 'msw/browser'
9+
import { mswLoader } from 'msw-storybook-addon/csf3'
10+
import { LocalizationProvider } from '@mui/x-date-pickers'
11+
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'
12+
import TimeAgo from 'javascript-time-ago'
13+
import en from 'javascript-time-ago/locale/en.json'
14+
import { createTheme } from '../src/theme'
15+
import { SettingsContext } from '../src/contexts/settings-context'
16+
import { handlers } from '../tests/mocks/handlers'
17+
// require.context polyfill must load in the storybook dev server too, the vitest
18+
// setup files don't run there
19+
import '../tests/mocks/require-context'
20+
21+
const mockSettings = {
22+
currentTenant: 'testdomain.com',
23+
currentTheme: { value: 'light', label: 'light' },
24+
paletteMode: 'light',
25+
direction: 'ltr',
26+
pinNav: true,
27+
showDevtools: false,
28+
handleUpdate: () => {},
29+
handleReset: () => {},
30+
isCustom: false,
31+
}
32+
33+
TimeAgo.addDefaultLocale(en)
34+
35+
const darkTheme = createTheme({
36+
colorPreset: 'orange',
37+
direction: 'ltr',
38+
paletteMode: 'dark',
39+
contrast: 'high',
40+
})
41+
42+
const lightTheme = createTheme({
43+
colorPreset: 'orange',
44+
direction: 'ltr',
45+
paletteMode: 'light',
46+
contrast: 'high',
47+
})
48+
49+
const mockStore = configureStore({
50+
reducer: {
51+
toasts: (state = { toasts: [] }) => state,
52+
},
53+
})
54+
55+
/** @type { import('@storybook/react').Preview } */
56+
const preview = {
57+
parameters: {
58+
controls: {
59+
matchers: {
60+
color: /(background|color)$/i,
61+
date: /Date$/i,
62+
},
63+
},
64+
msw: {
65+
handlers,
66+
},
67+
},
68+
// custom setup instead of the addon default: 'bypass' silences MSW warnings for
69+
// unhandled requests (Vite module imports, static assets, unmocked /api routes),
70+
// 'quiet' suppresses console logging for handled requests
71+
loaders: [
72+
mswLoader(async () => {
73+
const worker = setupWorker()
74+
await worker.start({ onUnhandledRequest: 'bypass', quiet: true })
75+
return worker
76+
}),
77+
],
78+
decorators: [
79+
withThemeFromJSXProvider({
80+
themes: {
81+
light: lightTheme,
82+
dark: darkTheme,
83+
},
84+
defaultTheme: 'light',
85+
Provider: ThemeProvider,
86+
GlobalStyles: CssBaseline,
87+
}),
88+
(Story) => {
89+
const queryClient = new QueryClient({
90+
defaultOptions: { queries: { retry: false } },
91+
})
92+
return (
93+
<Provider store={mockStore}>
94+
<QueryClientProvider client={queryClient}>
95+
<SettingsContext.Provider value={mockSettings}>
96+
<LocalizationProvider dateAdapter={AdapterDateFns}>
97+
<Story />
98+
</LocalizationProvider>
99+
</SettingsContext.Provider>
100+
</QueryClientProvider>
101+
</Provider>
102+
)
103+
},
104+
],
105+
}
106+
107+
export default preview

.storybook/vitest.setup.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { configure } from 'storybook/test'
2+
import '../tests/mocks/require-context'
3+
4+
// coverage instrumentation slows lazy chunks and fetches past the 1s default
5+
configure({ asyncUtilTimeout: 10000 })

eslint.config.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ const eslintConfig = defineConfig([
2424
],
2525
},
2626
},
27+
{
28+
// csf meta is an anonymous default export by convention
29+
files: ['tests/**/*.stories.jsx', '.storybook/**'],
30+
rules: {
31+
'import/no-anonymous-default-export': 'off',
32+
},
33+
},
2734
// Override default ignores of eslint-config-next.
2835
globalIgnores([
2936
// Default ignores of eslint-config-next:

package.json

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"name": "cipp",
3-
"version": "10.7.5",
3+
"version": "10.8.2",
44
"author": "CIPP Contributors",
55
"homepage": "https://cipp.app/",
66
"bugs": {
77
"url": "https://github.com/CyberDrain/CIPP/issues"
88
},
99
"license": "AGPL-3.0",
1010
"engines": {
11-
"node": "^22.13.0"
11+
"node": "^22.22.0"
1212
},
1313
"repository": {
1414
"type": "git",
@@ -22,7 +22,16 @@
2222
"lint": "npx eslint .",
2323
"lint-fix": "npx eslint . --fix",
2424
"prettier": "prettier --write '**/*.{js,jsx,json}'",
25-
"start-swa": "swa start --swa-config-location .vscode http://127.0.0.1:3000 --api-location http://127.0.0.1:7071 --verbose=silly"
25+
"start-swa": "swa start --swa-config-location .vscode http://127.0.0.1:3000 --api-location http://127.0.0.1:7071 --verbose=silly",
26+
"storybook": "storybook dev -p 6006 --no-open",
27+
"storybook-build": "npx storybook build -o build-storybook",
28+
"storybook-serve": "npx http-server build-storybook -p 6006",
29+
"test": "vitest run",
30+
"test:watch": "vitest",
31+
"test:unit": "vitest run --project unit",
32+
"test:browser": "vitest run --project storybook --browser.headless=false",
33+
"test:coverage": "vitest run --coverage --testTimeout=30000",
34+
"test:storybook": "vitest run --project storybook"
2635
},
2736
"dependencies": {
2837
"@emotion/cache": "11.14.0",
@@ -35,7 +44,7 @@
3544
"@mui/lab": "7.0.0-beta.17",
3645
"@mui/material": "7.3.10",
3746
"@mui/system": "7.3.10",
38-
"@mui/x-date-pickers": "^9.0.2",
47+
"@mui/x-date-pickers": "^9.10.1",
3948
"@musement/iso-duration": "^1.0.0",
4049
"@nivo/core": "^0.99.0",
4150
"@nivo/sankey": "^0.99.0",
@@ -46,14 +55,14 @@
4655
"@tanstack/react-query-devtools": "^5.101.2",
4756
"@tanstack/react-query-persist-client": "^5.101.2",
4857
"@tanstack/react-table": "^8.19.2",
49-
"@tiptap/core": "^3.22.3",
50-
"@tiptap/extension-heading": "^3.22.3",
58+
"@tiptap/core": "^3.29.2",
59+
"@tiptap/extension-heading": "^3.27.3",
5160
"@tiptap/extension-table": "^3.20.5",
52-
"@tiptap/pm": "^3.27.3",
61+
"@tiptap/pm": "^3.29.2",
5362
"@tiptap/react": "^3.20.5",
5463
"@tiptap/starter-kit": "^3.20.5",
5564
"@vvo/tzdb": "^6.198.0",
56-
"apexcharts": "5.16.0",
65+
"apexcharts": "6.6.1",
5766
"axios": "1.18.1",
5867
"date-fns": "4.4.0",
5968
"diff": "^9.0.0",
@@ -73,15 +82,15 @@
7382
"material-react-table": "^3.0.1",
7483
"monaco-editor": "^0.55.1",
7584
"mui-tiptap": "^1.31.0",
76-
"next": "^16.2.10",
85+
"next": "^16.2.11",
7786
"nprogress": "0.2.0",
7887
"numeral": "2.0.6",
7988
"prop-types": "15.8.1",
8089
"punycode": "^2.3.1",
81-
"react": "19.2.6",
90+
"react": "19.2.8",
8291
"react-apexcharts": "2.1.1",
8392
"react-beautiful-dnd": "13.1.1",
84-
"react-dom": "19.2.6",
93+
"react-dom": "19.2.8",
8594
"react-dropzone": "15.0.0",
8695
"react-error-boundary": "^6.1.2",
8796
"react-hook-form": "^7.76.1",
@@ -106,15 +115,42 @@
106115
"simplebar": "6.3.3",
107116
"simplebar-react": "3.3.2",
108117
"stylis-plugin-rtl": "2.1.1",
118+
"swagger-ui-dist": "5.32.12",
109119
"unified": "^11.0.5",
110120
"yup": "1.7.1"
111121
},
112122
"devDependencies": {
123+
"@storybook/addon-a11y": "10.3.5",
124+
"@storybook/addon-docs": "10.3.5",
125+
"@storybook/addon-themes": "10.3.5",
126+
"@storybook/addon-vitest": "10.3.5",
127+
"@storybook/react-vite": "10.3.5",
113128
"@svgr/webpack": "8.1.0",
129+
"@testing-library/dom": "10.4.1",
130+
"@testing-library/jest-dom": "6.9.1",
131+
"@testing-library/react": "16.3.2",
132+
"@testing-library/user-event": "14.6.1",
133+
"@vitest/browser-playwright": "4.1.10",
134+
"@vitest/coverage-v8": "4.1.10",
114135
"eslint": "^9.39.4",
115136
"eslint-config-next": "^16.2.10",
116137
"eslint-config-prettier": "^10.1.8",
117-
"prettier": "^3.9.5",
118-
"typescript": "5.9.3"
138+
"jsdom": "29.0.1",
139+
"msw": "2.12.14",
140+
"msw-storybook-addon": "3.0.0",
141+
"playwright": "1.59.1",
142+
"prettier": "^3.9.6",
143+
"storybook": "10.3.5",
144+
"typescript": "5.9.3",
145+
"vite": "7.3.6",
146+
"vitest": "4.1.10"
147+
},
148+
"msw": {
149+
"workerDirectory": [
150+
"public"
151+
]
152+
},
153+
"resolutions": {
154+
"vite": "7.3.6"
119155
}
120-
}
156+
}

public/cippy-401.png

723 KB

public/cippy-404.png

623 KB

public/cippy-500.png

808 KB

public/cippy-auth.png

171 KB

public/intune-definitions/00.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)