diff --git a/.github/actions/check-pr-status/package.json b/.github/actions/check-pr-status/package.json index 4cac7955a7..25b5f0a90b 100644 --- a/.github/actions/check-pr-status/package.json +++ b/.github/actions/check-pr-status/package.json @@ -1,6 +1,6 @@ { "name": "check-pr-status", - "version": "4.3.8", + "version": "4.3.9", "main": "dist/index.js", "license": "MIT", "private": true, diff --git a/examples/getstarted/package.json b/examples/getstarted/package.json index 7eabe95497..990a655f54 100644 --- a/examples/getstarted/package.json +++ b/examples/getstarted/package.json @@ -1,7 +1,7 @@ { "name": "getstarted", "private": true, - "version": "4.3.8", + "version": "4.3.9", "description": "A Strapi application.", "scripts": { "develop": "strapi develop", @@ -12,15 +12,15 @@ "strapi": "strapi" }, "dependencies": { - "@strapi/plugin-documentation": "4.3.8", - "@strapi/plugin-graphql": "4.3.8", - "@strapi/plugin-i18n": "4.3.8", - "@strapi/plugin-sentry": "4.3.8", - "@strapi/plugin-users-permissions": "4.3.8", - "@strapi/provider-email-mailgun": "4.3.8", - "@strapi/provider-upload-aws-s3": "4.3.8", - "@strapi/provider-upload-cloudinary": "4.3.8", - "@strapi/strapi": "4.3.8", + "@strapi/plugin-documentation": "4.3.9", + "@strapi/plugin-graphql": "4.3.9", + "@strapi/plugin-i18n": "4.3.9", + "@strapi/plugin-sentry": "4.3.9", + "@strapi/plugin-users-permissions": "4.3.9", + "@strapi/provider-email-mailgun": "4.3.9", + "@strapi/provider-upload-aws-s3": "4.3.9", + "@strapi/provider-upload-cloudinary": "4.3.9", + "@strapi/strapi": "4.3.9", "@vscode/sqlite3": "5.0.8", "better-sqlite3": "7.4.6", "lodash": "4.17.21", diff --git a/examples/getstarted/src/api/address/content-types/address/lifecycles.js b/examples/getstarted/src/api/address/content-types/address/lifecycles.js new file mode 100644 index 0000000000..0b8555b065 --- /dev/null +++ b/examples/getstarted/src/api/address/content-types/address/lifecycles.js @@ -0,0 +1,7 @@ +module.exports = { + beforeUpdate() { + const ctx = strapi.requestContext.get(); + + console.log('User info in service: ', ctx.state.user); + }, +}; diff --git a/examples/getstarted/src/api/address/routes/address.js b/examples/getstarted/src/api/address/routes/address.js index c9da1c88db..549918452d 100755 --- a/examples/getstarted/src/api/address/routes/address.js +++ b/examples/getstarted/src/api/address/routes/address.js @@ -5,7 +5,7 @@ const { createCoreRouter } = require('@strapi/strapi').factories; module.exports = createCoreRouter('api::address.address', { config: { find: { - auth: false, + // auth: false, }, }, only: ['find', 'findOne'], diff --git a/examples/kitchensink-ts/package.json b/examples/kitchensink-ts/package.json index 31d8f455b4..98f71798a4 100644 --- a/examples/kitchensink-ts/package.json +++ b/examples/kitchensink-ts/package.json @@ -1,7 +1,7 @@ { "name": "kitchensink-ts", "private": true, - "version": "4.3.8", + "version": "4.3.9", "description": "A Strapi application", "scripts": { "develop": "strapi develop", @@ -10,9 +10,9 @@ "strapi": "strapi" }, "dependencies": { - "@strapi/plugin-i18n": "4.3.8", - "@strapi/plugin-users-permissions": "4.3.8", - "@strapi/strapi": "4.3.8", + "@strapi/plugin-i18n": "4.3.9", + "@strapi/plugin-users-permissions": "4.3.9", + "@strapi/strapi": "4.3.9", "better-sqlite3": "7.4.6" }, "author": { diff --git a/examples/kitchensink/package.json b/examples/kitchensink/package.json index ad526f7443..e95575d2dd 100644 --- a/examples/kitchensink/package.json +++ b/examples/kitchensink/package.json @@ -1,7 +1,7 @@ { "name": "kitchensink", "private": true, - "version": "4.3.8", + "version": "4.3.9", "description": "A Strapi application.", "scripts": { "develop": "strapi develop", @@ -12,10 +12,10 @@ "strapi": "strapi" }, "dependencies": { - "@strapi/provider-email-mailgun": "4.3.8", - "@strapi/provider-upload-aws-s3": "4.3.8", - "@strapi/provider-upload-cloudinary": "4.3.8", - "@strapi/strapi": "4.3.8", + "@strapi/provider-email-mailgun": "4.3.9", + "@strapi/provider-upload-aws-s3": "4.3.9", + "@strapi/provider-upload-cloudinary": "4.3.9", + "@strapi/strapi": "4.3.9", "lodash": "4.17.21", "mysql": "2.18.1", "passport-google-oauth2": "0.2.0", diff --git a/lerna.json b/lerna.json index 2aa14d2555..ea8fc13107 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "4.3.8", + "version": "4.3.9", "packages": [ "packages/*", "examples/*" diff --git a/package.json b/package.json index aa4c40f7e3..9df48d54c4 100644 --- a/package.json +++ b/package.json @@ -87,11 +87,11 @@ "husky": "3.1.0", "inquirer": "8.2.4", "istanbul": "~0.4.2", - "jest": "29.0.0", - "jest-circus": "29.0.0", - "jest-cli": "29.0.0", - "jest-environment-jsdom": "29.0.0", - "jest-watch-typeahead": "0.6.5", + "jest": "29.0.3", + "jest-circus": "29.0.3", + "jest-cli": "29.0.3", + "jest-environment-jsdom": "29.0.3", + "jest-watch-typeahead": "2.2.0", "lerna": "5.4.3", "lint-staged": "10.5.4", "lodash": "4.17.21", diff --git a/packages/admin-test-utils/package.json b/packages/admin-test-utils/package.json index f03a3ec53b..6ce80e4fd6 100644 --- a/packages/admin-test-utils/package.json +++ b/packages/admin-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@strapi/admin-test-utils", - "version": "4.3.8", + "version": "4.3.9", "private": true, "description": "Test utilities for the Strapi administration panel", "license": "MIT", diff --git a/packages/cli/create-strapi-app/package.json b/packages/cli/create-strapi-app/package.json index 7077de9c6c..6b0d364901 100644 --- a/packages/cli/create-strapi-app/package.json +++ b/packages/cli/create-strapi-app/package.json @@ -1,6 +1,6 @@ { "name": "create-strapi-app", - "version": "4.3.8", + "version": "4.3.9", "description": "Generate a new Strapi application.", "keywords": [ "create-strapi-app", @@ -38,7 +38,7 @@ "test": "echo \"no tests yet\"" }, "dependencies": { - "@strapi/generate-new": "4.3.8", + "@strapi/generate-new": "4.3.9", "commander": "6.1.0", "inquirer": "8.2.4" }, diff --git a/packages/cli/create-strapi-starter/package.json b/packages/cli/create-strapi-starter/package.json index c3e1e972d6..d9c9145fdf 100644 --- a/packages/cli/create-strapi-starter/package.json +++ b/packages/cli/create-strapi-starter/package.json @@ -1,6 +1,6 @@ { "name": "create-strapi-starter", - "version": "4.3.8", + "version": "4.3.9", "description": "Generate a new Strapi application.", "keywords": [ "create-strapi-starter", @@ -38,7 +38,7 @@ "test": "echo \"no tests yet\"" }, "dependencies": { - "@strapi/generate-new": "4.3.8", + "@strapi/generate-new": "4.3.9", "chalk": "4.1.1", "ci-info": "3.3.2", "commander": "7.1.0", diff --git a/packages/core/admin/admin/src/StrapiApp.js b/packages/core/admin/admin/src/StrapiApp.js index cca63eb768..ea82a02523 100644 --- a/packages/core/admin/admin/src/StrapiApp.js +++ b/packages/core/admin/admin/src/StrapiApp.js @@ -22,6 +22,7 @@ import { } from './exposedHooks'; import injectionZones from './injectionZones'; import favicon from './favicon.ico'; +import localStorageKey from './components/LanguageProvider/utils/localStorageKey'; class StrapiApp { constructor({ adminConfig, appPlugins, library, middlewares, reducers }) { @@ -457,6 +458,7 @@ class StrapiApp { href: this.configurations.head.favicon, }, ]} + htmlAttributes={{ lang: localStorage.getItem(localStorageKey) || 'en' }} /> diff --git a/packages/core/admin/admin/src/components/AuthenticatedApp/index.js b/packages/core/admin/admin/src/components/AuthenticatedApp/index.js index 143260812c..efddc5765f 100644 --- a/packages/core/admin/admin/src/components/AuthenticatedApp/index.js +++ b/packages/core/admin/admin/src/components/AuthenticatedApp/index.js @@ -65,11 +65,11 @@ const AuthenticatedApp = () => { if (userRoles) { const isUserSuperAdmin = userRoles.find(({ code }) => code === 'strapi-super-admin'); - if (isUserSuperAdmin) { + if (isUserSuperAdmin && appInfos?.autoReload) { setGuidedTourVisibilityRef.current(true); } } - }, [userRoles]); + }, [userRoles, appInfos]); // We don't need to wait for the release query to be fetched before rendering the plugins // however, we need the appInfos and the permissions diff --git a/packages/core/admin/admin/src/components/AuthenticatedApp/tests/index.test.js b/packages/core/admin/admin/src/components/AuthenticatedApp/tests/index.test.js index 7f185a7207..b966821a2c 100644 --- a/packages/core/admin/admin/src/components/AuthenticatedApp/tests/index.test.js +++ b/packages/core/admin/admin/src/components/AuthenticatedApp/tests/index.test.js @@ -130,6 +130,7 @@ describe('Admin | components | AuthenticatedApp', () => { .c3 { -webkit-animation: gzYjWD 1s infinite linear; animation: gzYjWD 1s infinite linear; + will-change: transform; } .c1 { @@ -175,8 +176,20 @@ describe('Admin | components | AuthenticatedApp', () => { await waitFor(() => expect(setGuidedTourVisibility).not.toHaveBeenCalled()); }); - it('should call setGuidedTourVisibility when user is super admin', async () => { + it('should not setGuidedTourVisibility when user is a super admin and autoReload is false ', async () => { fetchUserRoles.mockImplementationOnce(() => [{ code: 'strapi-super-admin' }]); + fetchAppInfo.mockImplementationOnce(() => ({ autoReload: false })); + const setGuidedTourVisibility = jest.fn(); + useGuidedTour.mockImplementation(() => ({ setGuidedTourVisibility })); + + render(); + + await waitFor(() => expect(setGuidedTourVisibility).not.toHaveBeenCalled()); + }); + + it('should call setGuidedTourVisibility when user is super admin and autoReload is true', async () => { + fetchUserRoles.mockImplementationOnce(() => [{ code: 'strapi-super-admin' }]); + fetchAppInfo.mockImplementationOnce(() => ({ autoReload: true })); const setGuidedTourVisibility = jest.fn(); useGuidedTour.mockImplementation(() => ({ setGuidedTourVisibility })); render(); diff --git a/packages/core/admin/admin/src/components/LanguageProvider/index.js b/packages/core/admin/admin/src/components/LanguageProvider/index.js index d94e792dc3..1825d57d0e 100644 --- a/packages/core/admin/admin/src/components/LanguageProvider/index.js +++ b/packages/core/admin/admin/src/components/LanguageProvider/index.js @@ -21,6 +21,7 @@ const LanguageProvider = ({ children, localeNames, messages }) => { useEffect(() => { // Set user language in local storage. window.localStorage.setItem(localStorageKey, locale); + document.documentElement.setAttribute('lang', locale); }, [locale]); const changeLocale = (locale) => { diff --git a/packages/core/admin/admin/src/components/ThemeToggleProvider/index.js b/packages/core/admin/admin/src/components/ThemeToggleProvider/index.js index b056ee090e..65482a77a0 100644 --- a/packages/core/admin/admin/src/components/ThemeToggleProvider/index.js +++ b/packages/core/admin/admin/src/components/ThemeToggleProvider/index.js @@ -4,7 +4,7 @@ * */ -import React, { useState } from 'react'; +import React, { useState, useMemo, useCallback } from 'react'; import PropTypes from 'prop-types'; import { ThemeToggleContext } from '../../contexts'; @@ -14,22 +14,33 @@ const getDefaultTheme = () => { const browserTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; const persistedTheme = localStorage.getItem(THEME_KEY); + if (!persistedTheme) { + localStorage.setItem(THEME_KEY, browserTheme); + } + return persistedTheme || browserTheme; }; const ThemeToggleProvider = ({ children, themes }) => { const [currentTheme, setCurrentTheme] = useState(getDefaultTheme()); - const handleChangeTheme = (nextTheme) => { - setCurrentTheme(nextTheme); - localStorage.setItem(THEME_KEY, nextTheme); - }; - - return ( - - {children} - + const handleChangeTheme = useCallback( + (nextTheme) => { + setCurrentTheme(nextTheme); + localStorage.setItem(THEME_KEY, nextTheme); + }, + [setCurrentTheme] ); + + const themeValues = useMemo(() => { + return { + currentTheme, + onChangeTheme: handleChangeTheme, + themes, + }; + }, [currentTheme, handleChangeTheme, themes]); + + return {children}; }; ThemeToggleProvider.propTypes = { diff --git a/packages/core/admin/admin/src/content-manager/components/InputJSON/index.js b/packages/core/admin/admin/src/content-manager/components/InputJSON/index.js index 182dc736a2..5806dc33cb 100644 --- a/packages/core/admin/admin/src/content-manager/components/InputJSON/index.js +++ b/packages/core/admin/admin/src/content-manager/components/InputJSON/index.js @@ -79,6 +79,8 @@ class InputJSON extends React.Component { try { if (value === null) return this.codeMirror.setValue(''); + if (value === 0) return this.codeMirror.setValue('0'); + return this.codeMirror.setValue(value); } catch (err) { return this.setState({ error: true }); diff --git a/packages/core/admin/admin/src/content-manager/pages/App/tests/index.test.js b/packages/core/admin/admin/src/content-manager/pages/App/tests/index.test.js index d364ab2129..4423695662 100644 --- a/packages/core/admin/admin/src/content-manager/pages/App/tests/index.test.js +++ b/packages/core/admin/admin/src/content-manager/pages/App/tests/index.test.js @@ -151,6 +151,7 @@ describe('Content manager | App | main', () => { .c35 { -webkit-animation: gzYjWD 1s infinite linear; animation: gzYjWD 1s infinite linear; + will-change: transform; } .c33 { diff --git a/packages/core/admin/admin/src/content-manager/pages/EditView/Header/tests/index.test.js b/packages/core/admin/admin/src/content-manager/pages/EditView/Header/tests/index.test.js index d56d568b2a..b4de90f268 100644 --- a/packages/core/admin/admin/src/content-manager/pages/EditView/Header/tests/index.test.js +++ b/packages/core/admin/admin/src/content-manager/pages/EditView/Header/tests/index.test.js @@ -123,7 +123,7 @@ describe('CONTENT MANAGER | EditView | Header', () => { border: 1px solid #4945ff; } - .c12 .sc-kBzgEd { + .c12 .sc-gJbFto { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; diff --git a/packages/core/admin/admin/src/pages/SettingsPage/components/SettingsNav/tests/index.test.js b/packages/core/admin/admin/src/pages/SettingsPage/components/SettingsNav/tests/index.test.js index 7481467ace..ff08add494 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/components/SettingsNav/tests/index.test.js +++ b/packages/core/admin/admin/src/pages/SettingsPage/components/SettingsNav/tests/index.test.js @@ -417,7 +417,7 @@ describe('SettingsPage || components || SettingsNav', () => {
renders and matches the snapshot 1`] = ` border: 1px solid #4945ff; } -.c13 .sc-kBzgEd { +.c13 .sc-gJbFto { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -172,7 +172,7 @@ exports[` renders and matches the snapshot 1`] = ` background: #f0f0ff; } -.c25 .sc-kBzgEd { +.c25 .sc-gJbFto { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -293,6 +293,7 @@ exports[` renders and matches the snapshot 1`] = ` .c46 { -webkit-animation: gzYjWD 1s infinite linear; animation: gzYjWD 1s infinite linear; + will-change: transform; } .c10 { diff --git a/packages/core/admin/admin/src/pages/SettingsPage/pages/Users/ListPage/PaginationFooter/tests/__snapshots__/index.test.js.snap b/packages/core/admin/admin/src/pages/SettingsPage/pages/Users/ListPage/PaginationFooter/tests/__snapshots__/index.test.js.snap index cfa97e4698..55cc3330b5 100644 --- a/packages/core/admin/admin/src/pages/SettingsPage/pages/Users/ListPage/PaginationFooter/tests/__snapshots__/index.test.js.snap +++ b/packages/core/admin/admin/src/pages/SettingsPage/pages/Users/ListPage/PaginationFooter/tests/__snapshots__/index.test.js.snap @@ -466,7 +466,7 @@ exports[`DynamicTable renders and matches the snapshot 1`] = `