diff --git a/.github/workflows/prepare-cloud-release.yaml b/.github/workflows/prepare-cloud-release.yaml index ae12390c551..5673715cc4d 100644 --- a/.github/workflows/prepare-cloud-release.yaml +++ b/.github/workflows/prepare-cloud-release.yaml @@ -41,13 +41,21 @@ jobs: - name: Enable PR automerge id: enable-pr-automerge + if: ${{ steps.create-pr.outputs.pr_url != '' }} run: | gh pr merge --auto -r ${{steps.create-pr.outputs.pr_url}} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Delete release branch step on failure + id: delete-branch + if: ${{ failure() || steps.create-pr.outputs.pr_url == '' }} + run: | + git push origin -d ${{ steps.output-variables.outputs.branch_name }} + - name: Generate commit log id: commit-log + if: ${{ success() }} run: | echo 'COMMIT_LOG<> $GITHUB_ENV echo $(git log --format="format:%h %s (@%aL)\n" origin/prod..origin/${{steps.output-variables.outputs.branch_name}} | sed "s/\"/'/g") >> $GITHUB_ENV @@ -56,6 +64,7 @@ jobs: - name: Send commit log to Slack id: slack uses: slackapi/slack-github-action@v1.26.0 + if: ${{ success() }} with: payload: | { diff --git a/apps/web/.eslintrc.js b/apps/web/.eslintrc.js index 625b1fb18ac..555f591e970 100644 --- a/apps/web/.eslintrc.js +++ b/apps/web/.eslintrc.js @@ -22,8 +22,16 @@ module.exports = { 'no-restricted-imports': [ 'error', { - paths: ['src'], - patterns: ['@novu/dal'], + paths: [ + { + name: '@novu/dal', + }, + { + name: '@mantine/core', + message: + 'Please avoid referencing @mantine/core directly in new or updated code. Instead, import from @novu/novui', + }, + ], }, ], '@typescript-eslint/naming-convention': [ @@ -35,9 +43,9 @@ module.exports = { format: ['PascalCase', 'camelCase', 'UPPER_CASE'], }, ], - "react-hooks/rules-of-hooks": 'error', - "react-hooks/exhaustive-deps": 'warn', - "import/extensions": 'off', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + 'import/extensions': 'off', }, env: { 'cypress/globals': true, diff --git a/apps/web/netlify.toml b/apps/web/netlify.toml index cc8e3fa70a1..fd7f22df7bc 100644 --- a/apps/web/netlify.toml +++ b/apps/web/netlify.toml @@ -1,3 +1,13 @@ +[build.environment] + DISABLE_ESLINT_PLUGIN="true" + +[build] + # default build command + command = "cd apps/web && pnpm run envsetup && cd ../../ && pnpm run build:web --skip-nx-cache" + +[context.deploy-preview] + command = "cd apps/web && pnpm run envsetup && cd ../../ && pnpm run build:web --skip-nx-cache" + [[redirects]] from = "/*" to = "/index.html" diff --git a/apps/web/public/env-config.js b/apps/web/public/env-config.js index d2769acd5c8..761a0411621 100644 --- a/apps/web/public/env-config.js +++ b/apps/web/public/env-config.js @@ -1,3 +1,5 @@ window._env_ = { SKIP_PREFLIGHT_CHECK: 'true', + REACT_APP_ENVIRONMENT: 'dev', + REACT_APP_VERSION: '$npm_package_version', }; diff --git a/libs/design-system/src/color-scheme/getColorScheme.ts b/libs/design-system/src/color-scheme/getColorScheme.ts new file mode 100644 index 00000000000..25a20f25cd4 --- /dev/null +++ b/libs/design-system/src/color-scheme/getColorScheme.ts @@ -0,0 +1,31 @@ +import { ColorScheme } from './ColorScheme'; +import { getColorSchemeHtmlElement } from './getColorSchemeHtmlElement'; + +const DEFAULT_COLOR_SCHEME: ColorScheme = 'light'; + +/** + * Gets the user's preferred color scheme according to their browser settings. + * @returns ColorScheme + */ +export const getBrowserColorScheme = (): ColorScheme => { + return window?.matchMedia?.(`(prefers-color-scheme: dark)`)?.matches ? 'dark' : DEFAULT_COLOR_SCHEME; +}; + +/** + * Get the current color scheme of the application based on the application html. + * @returns ColorScheme + */ +export const getCurrentColorScheme = (): ColorScheme => { + const htmlElem = getColorSchemeHtmlElement(); + + // fallback to browser preferences if there isn't an html element + if (!htmlElem?.classList) { + return getBrowserColorScheme(); + } + + return htmlElem.classList.contains('dark') + ? 'dark' + : htmlElem.classList.contains('light') + ? 'light' + : DEFAULT_COLOR_SCHEME; +}; diff --git a/libs/design-system/src/color-scheme/getColorSchemeHtmlElement.ts b/libs/design-system/src/color-scheme/getColorSchemeHtmlElement.ts new file mode 100644 index 00000000000..d6d719eb244 --- /dev/null +++ b/libs/design-system/src/color-scheme/getColorSchemeHtmlElement.ts @@ -0,0 +1,14 @@ +/** Get the innermost element that serves as the basis for our theme */ +export const getColorSchemeHtmlElement = (): HTMLHtmlElement | null => { + /** + * Avoid issues with multiple `html` elements (like in Storybook) by getting all html elements + * and taking the innermost one + */ + const htmlElements = document.querySelectorAll('html'); + + if (!htmlElements?.length) { + return null; + } + + return htmlElements.item(htmlElements.length - 1); +}; diff --git a/libs/design-system/src/color-scheme/index.ts b/libs/design-system/src/color-scheme/index.ts index 7841a642b54..23f2f63bd47 100644 --- a/libs/design-system/src/color-scheme/index.ts +++ b/libs/design-system/src/color-scheme/index.ts @@ -1,3 +1,4 @@ export * from './ColorScheme'; export * from './mapThemeStatusToColorScheme'; export * from './useColorScheme'; +export * from './getColorScheme'; diff --git a/libs/design-system/src/color-scheme/useColorScheme.ts b/libs/design-system/src/color-scheme/useColorScheme.ts index 6953303214c..820a9f3397d 100644 --- a/libs/design-system/src/color-scheme/useColorScheme.ts +++ b/libs/design-system/src/color-scheme/useColorScheme.ts @@ -3,6 +3,7 @@ import { useLocalThemePreference, ColorSchemePreferenceEnum } from '@novu/shared import { useColorScheme as useMantineColorScheme } from '@mantine/hooks'; import { ColorScheme } from './ColorScheme'; import { mapThemeStatusToColorScheme } from './mapThemeStatusToColorScheme'; +import { getColorSchemeHtmlElement } from './getColorSchemeHtmlElement'; /** * Handle behavior for changing ColorSchemes or ThemeStatuses @@ -14,9 +15,10 @@ export const useColorScheme = () => { const setColorScheme = useCallback( (newColorScheme: ColorScheme) => { - // avoid issues with multiple `html` elements (like in Storybook) - const htmlElements = document.querySelectorAll('html'); - const htmlElem = htmlElements.item(htmlElements.length - 1); + const htmlElem = getColorSchemeHtmlElement(); + if (!htmlElem) { + return; + } htmlElem.className = newColorScheme; _setColorScheme(newColorScheme); diff --git a/libs/design-system/src/config/colors.ts b/libs/design-system/src/config/colors.ts index 70a44ead5d4..7fe46b84b5d 100644 --- a/libs/design-system/src/config/colors.ts +++ b/libs/design-system/src/config/colors.ts @@ -1,7 +1,11 @@ +/** @deprecated: Please only use values via Panda CSS defined via tokens. If the color doesn't exist, please contact Design. */ const gradientStart = '#FF512F'; +/** @deprecated: Please only use values via Panda CSS defined via tokens. If the color doesn't exist, please contact Design. */ const gradientEnd = '#DD2476'; +/** @deprecated: Please only use values via Panda CSS defined via tokens. If the color doesn't exist, please contact Design. */ const error = '#E54545'; +/** @deprecated: Please only use values via Panda CSS defined via tokens. If the color doesn't exist, please contact Design. */ export const colors = { white: '#FFFFFF', black: '#000000', diff --git a/libs/design-system/src/config/shadows.ts b/libs/design-system/src/config/shadows.ts index 38cd456470e..07291f27b07 100644 --- a/libs/design-system/src/config/shadows.ts +++ b/libs/design-system/src/config/shadows.ts @@ -1,3 +1,4 @@ +/** @deprecated: Please only use values via Panda CSS defined via tokens. If the color doesn't exist, please contact Design. */ export const shadows = { light: '0px 5px 15px rgba(38, 68, 128, 0.05)', medium: '0px 5px 15px rgba(122, 133, 153, 0.25)',