diff --git a/cypress/e2e/builder/main.cy.ts b/cypress/e2e/builder/main.cy.ts index e374b31..bbeb453 100644 --- a/cypress/e2e/builder/main.cy.ts +++ b/cypress/e2e/builder/main.cy.ts @@ -50,9 +50,6 @@ describe('Builder View', () => { cy.visit('/'); // move to add labels step - // TODO: due to an issue, we have to click twice. Remove the second click when the issue is resolved. - // for more, see https://github.com/graasp/graasp-app-name-the-frame/issues/167. - cy.get(`#${CONFIG_STEPPERS_ADD_LABELS_ID}`).click(); cy.get(`#${CONFIG_STEPPERS_ADD_LABELS_ID}`).click(); }); }); diff --git a/cypress/fixtures/appSettings.ts b/cypress/fixtures/appSettings.ts index 938cd8f..0563d6b 100644 --- a/cypress/fixtures/appSettings.ts +++ b/cypress/fixtures/appSettings.ts @@ -20,7 +20,7 @@ const EMPTY_SETTING: Pick< export const MOCK_SETTING_DATA: AppSetting & { data: Settings } = { ...EMPTY_SETTING, id: v4(), - name: SettingsKeys.SettingsData, + name: SettingsKeys.Settings, data: { description: 'item description', labels: [], @@ -40,7 +40,7 @@ export const MOCK_FILE_APP_SETTING: AppSetting & { data: FileSettings } = { export const MOCK_SETTING_DATA_WITH_LABELS: AppSetting & { data: Settings } = { ...EMPTY_SETTING, id: v4(), - name: SettingsKeys.SettingsData, + name: SettingsKeys.Settings, data: { description: 'Drag and drop colors within the right place', labels: [ diff --git a/index.html b/index.html index d66a2ad..5628379 100644 --- a/index.html +++ b/index.html @@ -4,10 +4,10 @@ - + - Graasp App Template + Name the Frame
diff --git a/package.json b/package.json index 3dad520..c65dbb0 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,9 @@ "dependencies": { "@emotion/react": "11.13.3", "@emotion/styled": "11.13.0", - "@graasp/apps-query-client": "3.6.0", + "@graasp/apps-query-client": "3.7.0", "@graasp/sdk": "4.29.1", + "@graasp/stylis-plugin-rtl": "^2.2.0", "@graasp/translations": "^1.28.0", "@graasp/ui": "5.0.0", "@mui/icons-material": "5.16.7", @@ -36,11 +37,13 @@ "lodash.groupby": "^4.6.0", "lodash.isequal": "^4.5.0", "lodash.orderby": "^4.6.0", + "lucide-react": "^0.441.0", "react": "18.3.1", "react-beautiful-dnd": "^13.1.1", "react-dom": "18.3.1", "react-draggable": "^4.4.6", "react-i18next": "14.1.3", + "react-router-dom": "^6.26.2", "react-toastify": "10.0.5", "react-zoom-pan-pinch": "^3.6.0", "typescript": "5.5.4" diff --git a/public/mockServiceWorker.js b/public/mockServiceWorker.js index e781514..b65d2b9 100644 --- a/public/mockServiceWorker.js +++ b/public/mockServiceWorker.js @@ -8,7 +8,7 @@ * - Please do NOT serve this file on production. */ -const PACKAGE_VERSION = '2.4.1' +const PACKAGE_VERSION = '2.4.8' const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423' const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') const activeClientIds = new Set() diff --git a/src/@types/index.ts b/src/@types/index.ts index 0a944fa..8d08f22 100644 --- a/src/@types/index.ts +++ b/src/@types/index.ts @@ -9,7 +9,7 @@ export type FileSettings = { export enum SettingsKeys { File = 'file', - SettingsData = 'settings-data', + Settings = 'settings', } // x and y are relative to image size (percentage) diff --git a/src/mocks/db.ts b/src/mocks/db.ts index 95532b9..dcb72de 100644 --- a/src/mocks/db.ts +++ b/src/mocks/db.ts @@ -33,7 +33,7 @@ export const defaultMockContext: LocalContext = { permission: PermissionLevel.Admin, context: 'builder', itemId: mockItem.id, - memberId: mockMembers[0].id, + accountId: mockMembers[0].id, }; const buildDatabase = (): Database => ({ @@ -127,7 +127,7 @@ const buildDatabase = (): Database => ({ { id: '2c11a73a-f333-47e1-8572-b8f99fe883b0', item: mockItem, - name: SettingsKeys.SettingsData, + name: SettingsKeys.Settings, data: { description: '', labels: [ diff --git a/src/modules/Root.tsx b/src/modules/Root.tsx index 371ad59..caefbb8 100644 --- a/src/modules/Root.tsx +++ b/src/modules/Root.tsx @@ -74,10 +74,6 @@ const RootDiv = styled('div')({ const Root: FC = () => { const [mockContext, setMockContext] = useObjectState(defaultMockContext); - - // eslint-disable-next-line no-console - console.log('render root'); - return ( {/* Used to define the order of injected properties between JSS and emotion */} diff --git a/src/modules/builder/configuration/AddImageStep.tsx b/src/modules/builder/configuration/AddImageStep.tsx index 4d45039..3616322 100644 --- a/src/modules/builder/configuration/AddImageStep.tsx +++ b/src/modules/builder/configuration/AddImageStep.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useEffect, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { Box, @@ -18,23 +18,22 @@ import { DESCRIPTION_INPUT_ID } from '@/config/selectors'; import { APP } from '@/langs/constants'; import ImageDisplay from '@/modules/builder/ImageDisplay'; import UploadImage from '@/modules/common/UploadImage'; -import { SettingsContext } from '@/modules/context/SettingsContext'; +import { useSaveSettings } from '@/utils/useSaveSettings'; -type Props = { - moveToNextStep: () => void; -}; -const AddImageStep = ({ moveToNextStep }: Props): JSX.Element => { +import { useStepContext } from './StepContext'; + +const AddImageStep = (): JSX.Element => { const { t } = useAppTranslation(); const { itemId } = useLocalContext(); + const { goToNextStep } = useStepContext(); const token = useContext(TokenContext); + const saveSettings = useSaveSettings(); const { data: imageSetting } = hooks.useAppSettings({ name: SettingsKeys.File, }); - const { saveSettings } = useContext(SettingsContext); - const { data: appSetting } = hooks.useAppSettings({ - name: SettingsKeys.SettingsData, + name: SettingsKeys.Settings, }); const image = imageSetting?.[0]; @@ -45,8 +44,8 @@ const AddImageStep = ({ moveToNextStep }: Props): JSX.Element => { const saveData = (): void => { const newData = { ...(settings && settings.data), description }; - saveSettings(SettingsKeys.SettingsData, newData); - moveToNextStep(); + saveSettings(SettingsKeys.Settings, newData); + goToNextStep(); }; useEffect(() => { diff --git a/src/modules/builder/configuration/AddLabelsStep/AddLabelsStep.tsx b/src/modules/builder/configuration/AddLabelsStep/AddLabelsStep.tsx index b7bb542..8914ecd 100644 --- a/src/modules/builder/configuration/AddLabelsStep/AddLabelsStep.tsx +++ b/src/modules/builder/configuration/AddLabelsStep/AddLabelsStep.tsx @@ -6,17 +6,11 @@ import { useAppTranslation } from '@/config/i18n'; import { APP } from '@/langs/constants'; import { LabelsContext } from '@/modules/context/LabelsContext'; +import { useStepContext } from '../StepContext'; import AddLabelWithinFrame from './AddLabelWithinFrame'; -type Props = { - moveToNextStep: () => void; - moveToPrevStep: () => void; -}; - -const AddLabelsStep = ({ - moveToNextStep, - moveToPrevStep, -}: Props): JSX.Element => { +const AddLabelsStep = (): JSX.Element => { + const { goToPrevStep, goToNextStep } = useStepContext(); const { t } = useAppTranslation(); const { labels } = useContext(LabelsContext); @@ -25,13 +19,20 @@ const AddLabelsStep = ({ - diff --git a/src/modules/builder/configuration/StepContext.tsx b/src/modules/builder/configuration/StepContext.tsx new file mode 100644 index 0000000..e12eaa8 --- /dev/null +++ b/src/modules/builder/configuration/StepContext.tsx @@ -0,0 +1,76 @@ +import { + Dispatch, + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from 'react'; + +import { Loader } from '@graasp/ui'; + +import { Settings, SettingsKeys } from '@/@types'; +import { hooks } from '@/config/queryClient'; + +type StepContextType = { + activeStep: number; + setActiveStep: Dispatch; + goToNextStep: () => void; + goToPrevStep: () => void; +}; + +const StepContext = createContext({ + activeStep: 0, + setActiveStep: () => {}, + goToNextStep: () => {}, + goToPrevStep: () => {}, +}); + +type Props = { + children: JSX.Element; +}; + +const StepProvider = ({ children }: Props): JSX.Element => { + const [activeStep, setActiveStep] = useState(0); + const { + data: settings, + isSuccess, + isLoading, + } = hooks.useAppSettings({ + name: SettingsKeys.Settings, + }); + + const [initialSetRef, setInitialSetRef] = useState(false); + + useEffect(() => { + // move to preview step in case all was settled, using Ref to move only within first render, So If i change sth with second step I don't want to move to preview immediately + if (!initialSetRef && isSuccess && settings?.[0]?.data?.labels) { + setActiveStep(2); + setInitialSetRef(true); + } + }, [settings, isSuccess, initialSetRef, setInitialSetRef]); + + const goToNextStep = useCallback((): void => { + setActiveStep(activeStep + 1); + }, [setActiveStep, activeStep]); + + const goToPrevStep = useCallback((): void => { + setActiveStep(activeStep - 1); + }, [setActiveStep, activeStep]); + + const value = useMemo( + () => ({ goToNextStep, activeStep, goToPrevStep, setActiveStep }), + [activeStep, goToNextStep, goToPrevStep], + ); + + if (isLoading) { + return ; + } + + return {children}; +}; + +export const useStepContext = (): StepContextType => useContext(StepContext); + +export default StepProvider; diff --git a/src/modules/builder/results/BuilderResults.tsx b/src/modules/builder/results/BuilderResults.tsx index ce4c406..8278ce6 100644 --- a/src/modules/builder/results/BuilderResults.tsx +++ b/src/modules/builder/results/BuilderResults.tsx @@ -33,7 +33,7 @@ const BuilderResults = (): JSX.Element => { const { data: appSetting, isLoading: isSettingsLoading } = hooks.useAppSettings({ - name: SettingsKeys.SettingsData, + name: SettingsKeys.Settings, }); if (appData?.length && appSetting?.length) { diff --git a/src/modules/context/LabelsContext.tsx b/src/modules/context/LabelsContext.tsx index 1968a23..3bac1c3 100644 --- a/src/modules/context/LabelsContext.tsx +++ b/src/modules/context/LabelsContext.tsx @@ -28,7 +28,7 @@ type Props = { export const LabelsProvider = ({ children }: Props): JSX.Element => { const { data: settingsData } = hooks.useAppSettings({ - name: SettingsKeys.SettingsData, + name: SettingsKeys.Settings, }); const [isDragging, setIsDragging] = useState(false); diff --git a/src/modules/context/SettingsContext.tsx b/src/modules/context/SettingsContext.tsx deleted file mode 100644 index 99cde62..0000000 --- a/src/modules/context/SettingsContext.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { FC, ReactElement, createContext, useContext } from 'react'; - -import { Settings, SettingsKeys } from '@/@types'; - -import { hooks, mutations } from '../../config/queryClient'; -import Loader from '../common/Loader'; - -// mapping between Setting names and their data type -// eslint-disable-next-line @typescript-eslint/ban-types -type AllSettingsType = { - [SettingsKeys.SettingsData]: Settings; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [SettingsKeys.File]: any; -}; - -// default values for the data property of settings by name -const defaultSettingsValues: AllSettingsType = { - [SettingsKeys.SettingsData]: { - description: '', - labels: [], - }, - [SettingsKeys.File]: {}, -}; - -// automatically generated types -type AllSettingsNameType = SettingsKeys; -type AllSettingsDataType = AllSettingsType[keyof AllSettingsType]; - -export type SettingsContextType = AllSettingsType & { - saveSettings: ( - name: AllSettingsNameType, - newValue: AllSettingsDataType, - ) => void; -}; - -const defaultContextValue = { - ...defaultSettingsValues, - saveSettings: () => null, -}; - -export const SettingsContext = - createContext(defaultContextValue); - -type Prop = { - children: ReactElement | ReactElement[]; -}; - -export const SettingsProvider: FC = ({ children }) => { - const { mutate: postAppSetting } = mutations.usePostAppSetting(); - const { mutate: patchAppSetting } = mutations.usePatchAppSetting(); - const { - data: appSettingsList, - isLoading, - isSuccess, - } = hooks.useAppSettings(); - - const saveSettings = ( - name: AllSettingsNameType, - newValue: AllSettingsDataType, - ): void => { - if (appSettingsList) { - const previousSetting = appSettingsList.find((s) => s.name === name); - // setting does not exist - if (!previousSetting) { - postAppSetting({ - data: newValue, - name, - }); - } else { - patchAppSetting({ - id: previousSetting.id, - data: newValue, - }); - } - } - }; - - if (isLoading) { - return ; - } - - const getContextValue = (): SettingsContextType => { - if (isSuccess) { - const ALL_SETTING_NAMES = Object.values(SettingsKeys); - const allSettings: AllSettingsType = ALL_SETTING_NAMES.reduce( - (acc: AllSettingsType, key: T) => { - // todo: types are not inferred correctly here - // @ts-ignore - const setting = appSettingsList.find((s) => s.name === key); - const settingData = setting?.data; - acc[key] = settingData as AllSettingsType[T]; - return acc; - }, - {} as AllSettingsType, - ); - return { - ...allSettings, - saveSettings, - }; - } - return defaultContextValue; - }; - - const contextValue = getContextValue(); - - return ( - - {children} - - ); -}; - -export const useSettings = (): SettingsContextType => - useContext(SettingsContext); diff --git a/src/modules/main/App.tsx b/src/modules/main/App.tsx index 3288231..739a732 100644 --- a/src/modules/main/App.tsx +++ b/src/modules/main/App.tsx @@ -5,7 +5,6 @@ import { Context } from '@graasp/sdk'; import { DEFAULT_LANG } from '@graasp/translations'; import i18n from '../../config/i18n'; -import { SettingsProvider } from '../context/SettingsContext'; import AnalyticsView from './AnalyticsView'; import BuilderView from './BuilderView'; import PlayerView from './PlayerView'; @@ -21,21 +20,17 @@ const App = (): JSX.Element => { } }, [context]); - const renderContent = (): JSX.Element => { - switch (context.context) { - case Context.Builder: - return ; + switch (context.context) { + case Context.Builder: + return ; - case Context.Analytics: - return ; + case Context.Analytics: + return ; - case Context.Player: - default: - return ; - } - }; - - return {renderContent()}; + case Context.Player: + default: + return ; + } }; export default App; diff --git a/src/modules/main/BuilderView.tsx b/src/modules/main/BuilderView.tsx index 5ed27ae..c8821ec 100644 --- a/src/modules/main/BuilderView.tsx +++ b/src/modules/main/BuilderView.tsx @@ -9,7 +9,6 @@ import { APP } from '@/langs/constants'; import Configurations from '../builder/configuration/Configurations'; import BuilderResults from '../builder/results/BuilderResults'; -import { LabelsProvider } from '../context/LabelsContext'; import { BuilderTab } from './BuilderTab'; const BuilderView = (): JSX.Element => { @@ -39,9 +38,7 @@ const BuilderView = (): JSX.Element => { /> - - - + diff --git a/src/modules/main/PlayerView.tsx b/src/modules/main/PlayerView.tsx index 6a726a8..2baf562 100644 --- a/src/modules/main/PlayerView.tsx +++ b/src/modules/main/PlayerView.tsx @@ -36,7 +36,7 @@ const PlayerView = (): JSX.Element => { const { t } = useAppTranslation(); const { data: appData } = hooks.useAppData<{ answers: SubmittedAnswer[] }>(); const { data: appSettings, isLoading } = hooks.useAppSettings({ - name: SettingsKeys.SettingsData, + name: SettingsKeys.Settings, }); const { mutate: saveAppData } = mutations.usePostAppData(); const [answeredLabels, setAnsweredLabels] = useState([]); diff --git a/src/utils/useSaveSettings.ts b/src/utils/useSaveSettings.ts new file mode 100644 index 0000000..f80d2b3 --- /dev/null +++ b/src/utils/useSaveSettings.ts @@ -0,0 +1,35 @@ +import { Settings, SettingsKeys } from '@/@types'; +import { hooks, mutations } from '@/config/queryClient'; + +// mapping between Setting names and their data type +// eslint-disable-next-line @typescript-eslint/ban-types +type AllSettingsType = { + [SettingsKeys.Settings]: Settings; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [SettingsKeys.File]: any; +}; +type AllSettingsNameType = SettingsKeys; +type AllSettingsDataType = AllSettingsType[keyof AllSettingsType]; +export const useSaveSettings = () => { + const { mutate: postAppSetting } = mutations.usePostAppSetting(); + const { mutate: patchAppSetting } = mutations.usePatchAppSetting(); + const { data: appSettingsList } = hooks.useAppSettings(); + + return (name: AllSettingsNameType, newValue: AllSettingsDataType) => { + if (appSettingsList) { + const previousSetting = appSettingsList.find((s) => s.name === name); + // setting does not exist + if (!previousSetting) { + postAppSetting({ + data: newValue, + name, + }); + } else { + patchAppSetting({ + id: previousSetting.id, + data: newValue, + }); + } + } + }; +}; diff --git a/yarn.lock b/yarn.lock index 1c5fa36..bcdd0ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2097,27 +2097,6 @@ __metadata: languageName: node linkType: hard -"@emotion/react@npm:11.13.0": - version: 11.13.0 - resolution: "@emotion/react@npm:11.13.0" - dependencies: - "@babel/runtime": "npm:^7.18.3" - "@emotion/babel-plugin": "npm:^11.12.0" - "@emotion/cache": "npm:^11.13.0" - "@emotion/serialize": "npm:^1.3.0" - "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0" - "@emotion/utils": "npm:^1.4.0" - "@emotion/weak-memoize": "npm:^0.4.0" - hoist-non-react-statics: "npm:^3.3.1" - peerDependencies: - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10/3dd2b3ffac51f0fa67ef3cb85d4064fd7ddc1212b587e3b328a1eade47024690175518d63c4cbabf28afa07e29187136b26d646e395158f6574fa6321a0b68f9 - languageName: node - linkType: hard - "@emotion/react@npm:11.13.3": version: 11.13.3 resolution: "@emotion/react@npm:11.13.3" @@ -2412,13 +2391,6 @@ __metadata: languageName: node linkType: hard -"@faker-js/faker@npm:9.0.0": - version: 9.0.0 - resolution: "@faker-js/faker@npm:9.0.0" - checksum: 10/aedd68affd27065450da3c19a0ea3050e6a16078e7d591faf38402e572dd555f5ae6b402d26456eceb6b793c44b8f83ea7b48804d1fcb841610acd4988c41f91 - languageName: node - linkType: hard - "@faker-js/faker@npm:9.0.1": version: 9.0.1 resolution: "@faker-js/faker@npm:9.0.1" @@ -2464,45 +2436,30 @@ __metadata: languageName: node linkType: hard -"@graasp/apps-query-client@npm:3.6.0": - version: 3.6.0 - resolution: "@graasp/apps-query-client@npm:3.6.0" +"@graasp/apps-query-client@npm:3.7.0": + version: 3.7.0 + resolution: "@graasp/apps-query-client@npm:3.7.0" dependencies: - "@emotion/react": "npm:11.13.0" + "@emotion/react": "npm:11.13.3" "@emotion/styled": "npm:11.13.0" - "@graasp/sdk": "npm:4.29.0" - "@mui/icons-material": "npm:5.16.6" - "@mui/material": "npm:5.16.6" - axios: "npm:1.7.3" + "@mui/icons-material": "npm:5.16.7" + "@mui/material": "npm:5.16.7" + axios: "npm:1.7.7" dexie: "npm:4.0.8" http-status-codes: "npm:2.3.0" miragejs: "npm:0.1.48" - msw: "npm:2.4.1" + msw: "npm:2.4.8" uuid: "npm:10.0.0" peerDependencies: + "@graasp/sdk": ^4.22.0 "@mui/icons-material": ^5.15.5 "@mui/material": ^5.15.5 "@tanstack/react-query": ^4.28.0 "@tanstack/react-query-devtools": ^4.28.0 - date-fns: ^3.3.0 + date-fns: ^3.3.0 || ^4.0.0 react: ^18.0.0 react-dom: ^18.0.0 - checksum: 10/5cdf11d5339fa0d71461c949b16d0038e69736a2cb13a945cc733157f2d2a4ffd1b28cc24e82c40bc0d908fef3591cdf2ccce5b71860b01f54adeea3af2a7661 - languageName: node - linkType: hard - -"@graasp/sdk@npm:4.29.0": - version: 4.29.0 - resolution: "@graasp/sdk@npm:4.29.0" - dependencies: - "@faker-js/faker": "npm:9.0.0" - filesize: "npm:10.1.6" - js-cookie: "npm:3.0.5" - validator: "npm:13.12.0" - peerDependencies: - date-fns: ^3 - uuid: ^9 || ^10 - checksum: 10/9801f0429172f325d14b378d4d2b2ec1ada679da736901e8ae9fca2f52f1b29b508809b686ee0b3fd8944262958a1e9c4b77936f57e5f448ad1ca8cc5632c50b + checksum: 10/0c1c11a258ff0da9045bf70ce5df54b49de267c4b9f0fa7ff21be067e94eb0eb8a7d2ad793a51af5aa6336d015cfca87601e8a108b4ae79bd35f9d1a9f0a0bac languageName: node linkType: hard @@ -2521,6 +2478,17 @@ __metadata: languageName: node linkType: hard +"@graasp/stylis-plugin-rtl@npm:^2.2.0": + version: 2.2.0 + resolution: "@graasp/stylis-plugin-rtl@npm:2.2.0" + dependencies: + cssjanus: "npm:^2.3.0" + peerDependencies: + stylis: 4.x + checksum: 10/4b873aa7465c894ff5422f851522feda36bf73923f7a859befc7d5c8049e660a80a103090b977d01fad5c7d2c7ab92e313a7fa3eb263e2ce41bdb9597762edac + languageName: node + linkType: hard + "@graasp/translations@npm:^1.28.0": version: 1.37.0 resolution: "@graasp/translations@npm:1.37.0" @@ -2740,17 +2708,17 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.29.0": - version: 0.29.1 - resolution: "@mswjs/interceptors@npm:0.29.1" +"@mswjs/interceptors@npm:^0.35.6": + version: 0.35.6 + resolution: "@mswjs/interceptors@npm:0.35.6" dependencies: "@open-draft/deferred-promise": "npm:^2.2.0" "@open-draft/logger": "npm:^0.3.0" "@open-draft/until": "npm:^2.0.0" is-node-process: "npm:^1.2.0" - outvariant: "npm:^1.2.1" + outvariant: "npm:^1.4.3" strict-event-emitter: "npm:^0.5.1" - checksum: 10/6a6ee6eb3db0fed60bbeb710288f8c1e2cac84f08254756b684dbd553b04449dfe4cce1261fcc83772ee114be2043d9777e2ee6d72bc8d14fd394f961827e528 + checksum: 10/da0c50c924301fd8d6a57b102bae65721f1253b5bbf1a64c4d9108cc70f91f89552d67efe01effe37413eb0b93ca268f63a899f0578dc1f7be7621658b4b292d languageName: node linkType: hard @@ -2776,29 +2744,13 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.16.6, @mui/core-downloads-tracker@npm:^5.16.7": +"@mui/core-downloads-tracker@npm:^5.16.7": version: 5.16.7 resolution: "@mui/core-downloads-tracker@npm:5.16.7" checksum: 10/b65c48ba2bf6bba6435ba9f2d6c33db0c8a85b3ff7599136a9682b72205bec76470ab5ed5e6e625d5bd012ed9bcbc641ed677548be80d217c9fb5d0435567062 languageName: node linkType: hard -"@mui/icons-material@npm:5.16.6": - version: 5.16.6 - resolution: "@mui/icons-material@npm:5.16.6" - dependencies: - "@babel/runtime": "npm:^7.23.9" - peerDependencies: - "@mui/material": ^5.0.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10/14090d064b909aab1f2bea82dee8754408be53efa33f1b6787d5867d5931fe571e2019a14426d35e53c35fa8dbf0d52691bedeae37779e1050206ebc3556e369 - languageName: node - linkType: hard - "@mui/icons-material@npm:5.16.7": version: 5.16.7 resolution: "@mui/icons-material@npm:5.16.7" @@ -2844,39 +2796,6 @@ __metadata: languageName: node linkType: hard -"@mui/material@npm:5.16.6": - version: 5.16.6 - resolution: "@mui/material@npm:5.16.6" - dependencies: - "@babel/runtime": "npm:^7.23.9" - "@mui/core-downloads-tracker": "npm:^5.16.6" - "@mui/system": "npm:^5.16.6" - "@mui/types": "npm:^7.2.15" - "@mui/utils": "npm:^5.16.6" - "@popperjs/core": "npm:^2.11.8" - "@types/react-transition-group": "npm:^4.4.10" - clsx: "npm:^2.1.0" - csstype: "npm:^3.1.3" - prop-types: "npm:^15.8.1" - react-is: "npm:^18.3.1" - react-transition-group: "npm:^4.4.5" - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@types/react": - optional: true - checksum: 10/17e157eb53b73ae97c7dc3e6c4743dae730ebb4339759f44b183291ce5d409e2142e6e41b4470345b556baeb42c9801057e4b1ccf6a3240126d90f178267412c - languageName: node - linkType: hard - "@mui/material@npm:5.16.7": version: 5.16.7 resolution: "@mui/material@npm:5.16.7" @@ -2948,7 +2867,7 @@ __metadata: languageName: node linkType: hard -"@mui/system@npm:^5.16.5, @mui/system@npm:^5.16.6, @mui/system@npm:^5.16.7": +"@mui/system@npm:^5.16.5, @mui/system@npm:^5.16.7": version: 5.16.7 resolution: "@mui/system@npm:5.16.7" dependencies: @@ -3159,6 +3078,13 @@ __metadata: languageName: node linkType: hard +"@remix-run/router@npm:1.19.2": + version: 1.19.2 + resolution: "@remix-run/router@npm:1.19.2" + checksum: 10/31b62b66ea68bd62018189047de7b262700113438f62407df019f81a9856a08a705b2b77454be9293518e2f5f3bbf3f8b858ac19f48cb7d89f8ab56b7b630c19 + languageName: node + linkType: hard + "@rollup/pluginutils@npm:^5.0.2": version: 5.1.0 resolution: "@rollup/pluginutils@npm:5.1.0" @@ -5012,25 +4938,25 @@ __metadata: languageName: node linkType: hard -"axios@npm:1.7.3": - version: 1.7.3 - resolution: "axios@npm:1.7.3" +"axios@npm:1.7.5": + version: 1.7.5 + resolution: "axios@npm:1.7.5" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 10/7f92af205705a8fb4a9d35666b663729507657f252a1d39d83582590119941872d49078017cf992e32f47aa3b7317f5439f77be772a173dac2ae0fedd38f43ae + checksum: 10/6cbcfe943a84089f420a900a3a3aeb54ee94dcc9c2b81b150434896357be5d1079eff0b1bbb628597371e79f896b1bc5776df04184756ba99656ff31df9a75bf languageName: node linkType: hard -"axios@npm:1.7.5": - version: 1.7.5 - resolution: "axios@npm:1.7.5" +"axios@npm:1.7.7": + version: 1.7.7 + resolution: "axios@npm:1.7.7" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 10/6cbcfe943a84089f420a900a3a3aeb54ee94dcc9c2b81b150434896357be5d1079eff0b1bbb628597371e79f896b1bc5776df04184756ba99656ff31df9a75bf + checksum: 10/7f875ea13b9298cd7b40fd09985209f7a38d38321f1118c701520939de2f113c4ba137832fe8e3f811f99a38e12c8225481011023209a77b0c0641270e20cde1 languageName: node linkType: hard @@ -5848,6 +5774,13 @@ __metadata: languageName: node linkType: hard +"cssjanus@npm:^2.3.0": + version: 2.3.0 + resolution: "cssjanus@npm:2.3.0" + checksum: 10/eaa78f8b6047f52ea504964fd15b3f92b4d3603dd50350ad3c8c53dc51db8d4f75bac54570cd281df8ac368ed8759ccc677ae3cb53583af051688d63dc329232 + languageName: node + linkType: hard + "csstype@npm:^3.0.2, csstype@npm:^3.1.3": version: 3.1.3 resolution: "csstype@npm:3.1.3" @@ -7911,8 +7844,9 @@ __metadata: "@cypress/code-coverage": "npm:3.13.1" "@emotion/react": "npm:11.13.3" "@emotion/styled": "npm:11.13.0" - "@graasp/apps-query-client": "npm:3.6.0" + "@graasp/apps-query-client": "npm:3.7.0" "@graasp/sdk": "npm:4.29.1" + "@graasp/stylis-plugin-rtl": "npm:^2.2.0" "@graasp/translations": "npm:^1.28.0" "@graasp/ui": "npm:5.0.0" "@mui/icons-material": "npm:5.16.7" @@ -7962,6 +7896,7 @@ __metadata: lodash.groupby: "npm:^4.6.0" lodash.isequal: "npm:^4.5.0" lodash.orderby: "npm:^4.6.0" + lucide-react: "npm:^0.441.0" miragejs: "npm:^0.1.48" nock: "npm:^13.5.3" nyc: "npm:15.1.0" @@ -7971,6 +7906,7 @@ __metadata: react-dom: "npm:18.3.1" react-draggable: "npm:^4.4.6" react-i18next: "npm:14.1.3" + react-router-dom: "npm:^6.26.2" react-toastify: "npm:10.0.5" react-zoom-pan-pinch: "npm:^3.6.0" typescript: "npm:5.5.4" @@ -7995,6 +7931,13 @@ __metadata: languageName: node linkType: hard +"graphql@npm:^16.8.1": + version: 16.9.0 + resolution: "graphql@npm:16.9.0" + checksum: 10/5833f82bb6c31bec120bbf9cd400eda873e1bb7ef5c17974fa262cd82dc68728fda5d4cb859dc8aaa4c4fe4f6fe1103a9c47efc01a12c02ae5cb581d8e4029e2 + languageName: node + linkType: hard + "has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": version: 1.0.2 resolution: "has-bigints@npm:1.0.2" @@ -9320,6 +9263,15 @@ __metadata: languageName: node linkType: hard +"lucide-react@npm:^0.441.0": + version: 0.441.0 + resolution: "lucide-react@npm:0.441.0" + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + checksum: 10/c423ed98e1e7b28408991dc52675e98b11547e12c3d4e4b0c25cc5eb611b1535cad9136434ef54677c43ce34c6211981cb76fe92415a6aa7c66c4f5d9b0380b8 + languageName: node + linkType: hard + "magic-string@npm:^0.27.0": version: 0.27.0 resolution: "magic-string@npm:0.27.0" @@ -9641,37 +9593,35 @@ __metadata: languageName: node linkType: hard -"msw@npm:2.4.1": - version: 2.4.1 - resolution: "msw@npm:2.4.1" +"msw@npm:2.4.8": + version: 2.4.8 + resolution: "msw@npm:2.4.8" dependencies: "@bundled-es-modules/cookie": "npm:^2.0.0" "@bundled-es-modules/statuses": "npm:^1.0.1" "@bundled-es-modules/tough-cookie": "npm:^0.1.6" "@inquirer/confirm": "npm:^3.0.0" - "@mswjs/interceptors": "npm:^0.29.0" + "@mswjs/interceptors": "npm:^0.35.6" "@open-draft/until": "npm:^2.1.0" "@types/cookie": "npm:^0.6.0" "@types/statuses": "npm:^2.0.4" chalk: "npm:^4.1.2" + graphql: "npm:^16.8.1" headers-polyfill: "npm:^4.0.2" is-node-process: "npm:^1.2.0" outvariant: "npm:^1.4.2" - path-to-regexp: "npm:^6.2.0" + path-to-regexp: "npm:^6.3.0" strict-event-emitter: "npm:^0.5.1" type-fest: "npm:^4.9.0" yargs: "npm:^17.7.2" peerDependencies: - graphql: ">= 16.8.x" - typescript: ">= 4.7.x" + typescript: ">= 4.8.x" peerDependenciesMeta: - graphql: - optional: true typescript: optional: true bin: msw: cli/index.js - checksum: 10/618215e29815cb8305994d5cbaf37d6cdefb247668993957e2515ab822bc92042348a65540de6fc407700e77b3c46dc03ff7bb76ea0ffa44b3583785c9018ee9 + checksum: 10/bbb290ed9aeaa2ea72d60dfc669256fc3998fb96f81f280d8a9e5455543015f361b9da0ff99cd31e47f71461a11fdb59dec4a01418a777da41b75e2db80c57c5 languageName: node linkType: hard @@ -9975,7 +9925,7 @@ __metadata: languageName: node linkType: hard -"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0, outvariant@npm:^1.4.2": +"outvariant@npm:^1.4.0, outvariant@npm:^1.4.2, outvariant@npm:^1.4.3": version: 1.4.3 resolution: "outvariant@npm:1.4.3" checksum: 10/3a7582745850cb344d49641867a4c080858c54f4091afd91b9c0765ba6e471c2bc841348f0fff344845ddd0a4db42fd5d68c6f7ebaf32d4b676a3a9987b2488a @@ -10195,10 +10145,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^6.2.0": - version: 6.2.2 - resolution: "path-to-regexp@npm:6.2.2" - checksum: 10/f7d11c1a9e02576ce0294f4efdc523c11b73894947afdf7b23a0d0f7c6465d7a7772166e770ddf1495a8017cc0ee99e3e8a15ed7302b6b948b89a6dd4eea895e +"path-to-regexp@npm:^6.3.0": + version: 6.3.0 + resolution: "path-to-regexp@npm:6.3.0" + checksum: 10/6822f686f01556d99538b350722ef761541ec0ce95ca40ce4c29e20a5b492fe8361961f57993c71b2418de12e604478dcf7c430de34b2c31a688363a7a944d9c languageName: node linkType: hard @@ -10766,6 +10716,30 @@ __metadata: languageName: node linkType: hard +"react-router-dom@npm:^6.26.2": + version: 6.26.2 + resolution: "react-router-dom@npm:6.26.2" + dependencies: + "@remix-run/router": "npm:1.19.2" + react-router: "npm:6.26.2" + peerDependencies: + react: ">=16.8" + react-dom: ">=16.8" + checksum: 10/4eee37839bd1a660807c090b4d272e4aa9b95d8a9a932cdcdf7c5b10735f39b6db73bad79b08a3012386a7e225ff6bf60435e2741fb7c68e137ac5a6295d4308 + languageName: node + linkType: hard + +"react-router@npm:6.26.2": + version: 6.26.2 + resolution: "react-router@npm:6.26.2" + dependencies: + "@remix-run/router": "npm:1.19.2" + peerDependencies: + react: ">=16.8" + checksum: 10/496e855b53e61066c1791e354f5d79eab56a128d9722fdc6486c3ecd3b3a0bf9968e927028f429893b157f3cc10fc09e890a055847723ee242663e7995fedc9d + languageName: node + linkType: hard + "react-toastify@npm:10.0.5": version: 10.0.5 resolution: "react-toastify@npm:10.0.5"