From e39722b5be08c9fac0a99b33a1a397aa34671397 Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Mon, 11 May 2026 11:46:32 +0200 Subject: [PATCH 01/10] Upgrade ESLint to v10 and adopt @eslint-react MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrates from ESLint 9.39 to 10.3 ahead of the v9 EOL (2026-08-06). Since eslint-plugin-react has no ESLint 10 release (peer dep ^9.7; maintainer-confirmed incompatibility, PR #3979 still open), this swaps in @eslint-react/eslint-plugin v5 — a modern, actively-maintained linter built for ESLint 10 with native React 19 support. Toolchain - eslint 9.39.4 -> 10.3.0, @eslint/js 9.39.4 -> 10.0.1 - Replaced eslint-plugin-react@7.37.5 with @eslint-react/eslint-plugin@5.7.5 - Removed @eslint/compat and @eslint/eslintrc (FlatCompat shim no longer needed; @typescript-eslint and @eslint-react both ship native flat-config presets) - Regenerated the ESLint ajv-8 workaround patch for v10.3.0 Rule set audit Removed silencing of @typescript-eslint/no-explicit-any (defeated TS safety). Added the high-value type-aware rules from typescript-eslint: await-thenable (error), no-floating-promises and no-misused-promises (warn pending legacy-backlog cleanup), no-unnecessary-type-assertion, prefer-nullish-coalescing, prefer-optional-chain. Added code-quality rules: consistent-type-imports, no-non-null-assertion, no-explicit-any, eqeqeq (smart), no-throw-literal, no-implicit-coercion (with boolean: false so !!x stays usable for TS narrowing), no-console. Kept no-undef / no-redeclare disabled because TypeScript already enforces both and no-redeclare rejects legitimate function overloads. Bug fixes surfaced by the stricter linter - requests/handler.ts: removed duplicate else-if 404 branch (dead code) - DropDownMultiSelect: const-ified an always-reassigned let - ThesisCommentsList / CalendarCarousel: keyed Fragment for map roots - utils/format.ts: getInterviewStateColor() called a hook from a non-hook fn; refactored to accept isDark and updated 3 call sites - TopicCardGrid: hook was called conditionally (gridContent ?? useTopicsContext()); now always calls useContext - InterviewBookingPage: hoisted SlotInformation to a module-scope component (was a PascalCase function defined inside the parent) - CollapsibleDateCard / SlotItem / CollapsibleTopicElement: removed JSX IIFEs flagged by react compiler rules - ResearchGroupAdminPage: moved key before spread to avoid JSX deopt - AuthenticatedArea / ResearchGroupSettingPage: == -> ===, != -> !== - EmailTemplateEditPage: dropped async/await on two functions that call doRequest with a callback (callback overload returns void) Co-Authored-By: Claude Opus 4.7 (1M context) --- client/eslint.config.mjs | 112 +- client/package-lock.json | 2245 ++++------------- client/package.json | 8 +- client/patches/@eslint+eslintrc+3.3.5.patch | 105 - ...slint+9.39.4.patch => eslint+10.3.0.patch} | 0 .../AuthenticatedArea/AuthenticatedArea.tsx | 9 +- .../ContentContainer/ContentContainer.tsx | 5 +- .../src/app/layout/PublicArea/PublicArea.tsx | 5 +- .../ApplicationData/ApplicationData.tsx | 5 +- .../ApplicationDeleteButton.tsx | 3 +- .../ApplicationModal/ApplicationModal.tsx | 5 +- .../ApplicationRejectButton.tsx | 3 +- .../ApplicationReviewForm.tsx | 5 +- .../ApplicationsFilters.tsx | 2 +- .../ApplicationsTable/ApplicationsTable.tsx | 7 +- .../AuthenticatedFileDownloadButton.tsx | 3 +- .../AuthenticatedFilePreview.tsx | 5 +- .../AuthenticatedFilePreviewButton.tsx | 5 +- .../src/components/AvatarUser/AvatarUser.tsx | 5 +- .../AvatarUserList/AvatarUserList.tsx | 5 +- .../ConfirmationButton/ConfirmationButton.tsx | 3 +- .../components/CustomAvatar/CustomAvatar.tsx | 5 +- .../DocumentEditor/DocumentEditor.tsx | 3 +- .../DropDownMultiSelect.tsx | 9 +- .../EnvironmentBanner/EnvironmentBanner.tsx | 7 +- .../components/FileElement/FileElement.tsx | 11 +- .../components/FilePreview/FilePreview.tsx | 2 +- client/src/components/Footer/Footer.tsx | 3 +- .../src/components/GanttChart/GanttChart.tsx | 9 +- .../GanttChartZoomContainer.tsx | 6 +- client/src/components/GanttChart/context.ts | 3 +- .../InterviewSlotInformation.tsx | 2 +- .../KeycloakUserAutocomplete.tsx | 4 +- .../components/LabeledItem/LabeledItem.tsx | 3 +- .../NoContentFoundCard/NoContentFoundCard.tsx | 2 +- .../PresentationsTable/PresentationsTable.tsx | 9 +- .../ReplacePresentationModal.tsx | 2 +- .../SchedulePresentationModal.tsx | 9 +- .../PublicPresentationsTable.tsx | 4 +- .../ResearchGroupForm.test.tsx | 12 +- .../ResearchGroupForm/ResearchGroupForm.tsx | 6 +- .../ThesesFilters/ThesesFilters.tsx | 2 +- .../ThesesGanttChart/ThesesGanttChart.tsx | 8 +- .../components/ThesesTable/ThesesTable.tsx | 7 +- .../ThesisCommentsForm/ThesisCommentsForm.tsx | 2 +- .../ThesisCommentsList/ThesisCommentsList.tsx | 6 +- .../components/ThesisCommentElement.tsx | 2 +- .../src/components/ThesisData/ThesisData.tsx | 3 +- .../ThesisStateBadge/ThesisStateBadge.tsx | 2 +- .../TopicAccordionItem/TopicAccordionItem.tsx | 5 +- client/src/components/TopicData/TopicData.tsx | 2 +- .../TopicSearchFilters/TopicSearchFilters.tsx | 5 +- .../TopicsFilters/TopicsFilters.tsx | 2 +- .../components/TopicsTable/TopicsTable.tsx | 6 +- .../src/components/UploadArea/UploadArea.tsx | 2 +- .../UploadFileButton/UploadFileButton.tsx | 5 +- client/src/components/UserCard/UserCard.tsx | 2 +- .../UserInformationForm.tsx | 2 +- .../components/AvatarInput/AvatarInput.tsx | 4 +- .../UserInformationRow/UserInformationRow.tsx | 2 +- .../UserMultiSelect/UserMultiSelect.tsx | 4 +- client/src/config/global.ts | 2 +- client/src/hooks/fetcher.ts | 6 +- client/src/hooks/local-storage.ts | 3 +- client/src/hooks/notification.ts | 3 +- client/src/pages/AdminPage/AdminPage.tsx | 2 +- .../CreateThesisModal/CreateThesisModal.tsx | 8 +- .../src/pages/DashboardPage/DashboardPage.tsx | 3 +- .../MyTasksSection/MyTasksSection.tsx | 2 +- .../InterviewBookingPage.tsx | 87 +- .../components/SelectSlotCarousel.tsx | 2 +- .../InterviewOverviewPage.tsx | 4 +- .../components/CreateInterviewProcess.tsx | 4 +- .../components/InterviewProcessCard.tsx | 12 +- .../components/SelectApplicantsList.tsx | 2 +- .../SelectTopicInterviewProcessItem.tsx | 2 +- .../components/UpcomingInterviewCard.tsx | 2 +- .../InterviewTopicOverviewPage.tsx | 2 +- .../components/AcceptApplicantModal.tsx | 4 +- .../components/AddIntervieweesModal.tsx | 4 +- .../components/AddSlotsModal.tsx | 2 +- .../AssignIntervieweeToSlotModal.tsx | 2 +- .../components/CalendarCarousel.tsx | 8 +- .../CancelSlotConfirmationModal.tsx | 2 +- .../components/CollapsibleDateCard.tsx | 19 +- .../components/IntervieweeCard.tsx | 12 +- .../components/IntervieweesList.tsx | 6 +- .../components/InviteConfirmationModal.tsx | 2 +- .../components/SlotItem.tsx | 9 +- .../IntervieweeAssesmentPage.tsx | 2 +- client/src/pages/LandingPage/LandingPage.tsx | 2 +- .../LandingPageHeader/LandingPageHeader.tsx | 2 +- .../PublishedTheses/PublishedTheses.tsx | 6 +- .../TopicCardGrid/TopicCard/TopicCard.tsx | 9 +- .../TopicCardGrid/TopicCardGrid.tsx | 18 +- .../ManageTopicsPage/ManageTopicsPage.tsx | 2 +- .../CloseTopicButton/CloseTopicButton.tsx | 8 +- .../ReplaceTopicModal/ReplaceTopicModal.tsx | 13 +- .../PresentationOverviewPage.tsx | 8 +- .../PresentationPage/PresentationPage.tsx | 2 +- .../ReplaceApplicationPage.tsx | 2 +- .../MotivationStep/MotivationStep.tsx | 10 +- .../SelectTopicStep/SelectTopicStep.tsx | 4 +- .../components/CollapsibleTopicElement.tsx | 49 +- .../ResearchGroupAdminPage.tsx | 11 +- .../components/ResearchGroupCard.tsx | 2 +- .../ResearchGroupSettingPage.tsx | 6 +- .../ApplicationEmailContentSettingsCard.tsx | 2 +- .../ApplicationPhaseSettingsCard.tsx | 2 +- .../components/EmailSettingsCard.tsx | 2 +- .../EmailTemplateCard.tsx | 2 +- .../EmailTemplateEditPage.tsx | 12 +- .../EmailTemplatePreviewModal.tsx | 2 +- .../EmailTemplatesOverview.tsx | 4 +- .../EmailTextEditor/EmailTextEditor.tsx | 10 +- .../EmailTextEditor/Extension.ts | 2 +- .../VariableComboboxOptions.tsx | 2 +- .../EmailTextEditor/VariableComponent.tsx | 5 +- .../GeneralResearchGroupSettings.tsx | 4 +- .../components/GradingSchemeSettingsCard.tsx | 2 +- .../MemberSettings/DeleteMemberModal.tsx | 2 +- .../MemberSettings/ResearchGroupMembers.tsx | 4 +- .../components/PresentationSettingsCard.tsx | 2 +- .../components/ProposalSettingsCard.tsx | 2 +- .../components/ResearchGroupSettingsCard.tsx | 2 +- .../ScientificWritingGuideSettingsCard.tsx | 2 +- .../ReviewApplicationPage.tsx | 3 +- .../ApplicationListItem.tsx | 2 +- .../ApplicationReviewBody.tsx | 2 +- .../ApplicationsSidebar.tsx | 2 +- .../NotificationToggleSwitch.tsx | 3 +- .../FileHistoryTable/FileHistoryTable.tsx | 4 +- .../ReplaceAssessmentModal.tsx | 4 +- .../ThesisConfigSection.tsx | 6 +- .../ThesisFeedbackOverview.tsx | 4 +- .../ThesisFeedbackRequestButton.tsx | 6 +- .../ThesisFinalGradeSection.tsx | 3 +- .../SubmitFinalGradeModal.tsx | 2 +- .../ThesisInfoSection/ThesisInfoSection.tsx | 2 +- .../DownloadAllFilesButton.tsx | 4 +- .../components/PresentationCard.tsx | 2 +- .../ThesisProposalSection.tsx | 3 +- .../ThesisStudentInfoSection.tsx | 2 +- .../ThesisVisibilitySelect.tsx | 3 +- .../ThesisWritingSection.tsx | 5 +- .../TopicAdittionalInformationCard.tsx | 2 +- .../ApplicationsProvider.tsx | 15 +- .../providers/ApplicationsProvider/context.ts | 9 +- .../providers/ApplicationsProvider/hooks.ts | 2 +- .../AuthenticationProvider.tsx | 21 +- .../AuthenticationContext/context.ts | 10 +- .../InterviewProcessProvider.tsx | 13 +- .../InterviewProcessProvider/context.ts | 8 +- .../ThesesProvider/ThesesProvider.tsx | 10 +- .../src/providers/ThesesProvider/context.ts | 7 +- .../ThesisCommentsProvider.tsx | 10 +- .../ThesisCommentsProvider/context.ts | 7 +- .../ThesisProvider/ThesisProvider.tsx | 8 +- .../src/providers/ThesisProvider/context.ts | 2 +- client/src/providers/ThesisProvider/hooks.ts | 2 +- .../TopicsProvider/TopicsProvider.tsx | 11 +- .../src/providers/TopicsProvider/context.ts | 7 +- client/src/requests/handler.ts | 4 +- client/src/requests/responses/application.ts | 6 +- .../src/requests/responses/emailtemplate.ts | 2 +- client/src/requests/responses/interview.ts | 4 +- .../src/requests/responses/researchGroup.ts | 2 +- client/src/requests/responses/thesis.ts | 6 +- client/src/requests/responses/topic.ts | 4 +- client/src/utils/customDataLink.tsx | 2 +- client/src/utils/file.ts | 2 +- client/src/utils/format.ts | 15 +- client/src/utils/thesis.ts | 17 +- client/src/utils/user.ts | 2 +- 174 files changed, 1034 insertions(+), 2404 deletions(-) delete mode 100644 client/patches/@eslint+eslintrc+3.3.5.patch rename client/patches/{eslint+9.39.4.patch => eslint+10.3.0.patch} (100%) diff --git a/client/eslint.config.mjs b/client/eslint.config.mjs index a9839ee14..d102117d2 100644 --- a/client/eslint.config.mjs +++ b/client/eslint.config.mjs @@ -1,30 +1,13 @@ -import { fixupConfigRules, fixupPluginRules } from '@eslint/compat' -import typescriptEslint from '@typescript-eslint/eslint-plugin' -import react from 'eslint-plugin-react' -import globals from 'globals' -import tsParser from '@typescript-eslint/parser' -import path from 'node:path' -import { fileURLToPath } from 'node:url' import js from '@eslint/js' -import { FlatCompat } from '@eslint/eslintrc' - -const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) -const compat = new FlatCompat({ - baseDirectory: __dirname, - recommendedConfig: js.configs.recommended, - allConfig: js.configs.all, -}) +import tseslint from '@typescript-eslint/eslint-plugin' +import tsParser from '@typescript-eslint/parser' +import eslintReact from '@eslint-react/eslint-plugin' +import prettierConfig from 'eslint-config-prettier' +import prettierPlugin from 'eslint-plugin-prettier' +import globals from 'globals' export default [ - ...fixupConfigRules( - compat.extends( - 'plugin:react/recommended', - 'plugin:@typescript-eslint/recommended', - 'prettier', - 'plugin:prettier/recommended', - ), - ), + js.configs.recommended, { files: [ 'src/**/*.js', @@ -34,42 +17,70 @@ export default [ 'test/**/*.ts', 'test/**/*.tsx', ], - plugins: { - '@typescript-eslint': fixupPluginRules(typescriptEslint), - react: fixupPluginRules(react), + '@typescript-eslint': tseslint, + '@eslint-react': eslintReact, + prettier: prettierPlugin, }, - languageOptions: { - globals: { - ...globals.browser, - ...globals.jest, - }, - parser: tsParser, ecmaVersion: 'latest', sourceType: 'module', - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - + ecmaFeatures: { jsx: true }, project: ['tsconfig.json'], }, + globals: { + ...globals.browser, + ...globals.jest, + }, }, - settings: { - react: { - version: 'detect', + // @eslint-react reads React-version metadata under the `react-x` namespace + // (its underlying rule package is eslint-plugin-react-x), not under `react` + // like the legacy eslint-plugin-react. Pinning explicitly avoids the + // 'detect' codepath that uses APIs removed in ESLint 10. + 'react-x': { + version: '19.2', }, }, - rules: { + ...tseslint.configs.recommended.rules, + ...eslintReact.configs['recommended-typescript'].rules, + ...prettierConfig.rules, + + // Core JS rules that produce false positives in TS — TypeScript already enforces + // these and `no-redeclare` rejects legitimate function overloads. + 'no-undef': 'off', + 'no-redeclare': 'off', 'no-shadow': 'off', - '@typescript-eslint/no-shadow': ['error'], + '@typescript-eslint/no-shadow': 'error', + + // High-value type-safety rules (require type-aware linting via parserOptions.project). + // These catch entire classes of bugs that the type system alone can't detect. + // `await-thenable` is `error` because awaiting a non-Promise is always wrong. + // `no-floating-promises` and `no-misused-promises` are `warn` for now: the legacy + // codebase has many fire-and-forget calls (`doRequest` with callback) that need + // case-by-case review. Promote to `error` once the warning backlog is cleared. + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/no-floating-promises': 'warn', + '@typescript-eslint/no-misused-promises': 'warn', + '@typescript-eslint/no-unnecessary-type-assertion': 'warn', + '@typescript-eslint/prefer-nullish-coalescing': 'warn', + '@typescript-eslint/prefer-optional-chain': 'warn', + + // Code-quality rules (no type info needed) + '@typescript-eslint/consistent-type-imports': 'warn', + '@typescript-eslint/no-non-null-assertion': 'warn', + '@typescript-eslint/no-explicit-any': 'warn', + eqeqeq: ['error', 'smart'], + 'no-throw-literal': 'error', + // Allow `!!x` since it is idiomatic and preserves TypeScript narrowing in + // `&&` chains (Boolean(x) does not narrow). Still flags `+x`, `~x.indexOf()`, `'' + x`. + 'no-implicit-coercion': ['warn', { boolean: false }], + 'no-console': ['warn', { allow: ['warn', 'error', 'info'] }], - '@typescript-eslint/no-explicit-any': 'off', + // Intentionally disabled: too noisy or stylistic-only. '@typescript-eslint/strict-boolean-expressions': 'off', '@typescript-eslint/return-await': 'off', @@ -81,25 +92,12 @@ export default [ ignoreUrls: true, }, ], - - 'react/react-in-jsx-scope': 'off', - - 'react/jsx-filename-extension': [ - 1, - { - extensions: ['.tsx', '.jsx'], - }, - ], - 'prettier/prettier': [ 'error', { endOfLine: 'auto', }, ], - - 'react/prop-types': 'off', - 'react/display-name': 'off', }, }, ] diff --git a/client/package-lock.json b/client/package-lock.json index e1234051d..7652785db 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -43,9 +43,8 @@ "react-router": "7.15.0" }, "devDependencies": { - "@eslint/compat": "2.1.0", - "@eslint/eslintrc": "3.3.5", - "@eslint/js": "9.39.4", + "@eslint-react/eslint-plugin": "5.7.5", + "@eslint/js": "10.0.1", "@playwright/test": "1.59.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.2", @@ -60,10 +59,9 @@ "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.4", "css-minimizer-webpack-plugin": "8.0.0", - "eslint": "9.39.4", + "eslint": "10.3.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-prettier": "5.5.5", - "eslint-plugin-react": "7.37.5", "fork-ts-checker-webpack-plugin": "9.1.0", "globals": "17.6.0", "html-webpack-plugin": "5.6.7", @@ -493,166 +491,240 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint/compat": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.0.tgz", - "integrity": "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==", + "node_modules/@eslint-react/ast": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@eslint-react/ast/-/ast-5.7.5.tgz", + "integrity": "sha512-xMrkcIJH/n/YnR9ys0izfeHK0/LEEfC9y+YnM1LdKtGUSKm19vcZ506Nc/X1XfGYkHMaJQJvDnXbdMcGaCI8Sw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@eslint/core": "^1.2.1" + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/typescript-estree": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "string-ts": "^2.3.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=22.0.0" }, "peerDependencies": { - "eslint": "^8.40 || 9 || 10" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "eslint": "^10.3.0", + "typescript": "*" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "node_modules/@eslint-react/core": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@eslint-react/core/-/core-5.7.5.tgz", + "integrity": "sha512-v4ltzn/Y0gLVpJnFNBTsASPQI3XeIa925kq+bv6qM5i1/8b2MLMNKrf2InDOUVDWrtIRXwuqkeg9WYDVcpqhhA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.5" + "@eslint-react/ast": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/jsx": "5.7.5", + "@eslint-react/shared": "5.7.5", + "@eslint-react/var": "5.7.5", + "@typescript-eslint/scope-manager": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "ts-pattern": "^5.9.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "node_modules/@eslint-react/eslint": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@eslint-react/eslint/-/eslint-5.7.5.tgz", + "integrity": "sha512-PkpHtaVICA0LDl1oDXw7ZF1Nn4ik0TnrG5Urcacr2lwmvwYDvl31hxoBUqNTA+VkYzIDUqKeAUfMXpCtXe3rDw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@eslint/core": "^0.17.0" + "@typescript-eslint/utils": "^8.59.2" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" } }, - "node_modules/@eslint/config-helpers/node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "node_modules/@eslint-react/eslint-plugin": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@eslint-react/eslint-plugin/-/eslint-plugin-5.7.5.tgz", + "integrity": "sha512-LTNLG1UWhD2W06zu0nqPGv1pRoxLOZuFCOU2ndF8kwYvyF+4VhJoCo4MMTYMJbbmN9ZU61pZFbZAJvPQqXyxkw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.15" + "@eslint-react/shared": "5.7.5", + "eslint-plugin-react-dom": "5.7.5", + "eslint-plugin-react-jsx": "5.7.5", + "eslint-plugin-react-naming-convention": "5.7.5", + "eslint-plugin-react-rsc": "5.7.5", + "eslint-plugin-react-web-api": "5.7.5", + "eslint-plugin-react-x": "5.7.5" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" } }, - "node_modules/@eslint/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", - "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "node_modules/@eslint-react/jsx": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@eslint-react/jsx/-/jsx-5.7.5.tgz", + "integrity": "sha512-dmtbYB9p1yCneH4Eo16Zv1I7f3/BgGMsiQTm6FD+4KynFouOGZja+7TOU2VbUR4Lf1Hjg3RORA+RyD5VZQpc3Q==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.15" + "@eslint-react/ast": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/shared": "5.7.5", + "@eslint-react/var": "5.7.5", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "ts-pattern": "^5.9.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "node_modules/@eslint-react/shared": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@eslint-react/shared/-/shared-5.7.5.tgz", + "integrity": "sha512-NV3P16oiQeZBzBVGBMtjM7mxBkEBFcoIb3P898JBzU1S0BdYhR9d/oMTmdjm+81jBmBOBfuzObRZyV4wl6UWAQ==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.14.0", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.5", - "strip-json-comments": "^3.1.1" + "@eslint-react/eslint": "5.7.5", + "@typescript-eslint/utils": "^8.59.2", + "ts-pattern": "^5.9.0", + "zod": "^4.4.3" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=22.0.0" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/@eslint-react/var": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/@eslint-react/var/-/var-5.7.5.tgz", + "integrity": "sha512-Zyzb/DGSyXZDBkkRGcTww03JDFgVE3eAqMlRwgqoc28fRzIJNcJBXiUFaiDVGluf0OtZwLCspsvGmI9b0nJn+g==", "dev": true, "license": "MIT", + "dependencies": { + "@eslint-react/ast": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@typescript-eslint/scope-manager": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "ts-pattern": "^5.9.0" + }, "engines": { - "node": ">=18" + "node": ">=22.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", + "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", + "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.17.0", + "@eslint/core": "^1.2.1", "levn": "^0.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@exodus/bytes": { @@ -2998,6 +3070,13 @@ "@types/estree": "*" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -4073,23 +4152,6 @@ "dequal": "^2.0.3" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -4097,29 +4159,6 @@ "dev": true, "license": "MIT" }, - "node_modules/array-includes": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", - "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "get-intrinsic": "^1.3.0", - "is-string": "^1.1.1", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -4143,104 +4182,6 @@ "node": ">=0.10.0" } }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", - "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/asn1js": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", @@ -4285,16 +4226,6 @@ "dev": true, "license": "MIT" }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/attr-accept": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", @@ -4304,22 +4235,6 @@ "node": ">=4" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -4373,6 +4288,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/birecord": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/birecord/-/birecord-0.1.1.tgz", + "integrity": "sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==", + "dev": true, + "license": "(MIT OR Apache-2.0)" + }, "node_modules/body-parser": { "version": "1.20.5", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", @@ -4839,6 +4761,13 @@ "node": ">= 12" } }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true, + "license": "MIT" + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -5409,82 +5338,28 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "ms": "^2.1.3" }, "engines": { - "node": ">= 0.4" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/inspect-js" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/dayjs": { - "version": "1.11.20", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", - "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decimal.js": { @@ -5572,24 +5447,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/del": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", @@ -5692,19 +5549,6 @@ "node": ">=6" } }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/dom-accessibility-api": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", @@ -5976,75 +5820,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/es-abstract": { - "version": "1.24.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", - "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -6065,34 +5840,6 @@ "node": ">= 0.4" } }, - "node_modules/es-iterator-helpers": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz", - "integrity": "sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.2", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.1.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.3.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "iterator.prototype": "^1.1.5", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/es-module-lexer": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", @@ -6113,53 +5860,6 @@ "node": ">= 0.4" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6191,33 +5891,30 @@ } }, "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz", + "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.2", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", - "@eslint/plugin-kit": "^0.4.1", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.5.5", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", - "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -6227,8 +5924,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.5", + "minimatch": "^10.2.4", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -6236,7 +5932,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" @@ -6297,61 +5993,168 @@ } } }, - "node_modules/eslint-plugin-react": { - "version": "7.37.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", - "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "node_modules/eslint-plugin-react-dom": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-dom/-/eslint-plugin-react-dom-5.7.5.tgz", + "integrity": "sha512-Offk+olNNmubwu7VjKUKClTIf2/48PyHv0nrLCjNN/3qslql+T93tDbvKwvK9K2p4c0nDZ8vENi5phy06Hy5Tg==", "dev": true, "license": "MIT", "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.3", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.2.1", - "estraverse": "^5.3.0", - "hasown": "^2.0.2", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.9", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.1", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.12", - "string.prototype.repeat": "^1.0.0" + "@eslint-react/ast": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/jsx": "5.7.5", + "@eslint-react/shared": "5.7.5", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "compare-versions": "^6.1.1" }, "engines": { - "node": ">=4" + "node": ">=22.0.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + "eslint": "^10.3.0", + "typescript": "*" } }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/eslint-plugin-react-jsx": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-jsx/-/eslint-plugin-react-jsx-5.7.5.tgz", + "integrity": "sha512-ACA9EGiYF39ZDt4Huv4zKsBYCBuUO9eKsliMkuKbBnK1QbH3tvpdbwIU4g6vdcOKmS7Y+jf9m3fzezGYtw2mdg==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "dependencies": { + "@eslint-react/ast": "5.7.5", + "@eslint-react/core": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/jsx": "5.7.5", + "@eslint-react/shared": "5.7.5", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2" + }, + "engines": { + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" + } + }, + "node_modules/eslint-plugin-react-naming-convention": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-naming-convention/-/eslint-plugin-react-naming-convention-5.7.5.tgz", + "integrity": "sha512-1M4xXTfXrBqtmkSK5XGFuzEKdMhsk4jtlFIHmxqQ8ZtuByv9VUqm+UBIXqW60HSKER4lmHaJnAEhZCVbPJCaUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-react/ast": "5.7.5", + "@eslint-react/core": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/var": "5.7.5", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "ts-pattern": "^5.9.0" + }, + "engines": { + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" + } + }, + "node_modules/eslint-plugin-react-rsc": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-rsc/-/eslint-plugin-react-rsc-5.7.5.tgz", + "integrity": "sha512-2uuJ+tPN0QXEyMdGZjIWuWdqLr0/nLViT3GqNYyZo1oL2Fn7EozM7piXxt7PvfsVqhW9xBAHZFX8+2B5Iwiu1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-react/ast": "5.7.5", + "@eslint-react/core": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/shared": "5.7.5", + "@eslint-react/var": "5.7.5", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2" + }, + "engines": { + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" + } + }, + "node_modules/eslint-plugin-react-web-api": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-web-api/-/eslint-plugin-react-web-api-5.7.5.tgz", + "integrity": "sha512-6lWV7Bydx7ZraMEhcJ/Ra/DKLodBuuP9hlWOQEknUDVXtuyk3l494HqP09Yvh6llBa5Nl7+smXlOP/s8TmKOFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-react/ast": "5.7.5", + "@eslint-react/core": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/shared": "5.7.5", + "@eslint-react/var": "5.7.5", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "birecord": "^0.1.1", + "ts-pattern": "^5.9.0" + }, + "engines": { + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" + } + }, + "node_modules/eslint-plugin-react-x": { + "version": "5.7.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-x/-/eslint-plugin-react-x-5.7.5.tgz", + "integrity": "sha512-oHUoWMWhs2oU3OCrgiVNtzHlIgbZV3GxH/1QPrpCIMT1vn9Nb2TSr8TOLW5nj2kNDglmyCBScBJxo5yxHeS/cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-react/ast": "5.7.5", + "@eslint-react/core": "5.7.5", + "@eslint-react/eslint": "5.7.5", + "@eslint-react/jsx": "5.7.5", + "@eslint-react/shared": "5.7.5", + "@eslint-react/var": "5.7.5", + "@typescript-eslint/scope-manager": "^8.59.2", + "@typescript-eslint/type-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "@typescript-eslint/typescript-estree": "^8.59.2", + "@typescript-eslint/utils": "^8.59.2", + "compare-versions": "^6.1.1", + "string-ts": "^2.3.1", + "ts-api-utils": "^2.5.0", + "ts-pattern": "^5.9.0" + }, + "engines": { + "node": ">=22.0.0" + }, + "peerDependencies": { + "eslint": "^10.3.0", + "typescript": "*" } }, "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -6370,58 +6173,45 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.15.0", + "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "eslint-visitor-keys": "^5.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -6855,22 +6645,6 @@ } } }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.1.0.tgz", @@ -6973,19 +6747,23 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "is-callable": "^1.2.7" + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6994,58 +6772,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", - "license": "MIT", - "engines": { - "node": ">=6" + "engines": { + "node": ">=6" } }, "node_modules/get-proto": { @@ -7062,24 +6795,6 @@ "node": ">= 0.4" } }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7152,23 +6867,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", @@ -7223,19 +6921,6 @@ "dev": true, "license": "MIT" }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7259,22 +6944,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -7288,22 +6957,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/hasown": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", @@ -7697,21 +7350,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -7732,24 +7370,6 @@ "node": ">= 10" } }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -7757,42 +7377,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -7806,36 +7390,6 @@ "node": ">=8" } }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-core-module": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", @@ -7852,41 +7406,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -7913,42 +7432,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -7997,32 +7480,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-network-error": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz", @@ -8046,23 +7503,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -8074,209 +7514,64 @@ } }, "node_modules/is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-path-inside": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-is-inside": "^1.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.16" + "is-path-inside": "^2.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "path-is-inside": "^1.0.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6" } }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3" - }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakset": { + "node_modules/is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" + "isobject": "^3.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, "node_modules/is-what": { "version": "4.1.16", "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", @@ -8366,24 +7661,6 @@ "node": ">=8" } }, - "node_modules/iterator.prototype": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", - "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "get-proto": "^1.0.0", - "has-symbols": "^1.1.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/jest-regex-util": { "version": "30.4.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", @@ -8599,22 +7876,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, "node_modules/jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -9108,13 +8369,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -9549,35 +8803,6 @@ "license": "MIT", "optional": true }, - "node_modules/node-exports-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", - "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array.prototype.flatmap": "^1.3.3", - "es-errors": "^1.3.0", - "object.entries": "^1.1.9", - "semver": "^6.3.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/node-exports-info/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/node-releases": { "version": "2.0.38", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", @@ -9640,81 +8865,6 @@ "node": ">= 0.4" } }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", - "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -9817,24 +8967,6 @@ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", "license": "MIT" }, - "node_modules/own-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", - "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.6", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -10297,16 +9429,6 @@ "node": ">=18" } }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/postcss": { "version": "8.5.14", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", @@ -11694,50 +10816,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -11786,30 +10864,6 @@ "dev": true, "license": "MIT" }, - "node_modules/resolve": { - "version": "2.0.0-next.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", - "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "node-exports-info": "^1.6.0", - "object-keys": "^1.1.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -11903,84 +10957,29 @@ }, "node_modules/rope-sequence": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", - "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", - "license": "MIT" - }, - "node_modules/run-applescript": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", - "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "get-intrinsic": "^1.3.0", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", + "license": "MIT" }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -12261,37 +11260,6 @@ "node": ">= 0.4" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -12592,20 +11560,6 @@ "dev": true, "license": "MIT" }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -12615,103 +11569,12 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/string.prototype.matchall": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", - "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.6", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "internal-slot": "^1.1.0", - "regexp.prototype.flags": "^1.5.3", - "set-function-name": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "node_modules/string-ts": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/string-ts/-/string-ts-2.3.1.tgz", + "integrity": "sha512-xSJq+BS52SaFFAVxuStmx6n5aYZU571uYUnUrPXkPFCfdHyZMMlbP2v2Wx5sNBnAVzq/2+0+mcBLBa3Xa5ubYw==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/strip-ansi": { "version": "6.0.1", @@ -12749,19 +11612,6 @@ "node": ">=8" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/style-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", @@ -13443,6 +12293,13 @@ } } }, + "node_modules/ts-pattern": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.9.0.tgz", + "integrity": "sha512-6s5V71mX8qBUmlgbrfL33xDUwO0fq48rxAu2LBE11WBeGdpCPOsXksQbZJHvHwhrd3QjUusd3mAOM5Gg0mFBLg==", + "dev": true, + "license": "MIT" + }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -13526,84 +12383,6 @@ "node": ">= 0.6" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -13648,25 +12427,6 @@ "typescript": ">=4.0.0" } }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/undici": { "version": "7.25.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", @@ -14609,95 +13369,6 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.20", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", - "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -14848,6 +13519,16 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/client/package.json b/client/package.json index 79434685f..90958c4f1 100644 --- a/client/package.json +++ b/client/package.json @@ -90,9 +90,8 @@ "react-router": "7.15.0" }, "devDependencies": { - "@eslint/compat": "2.1.0", - "@eslint/eslintrc": "3.3.5", - "@eslint/js": "9.39.4", + "@eslint-react/eslint-plugin": "5.7.5", + "@eslint/js": "10.0.1", "@playwright/test": "1.59.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.2", @@ -107,10 +106,9 @@ "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.4", "css-minimizer-webpack-plugin": "8.0.0", - "eslint": "9.39.4", + "eslint": "10.3.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-prettier": "5.5.5", - "eslint-plugin-react": "7.37.5", "fork-ts-checker-webpack-plugin": "9.1.0", "globals": "17.6.0", "html-webpack-plugin": "5.6.7", diff --git a/client/patches/@eslint+eslintrc+3.3.5.patch b/client/patches/@eslint+eslintrc+3.3.5.patch deleted file mode 100644 index 8ec92895b..000000000 --- a/client/patches/@eslint+eslintrc+3.3.5.patch +++ /dev/null @@ -1,105 +0,0 @@ -diff --git a/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs b/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs -index 6000445..e9d8e80 100644 ---- a/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs -+++ b/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs -@@ -216,6 +216,7 @@ function emitDeprecationWarning(source, errorCode) { - * Copyright (c) 2015-2017 Evgeny Poberezkin - */ - const metaSchema = { -+ $id: "http://json-schema.org/draft-04/schema", - id: "http://json-schema.org/draft-04/schema#", - $schema: "http://json-schema.org/draft-04/schema#", - description: "Core schema meta-schema", -@@ -374,15 +375,13 @@ var ajvOrig = (additionalOptions = {}) => { - meta: false, - useDefaults: true, - validateSchema: false, -- missingRefs: "ignore", - verbose: true, -- schemaId: "auto", -+ strict: false, -+ defaultMeta: metaSchema.$id, - ...additionalOptions - }); - - ajv.addMetaSchema(metaSchema); -- // eslint-disable-next-line no-underscore-dangle -- part of the API -- ajv._opts.defaultMeta = metaSchema.id; - - return ajv; - }; -diff --git a/node_modules/@eslint/eslintrc/dist/eslintrc.cjs b/node_modules/@eslint/eslintrc/dist/eslintrc.cjs -index 1b76091..4006c05 100644 ---- a/node_modules/@eslint/eslintrc/dist/eslintrc.cjs -+++ b/node_modules/@eslint/eslintrc/dist/eslintrc.cjs -@@ -1449,6 +1449,7 @@ function emitDeprecationWarning(source, errorCode) { - * Copyright (c) 2015-2017 Evgeny Poberezkin - */ - const metaSchema = { -+ $id: "http://json-schema.org/draft-04/schema", - id: "http://json-schema.org/draft-04/schema#", - $schema: "http://json-schema.org/draft-04/schema#", - description: "Core schema meta-schema", -@@ -1607,15 +1608,13 @@ var ajvOrig = (additionalOptions = {}) => { - meta: false, - useDefaults: true, - validateSchema: false, -- missingRefs: "ignore", - verbose: true, -- schemaId: "auto", -+ strict: false, -+ defaultMeta: metaSchema.$id, - ...additionalOptions - }); - - ajv.addMetaSchema(metaSchema); -- // eslint-disable-next-line no-underscore-dangle -- part of the API -- ajv._opts.defaultMeta = metaSchema.id; - - return ajv; - }; -diff --git a/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js b/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js -index 3a445b1..afc8513 100644 ---- a/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js -+++ b/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js -@@ -20,9 +20,7 @@ - import assert from "node:assert"; - import path from "node:path"; - import util from "node:util"; --import minimatch from "minimatch"; -- --const { Minimatch } = minimatch; -+import { minimatch, Minimatch } from "minimatch"; - - const minimatchOpts = { dot: true, matchBase: true }; - -diff --git a/node_modules/@eslint/eslintrc/lib/shared/ajv.js b/node_modules/@eslint/eslintrc/lib/shared/ajv.js -index 7e53d12..82282c2 100644 ---- a/node_modules/@eslint/eslintrc/lib/shared/ajv.js -+++ b/node_modules/@eslint/eslintrc/lib/shared/ajv.js -@@ -19,6 +19,7 @@ import Ajv from "ajv"; - * Copyright (c) 2015-2017 Evgeny Poberezkin - */ - const metaSchema = { -+ $id: "http://json-schema.org/draft-04/schema", - id: "http://json-schema.org/draft-04/schema#", - $schema: "http://json-schema.org/draft-04/schema#", - description: "Core schema meta-schema", -@@ -177,15 +178,13 @@ export default (additionalOptions = {}) => { - meta: false, - useDefaults: true, - validateSchema: false, -- missingRefs: "ignore", - verbose: true, -- schemaId: "auto", -+ strict: false, -+ defaultMeta: metaSchema.$id, - ...additionalOptions - }); - - ajv.addMetaSchema(metaSchema); -- // eslint-disable-next-line no-underscore-dangle -- part of the API -- ajv._opts.defaultMeta = metaSchema.id; - - return ajv; - }; diff --git a/client/patches/eslint+9.39.4.patch b/client/patches/eslint+10.3.0.patch similarity index 100% rename from client/patches/eslint+9.39.4.patch rename to client/patches/eslint+10.3.0.patch diff --git a/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx index 7475eb143..9b2bf19c5 100644 --- a/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx +++ b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx @@ -1,4 +1,6 @@ -import { PropsWithChildren, Suspense, useEffect } from 'react' +import type { PropsWithChildren } from 'react' +import { Suspense, useEffect } from 'react' +import type { MantineSize } from '@mantine/core' import { ActionIcon, AppShell, @@ -8,7 +10,6 @@ import { Divider, Flex, Group, - MantineSize, Stack, Text, Tooltip, @@ -137,7 +138,7 @@ const AuthenticatedArea = (props: PropsWithChildren) => minimizeAnimationDuration, ) // only use debounced State if value is false because otherwise the text is formatted weirdly if you expand the navigation - const minimized = opened ? false : minimizedState || !!debouncedMinimized + const minimized = opened ? false : minimizedState || Boolean(debouncedMinimized) const location = useLocation() const navigationType = useNavigationType() @@ -202,7 +203,7 @@ const AuthenticatedArea = (props: PropsWithChildren) => (item) => !item.groups || item.groups.some((role) => auth.user?.groups?.includes(role)), ) - .filter((item) => item.display == undefined || item.display === true) + .filter((item) => item.display === undefined || item.display === true) .filter((item) => item.hideFromGroups ? !item.hideFromGroups.some((role) => auth.user?.groups?.includes(role)) diff --git a/client/src/app/layout/ContentContainer/ContentContainer.tsx b/client/src/app/layout/ContentContainer/ContentContainer.tsx index 9a8cd82b2..7bbf724e7 100644 --- a/client/src/app/layout/ContentContainer/ContentContainer.tsx +++ b/client/src/app/layout/ContentContainer/ContentContainer.tsx @@ -1,5 +1,6 @@ -import { PropsWithChildren } from 'react' -import { Container, MantineSize } from '@mantine/core' +import type { PropsWithChildren } from 'react' +import type { MantineSize } from '@mantine/core' +import { Container } from '@mantine/core' interface IContentContainerProps { size?: number | MantineSize | (string & {}) | undefined diff --git a/client/src/app/layout/PublicArea/PublicArea.tsx b/client/src/app/layout/PublicArea/PublicArea.tsx index 683192932..ce4e03025 100644 --- a/client/src/app/layout/PublicArea/PublicArea.tsx +++ b/client/src/app/layout/PublicArea/PublicArea.tsx @@ -1,6 +1,7 @@ -import { PropsWithChildren } from 'react' +import type { PropsWithChildren } from 'react' import Footer from '../../../components/Footer/Footer' -import { AppShell, Box, Container, Divider, Flex, MantineSize, Stack } from '@mantine/core' +import type { MantineSize } from '@mantine/core' +import { AppShell, Box, Container, Divider, Flex, Stack } from '@mantine/core' import ScrollToTop from '../ScrollToTop/ScrollToTop' import Header from '../../../components/Header/Header' import ContentContainer from '../ContentContainer/ContentContainer' diff --git a/client/src/components/ApplicationData/ApplicationData.tsx b/client/src/components/ApplicationData/ApplicationData.tsx index 01294b857..ff6b2a24a 100644 --- a/client/src/components/ApplicationData/ApplicationData.tsx +++ b/client/src/components/ApplicationData/ApplicationData.tsx @@ -1,6 +1,7 @@ -import { IApplication } from '../../requests/responses/application' +import type { IApplication } from '../../requests/responses/application' import { Stack, Group, Grid, Title, Badge, Accordion } from '@mantine/core' -import React, { ReactNode } from 'react' +import type { ReactNode } from 'react' +import React from 'react' import { GLOBAL_CONFIG } from '../../config/global' import { AVAILABLE_COUNTRIES } from '../../config/countries' import { diff --git a/client/src/components/ApplicationDeleteButton/ApplicationDeleteButton.tsx b/client/src/components/ApplicationDeleteButton/ApplicationDeleteButton.tsx index 1674dd3f9..91315a423 100644 --- a/client/src/components/ApplicationDeleteButton/ApplicationDeleteButton.tsx +++ b/client/src/components/ApplicationDeleteButton/ApplicationDeleteButton.tsx @@ -1,5 +1,6 @@ import { doRequest } from '../../requests/request' -import { ApplicationState, IApplication } from '../../requests/responses/application' +import type { IApplication } from '../../requests/responses/application' +import { ApplicationState } from '../../requests/responses/application' import { showSimpleError, showSimpleSuccess } from '../../utils/notification' import { Button, Modal, Stack, Text, Tooltip, type ButtonProps } from '@mantine/core' import React, { useState } from 'react' diff --git a/client/src/components/ApplicationModal/ApplicationModal.tsx b/client/src/components/ApplicationModal/ApplicationModal.tsx index 21193b5ef..56346bc12 100644 --- a/client/src/components/ApplicationModal/ApplicationModal.tsx +++ b/client/src/components/ApplicationModal/ApplicationModal.tsx @@ -1,4 +1,5 @@ -import { ApplicationState, IApplication } from '../../requests/responses/application' +import type { IApplication } from '../../requests/responses/application' +import { ApplicationState } from '../../requests/responses/application' import { Button, Divider, Modal, Stack } from '@mantine/core' import React from 'react' import ApplicationReviewForm from '../ApplicationReviewForm/ApplicationReviewForm' @@ -23,7 +24,7 @@ const ApplicationModal = (props: IApplicationModalProps) => { } = props return ( - + {application && ( { onChange={(value) => { setFilters((prev) => ({ ...prev, - states: value as ApplicationState[], + states: value, })) }} searchable diff --git a/client/src/components/ApplicationsTable/ApplicationsTable.tsx b/client/src/components/ApplicationsTable/ApplicationsTable.tsx index e7d2be90e..fd71eae9e 100644 --- a/client/src/components/ApplicationsTable/ApplicationsTable.tsx +++ b/client/src/components/ApplicationsTable/ApplicationsTable.tsx @@ -1,10 +1,11 @@ import React from 'react' -import { IApplication } from '../../requests/responses/application' -import { DataTable, DataTableColumn } from 'mantine-datatable' +import type { IApplication } from '../../requests/responses/application' +import type { DataTableColumn } from 'mantine-datatable' +import { DataTable } from 'mantine-datatable' import { Badge, Center } from '@mantine/core' import { formatApplicationState, formatDate, formatThesisType } from '../../utils/format' import { useApplicationsContext } from '../../providers/ApplicationsProvider/hooks' -import { IApplicationsSort } from '../../providers/ApplicationsProvider/context' +import type { IApplicationsSort } from '../../providers/ApplicationsProvider/context' import { ApplicationStateColor } from '../../config/colors' import AvatarUser from '../AvatarUser/AvatarUser' diff --git a/client/src/components/AuthenticatedFileDownloadButton/AuthenticatedFileDownloadButton.tsx b/client/src/components/AuthenticatedFileDownloadButton/AuthenticatedFileDownloadButton.tsx index a376bdab3..316c72b84 100644 --- a/client/src/components/AuthenticatedFileDownloadButton/AuthenticatedFileDownloadButton.tsx +++ b/client/src/components/AuthenticatedFileDownloadButton/AuthenticatedFileDownloadButton.tsx @@ -1,5 +1,6 @@ import { Button, type ButtonProps } from '@mantine/core' -import { PropsWithChildren, useState } from 'react' +import type { PropsWithChildren } from 'react' +import { useState } from 'react' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' diff --git a/client/src/components/AuthenticatedFilePreview/AuthenticatedFilePreview.tsx b/client/src/components/AuthenticatedFilePreview/AuthenticatedFilePreview.tsx index 9d4f5b0e4..5756c1ce2 100644 --- a/client/src/components/AuthenticatedFilePreview/AuthenticatedFilePreview.tsx +++ b/client/src/components/AuthenticatedFilePreview/AuthenticatedFilePreview.tsx @@ -1,11 +1,12 @@ -import { ReactNode, useEffect, useState } from 'react' +import type { ReactNode } from 'react' +import { useEffect, useState } from 'react' import { Button, Center, Group, Stack, type BoxProps } from '@mantine/core' import { downloadFile } from '../../utils/blob' import FilePreview from '../FilePreview/FilePreview' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' -import { UploadFileType } from '../../config/types' +import type { UploadFileType } from '../../config/types' import { getAdjustedFileType } from '../../utils/file' interface IAuthenticatedFilePreviewProps extends BoxProps { diff --git a/client/src/components/AuthenticatedFilePreviewButton/AuthenticatedFilePreviewButton.tsx b/client/src/components/AuthenticatedFilePreviewButton/AuthenticatedFilePreviewButton.tsx index 262025016..b8502726d 100644 --- a/client/src/components/AuthenticatedFilePreviewButton/AuthenticatedFilePreviewButton.tsx +++ b/client/src/components/AuthenticatedFilePreviewButton/AuthenticatedFilePreviewButton.tsx @@ -1,7 +1,8 @@ import { Button, Modal, type ButtonProps } from '@mantine/core' -import { PropsWithChildren, useState } from 'react' +import type { PropsWithChildren } from 'react' +import { useState } from 'react' import { AuthenticatedFilePreview } from '../AuthenticatedFilePreview/AuthenticatedFilePreview' -import { UploadFileType } from '../../config/types' +import type { UploadFileType } from '../../config/types' import { getAdjustedFileType } from '../../utils/file' interface IAuthenticatedFilePreviewButtonProps extends ButtonProps { diff --git a/client/src/components/AvatarUser/AvatarUser.tsx b/client/src/components/AvatarUser/AvatarUser.tsx index 6d5f91841..21ea649f9 100644 --- a/client/src/components/AvatarUser/AvatarUser.tsx +++ b/client/src/components/AvatarUser/AvatarUser.tsx @@ -1,5 +1,6 @@ -import { IMinimalUser } from '../../requests/responses/user' -import { Group, MantineSize, Text } from '@mantine/core' +import type { IMinimalUser } from '../../requests/responses/user' +import type { MantineSize } from '@mantine/core' +import { Group, Text } from '@mantine/core' import { formatUser } from '../../utils/format' import { CustomAvatar } from '../CustomAvatar/CustomAvatar' diff --git a/client/src/components/AvatarUserList/AvatarUserList.tsx b/client/src/components/AvatarUserList/AvatarUserList.tsx index ce1ff3261..7a2a823b7 100644 --- a/client/src/components/AvatarUserList/AvatarUserList.tsx +++ b/client/src/components/AvatarUserList/AvatarUserList.tsx @@ -1,5 +1,6 @@ -import { IMinimalUser } from '../../requests/responses/user' -import { MantineSize, Stack } from '@mantine/core' +import type { IMinimalUser } from '../../requests/responses/user' +import type { MantineSize } from '@mantine/core' +import { Stack } from '@mantine/core' import AvatarUser from '../AvatarUser/AvatarUser' interface IAvatarUserListProps { diff --git a/client/src/components/ConfirmationButton/ConfirmationButton.tsx b/client/src/components/ConfirmationButton/ConfirmationButton.tsx index e5f839cc0..a2203d4e5 100644 --- a/client/src/components/ConfirmationButton/ConfirmationButton.tsx +++ b/client/src/components/ConfirmationButton/ConfirmationButton.tsx @@ -7,7 +7,8 @@ import { Text, type ButtonProps, } from '@mantine/core' -import { forwardRef, ReactNode, useState } from 'react' +import type { ReactNode } from 'react' +import { forwardRef, useState } from 'react' interface IConfirmationButtonProps extends ButtonProps { confirmationTitle: string diff --git a/client/src/components/CustomAvatar/CustomAvatar.tsx b/client/src/components/CustomAvatar/CustomAvatar.tsx index 504690364..2c1906086 100644 --- a/client/src/components/CustomAvatar/CustomAvatar.tsx +++ b/client/src/components/CustomAvatar/CustomAvatar.tsx @@ -1,6 +1,7 @@ import { useContext, useEffect, useRef, useState } from 'react' -import { IMinimalUser } from '../../requests/responses/user' -import { Avatar, MantineSize, type BoxProps } from '@mantine/core' +import type { IMinimalUser } from '../../requests/responses/user' +import type { MantineSize } from '@mantine/core' +import { Avatar, type BoxProps } from '@mantine/core' import { getAvatar, getAvatarPath } from '../../utils/user' import { AuthenticationContext } from '../../providers/AuthenticationContext/context' import { doRequest } from '../../requests/request' diff --git a/client/src/components/DocumentEditor/DocumentEditor.tsx b/client/src/components/DocumentEditor/DocumentEditor.tsx index 4f3953d3b..4a7133350 100644 --- a/client/src/components/DocumentEditor/DocumentEditor.tsx +++ b/client/src/components/DocumentEditor/DocumentEditor.tsx @@ -6,7 +6,8 @@ import Underline from '@tiptap/extension-underline' import TextAlign from '@tiptap/extension-text-align' import Superscript from '@tiptap/extension-superscript' import SubScript from '@tiptap/extension-subscript' -import { ChangeEvent, ComponentProps, useEffect, useRef } from 'react' +import type { ChangeEvent, ComponentProps } from 'react' +import { useEffect, useRef } from 'react' import { Input, Text, useMantineColorScheme } from '@mantine/core' import { ensureAbsoluteLinkHref } from '../../utils/format' diff --git a/client/src/components/DropDownMultiSelect/DropDownMultiSelect.tsx b/client/src/components/DropDownMultiSelect/DropDownMultiSelect.tsx index 5f4901bd0..d2251dae9 100644 --- a/client/src/components/DropDownMultiSelect/DropDownMultiSelect.tsx +++ b/client/src/components/DropDownMultiSelect/DropDownMultiSelect.tsx @@ -47,12 +47,9 @@ const DropDownMultiSelect = ({ const computedColorScheme = useComputedColorScheme() useEffect(() => { - let filteredData = data - if (searchFunction) { - filteredData = searchFunction(search) - } else { - filteredData = data.filter((item) => item.toLowerCase().includes(search.toLowerCase())) - } + const filteredData = searchFunction + ? searchFunction(search) + : data.filter((item) => item.toLowerCase().includes(search.toLowerCase())) setDisplayData( showSelectedOnTop diff --git a/client/src/components/EnvironmentBanner/EnvironmentBanner.tsx b/client/src/components/EnvironmentBanner/EnvironmentBanner.tsx index f22da7e7a..e9a6be2cd 100644 --- a/client/src/components/EnvironmentBanner/EnvironmentBanner.tsx +++ b/client/src/components/EnvironmentBanner/EnvironmentBanner.tsx @@ -1,6 +1,7 @@ -import { Group, Text, MantineColor } from '@mantine/core' +import type { MantineColor } from '@mantine/core' +import { Group, Text } from '@mantine/core' import { Warning } from '@phosphor-icons/react' -import { Environment } from '../../config/types' +import type { Environment } from '../../config/types' import { GLOBAL_CONFIG } from '../../config/global' export const ENVIRONMENT_BANNER_HEIGHT = 28 @@ -21,7 +22,7 @@ export const labelByEnvironment: Record = { export const isEnvironmentBannerVisible = (): boolean => { const environment = GLOBAL_CONFIG.environment - return !!environment && environment !== 'production' + return Boolean(environment) && environment !== 'production' } const EnvironmentBanner = () => { diff --git a/client/src/components/FileElement/FileElement.tsx b/client/src/components/FileElement/FileElement.tsx index 920e573f0..d8771638d 100644 --- a/client/src/components/FileElement/FileElement.tsx +++ b/client/src/components/FileElement/FileElement.tsx @@ -1,12 +1,5 @@ -import { - Group, - MantineColor, - MantineFontSize, - Paper, - Stack, - Text, - useMantineColorScheme, -} from '@mantine/core' +import type { MantineColor, MantineFontSize } from '@mantine/core' +import { Group, Paper, Stack, Text, useMantineColorScheme } from '@mantine/core' import { FileAudioIcon, FileIcon, FileImageIcon, FilePdfIcon } from '@phosphor-icons/react' import { FileVideoIcon } from '@phosphor-icons/react/dist/ssr' diff --git a/client/src/components/FilePreview/FilePreview.tsx b/client/src/components/FilePreview/FilePreview.tsx index 7fcfc56fe..2ddea80c0 100644 --- a/client/src/components/FilePreview/FilePreview.tsx +++ b/client/src/components/FilePreview/FilePreview.tsx @@ -1,6 +1,6 @@ import { AspectRatio, Group, Text } from '@mantine/core' import { useMemo } from 'react' -import { UploadFileType } from '../../config/types' +import type { UploadFileType } from '../../config/types' import { File } from '@phosphor-icons/react' import { getAdjustedFileType } from '../../utils/file' diff --git a/client/src/components/Footer/Footer.tsx b/client/src/components/Footer/Footer.tsx index dc4b976b4..914903532 100644 --- a/client/src/components/Footer/Footer.tsx +++ b/client/src/components/Footer/Footer.tsx @@ -1,4 +1,5 @@ -import { Anchor, Container, Flex, MantineSize } from '@mantine/core' +import type { MantineSize } from '@mantine/core' +import { Anchor, Container, Flex } from '@mantine/core' import { GLOBAL_CONFIG } from '../../config/global' import { Link } from 'react-router' import packageJson from '../../../package.json' diff --git a/client/src/components/GanttChart/GanttChart.tsx b/client/src/components/GanttChart/GanttChart.tsx index 7ac2d5472..c9acc7588 100644 --- a/client/src/components/GanttChart/GanttChart.tsx +++ b/client/src/components/GanttChart/GanttChart.tsx @@ -1,9 +1,12 @@ import * as classes from './GanttChart.module.css' -import { ArrayElement, arrayUnique } from '../../utils/array' -import { ReactNode, useMemo, useState, useEffect, CSSProperties } from 'react' +import type { ArrayElement } from '../../utils/array' +import { arrayUnique } from '../../utils/array' +import type { ReactNode, CSSProperties } from 'react' +import { useMemo, useState, useEffect } from 'react' import { Button, Collapse, Popover, Skeleton } from '@mantine/core' import { CaretDown, CaretUp } from '@phosphor-icons/react' -import { DateRange, GanttChartContext, IGanttChartContext, IGanttChartDataElement } from './context' +import type { DateRange, IGanttChartContext, IGanttChartDataElement } from './context' +import { GanttChartContext } from './context' import GanttChartRangeSlider from './components/GanttChartRangeSlider/GanttChartRangeSlider' import GanttChartZoomContainer from './components/GanttChartZoomContainer/GanttChartZoomContainer' import GanttChartTicks from './components/GanttChartTicks/GanttChartTicks' diff --git a/client/src/components/GanttChart/components/GanttChartZoomContainer/GanttChartZoomContainer.tsx b/client/src/components/GanttChart/components/GanttChartZoomContainer/GanttChartZoomContainer.tsx index 12c48a290..105803fec 100644 --- a/client/src/components/GanttChart/components/GanttChartZoomContainer/GanttChartZoomContainer.tsx +++ b/client/src/components/GanttChart/components/GanttChartZoomContainer/GanttChartZoomContainer.tsx @@ -1,6 +1,8 @@ -import { TouchEvent, Touch, WheelEvent, useEffect, useRef, PropsWithChildren } from 'react' +import type { TouchEvent, Touch, WheelEvent, PropsWithChildren } from 'react' +import { useEffect, useRef } from 'react' import * as classes from '../../GanttChart.module.css' -import { DateRange, useGanttChartContext } from '../../context' +import type { DateRange } from '../../context' +import { useGanttChartContext } from '../../context' const GanttChartZoomContainer = (props: PropsWithChildren) => { const { children } = props diff --git a/client/src/components/GanttChart/context.ts b/client/src/components/GanttChart/context.ts index 3cf7f7518..ca2b41c6e 100644 --- a/client/src/components/GanttChart/context.ts +++ b/client/src/components/GanttChart/context.ts @@ -1,4 +1,5 @@ -import React, { Dispatch, ReactNode, SetStateAction, useContext } from 'react' +import type { Dispatch, ReactNode, SetStateAction } from 'react' +import React, { useContext } from 'react' export type DateRange = [number, number] diff --git a/client/src/components/InterviewSlotInformation/InterviewSlotInformation.tsx b/client/src/components/InterviewSlotInformation/InterviewSlotInformation.tsx index 60f1ea7f5..1d983baa1 100644 --- a/client/src/components/InterviewSlotInformation/InterviewSlotInformation.tsx +++ b/client/src/components/InterviewSlotInformation/InterviewSlotInformation.tsx @@ -1,5 +1,5 @@ import { Stack } from '@mantine/core' -import { IInterviewSlot } from '../../requests/responses/interview' +import type { IInterviewSlot } from '../../requests/responses/interview' import InterviewInfoItem from '../InterviewInfoItem/InterviewInfoItem' import { CalendarBlankIcon, ClockIcon, MapPinIcon, WebcamIcon } from '@phosphor-icons/react' diff --git a/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx b/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx index b5b3cd521..b966952ba 100644 --- a/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx +++ b/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx @@ -5,8 +5,8 @@ import { showSimpleError } from '../../utils/notification' import { doRequest } from '../../requests/request' import { getApiResponseErrorMessage } from '../../requests/handler' import UserInformationRow from '../UserInformationRow/UserInformationRow' -import { ILightUser } from '../../requests/responses/user' -import { IKeycloakUserElement } from '../../requests/responses/keycloakUser' +import type { ILightUser } from '../../requests/responses/user' +import type { IKeycloakUserElement } from '../../requests/responses/keycloakUser' interface KeycloakUserAutocompleteProps { selectedLabel: string diff --git a/client/src/components/LabeledItem/LabeledItem.tsx b/client/src/components/LabeledItem/LabeledItem.tsx index 724ece6c2..9fa849d56 100644 --- a/client/src/components/LabeledItem/LabeledItem.tsx +++ b/client/src/components/LabeledItem/LabeledItem.tsx @@ -1,4 +1,5 @@ -import React, { ReactNode } from 'react' +import type { ReactNode } from 'react' +import React from 'react' import { ActionIcon, CopyButton, Group, Input, Text, Tooltip } from '@mantine/core' import { Check, Copy } from '@phosphor-icons/react' diff --git a/client/src/components/NoContentFoundCard/NoContentFoundCard.tsx b/client/src/components/NoContentFoundCard/NoContentFoundCard.tsx index e4a75c274..5d2f26799 100644 --- a/client/src/components/NoContentFoundCard/NoContentFoundCard.tsx +++ b/client/src/components/NoContentFoundCard/NoContentFoundCard.tsx @@ -1,5 +1,5 @@ import { Card, Stack, Text, Title, Center } from '@mantine/core' -import { ReactNode } from 'react' +import type { ReactNode } from 'react' interface NoContentFoundCardProps { icon: ReactNode diff --git a/client/src/components/PresentationsTable/PresentationsTable.tsx b/client/src/components/PresentationsTable/PresentationsTable.tsx index 7b5091825..5740efbd5 100644 --- a/client/src/components/PresentationsTable/PresentationsTable.tsx +++ b/client/src/components/PresentationsTable/PresentationsTable.tsx @@ -1,12 +1,13 @@ import React, { useState } from 'react' -import { DataTable, DataTableColumn } from 'mantine-datatable' -import { +import type { DataTableColumn } from 'mantine-datatable' +import { DataTable } from 'mantine-datatable' +import type { IPublishedPresentation, IPublishedThesis, - isPublishedPresentation, IThesis, IThesisPresentation, } from '../../requests/responses/thesis' +import { isPublishedPresentation } from '../../requests/responses/thesis' import { formatDate, formatPresentationType } from '../../utils/format' import { GLOBAL_CONFIG } from '../../config/global' import { Anchor, Badge, Button, Center, Group, Stack, Text, Tooltip } from '@mantine/core' @@ -227,7 +228,7 @@ const PresentationsTable = row.thesisId === editPresentationModal?.thesisId)} presentation={editPresentationModal} - opened={!!editPresentationModal} + opened={Boolean(editPresentationModal)} onClose={() => setEditPresentationModal(undefined)} onChange={onChange} /> diff --git a/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx b/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx index 29b10f85a..2b9b0c784 100644 --- a/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx +++ b/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx @@ -4,7 +4,7 @@ import { useEffect } from 'react' import { useThesisUpdateAction } from '../../../../providers/ThesisProvider/hooks' import { Accordion, Alert, Button, Modal, Select, Stack, TextInput } from '@mantine/core' import { doRequest } from '../../../../requests/request' -import { +import type { IPublishedPresentation, IPublishedThesis, IThesis, diff --git a/client/src/components/PresentationsTable/components/SchedulePresentationModal/SchedulePresentationModal.tsx b/client/src/components/PresentationsTable/components/SchedulePresentationModal/SchedulePresentationModal.tsx index c16a9179a..1aa734c8f 100644 --- a/client/src/components/PresentationsTable/components/SchedulePresentationModal/SchedulePresentationModal.tsx +++ b/client/src/components/PresentationsTable/components/SchedulePresentationModal/SchedulePresentationModal.tsx @@ -1,4 +1,4 @@ -import { +import type { IPublishedPresentation, IThesis, IThesisPresentation, @@ -65,7 +65,12 @@ const SchedulePresentationModal = (props: ISchedulePresentationModalProps) => { }, [presentation?.presentationId]) return ( - onClose()} centered> + onClose()} + centered + > { const user = userEvent.setup() renderForm() - const description = screen.getByLabelText(/description/i) as HTMLTextAreaElement + const description = screen.getByLabelText(/description/i) await user.clear(description) await user.type(description, 'A different description') expect(description).toHaveValue('A different description') @@ -84,7 +84,7 @@ describe('ResearchGroupForm — issue #521 (discardable form)', () => { // Edit the head autocomplete too so we can verify the label restoration. const headInput = screen.getByRole('combobox', { name: /group head/i, - }) as HTMLInputElement + }) expect(headInput).toHaveValue('Ada Lovelace') await user.clear(headInput) await user.type(headInput, 'Someone Else') @@ -94,9 +94,7 @@ describe('ResearchGroupForm — issue #521 (discardable form)', () => { expect(description).toHaveValue('Original description') // After discard, the head autocomplete remounts with the original label. - expect(screen.getByRole('combobox', { name: /group head/i }) as HTMLInputElement).toHaveValue( - 'Ada Lovelace', - ) + expect(screen.getByRole('combobox', { name: /group head/i })).toHaveValue('Ada Lovelace') expect(screen.getByRole('button', { name: /discard changes/i })).toBeDisabled() expect(screen.getByRole('button', { name: /^save$/i })).toBeDisabled() }) @@ -106,7 +104,7 @@ describe('ResearchGroupForm — issue #521 (discardable form)', () => { renderForm() // Force a validation failure: name must be at least 2 characters. - const name = screen.getByLabelText(/name/i) as HTMLInputElement + const name = screen.getByLabelText(/name/i) await user.clear(name) await user.type(name, 'a') expect(await screen.findByText(/name must be at least 2 characters/i)).toBeInTheDocument() diff --git a/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx b/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx index a869d8e1d..c44277808 100644 --- a/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx +++ b/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx @@ -3,8 +3,8 @@ import { useForm } from '@mantine/form' import KeycloakUserAutocomplete from '../KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete' import { GLOBAL_CONFIG } from '../../config/global' import { useState } from 'react' -import { ResearchGroupFormValues } from '../../pages/ResearchGroupAdminPage/components/CreateResearchGroupModal' -import { IResearchGroup } from '../../requests/responses/researchGroup' +import type { ResearchGroupFormValues } from '../../pages/ResearchGroupAdminPage/components/CreateResearchGroupModal' +import type { IResearchGroup } from '../../requests/responses/researchGroup' interface IResearchGroupFormProps { initialResearchGroup?: Partial @@ -35,7 +35,7 @@ const ResearchGroupForm = ({ const initialValues = getInitialValues(initialFormValues) // Discard only makes sense in the edit flow — on create there's nothing // meaningful to revert to. - const isEditing = !!initialFormValues?.id || !!initialFormValues?.name + const isEditing = Boolean(initialFormValues?.id) || Boolean(initialFormValues?.name) const form = useForm({ initialValues, diff --git a/client/src/components/ThesesFilters/ThesesFilters.tsx b/client/src/components/ThesesFilters/ThesesFilters.tsx index 3aed9c317..4ba086726 100644 --- a/client/src/components/ThesesFilters/ThesesFilters.tsx +++ b/client/src/components/ThesesFilters/ThesesFilters.tsx @@ -69,7 +69,7 @@ const ThesesFilters = () => { onChange={(x) => setFilters((prev) => ({ ...prev, - states: x as ThesisState[], + states: x, })) } /> diff --git a/client/src/components/ThesesGanttChart/ThesesGanttChart.tsx b/client/src/components/ThesesGanttChart/ThesesGanttChart.tsx index 4a5dc679f..a489736d7 100644 --- a/client/src/components/ThesesGanttChart/ThesesGanttChart.tsx +++ b/client/src/components/ThesesGanttChart/ThesesGanttChart.tsx @@ -12,7 +12,7 @@ import { arrayUnique } from '../../utils/array' import AvatarUserList from '../AvatarUserList/AvatarUserList' import AvatarUser from '../AvatarUser/AvatarUser' import LabeledItem from '../LabeledItem/LabeledItem' -import { IGanttChartDataElement } from '../GanttChart/context' +import type { IGanttChartDataElement } from '../GanttChart/context' const ThesesGanttChart = () => { const { theses, page, setPage } = useThesesContext() @@ -140,8 +140,8 @@ const ThesesGanttChart = () => { ]) : [] - const hasKeywordsColumn = !!(theses?.content ?? []).some( - (thesis) => !!(thesis.keywords ?? []).length, + const hasKeywordsColumn = Boolean( + (theses?.content ?? []).some((thesis) => Boolean((thesis.keywords ?? []).length)), ) return ( @@ -225,7 +225,7 @@ const ThesesGanttChart = () => { )} setOpenedThesisId(undefined)} thesisId={openedThesisId} /> diff --git a/client/src/components/ThesesTable/ThesesTable.tsx b/client/src/components/ThesesTable/ThesesTable.tsx index 4cef16ac0..690100078 100644 --- a/client/src/components/ThesesTable/ThesesTable.tsx +++ b/client/src/components/ThesesTable/ThesesTable.tsx @@ -1,10 +1,11 @@ -import { DataTable, DataTableColumn } from 'mantine-datatable' +import type { DataTableColumn } from 'mantine-datatable' +import { DataTable } from 'mantine-datatable' import { formatDate, formatThesisType } from '../../utils/format' import React from 'react' import { useThesesContext } from '../../providers/ThesesProvider/hooks' -import { IThesesSort } from '../../providers/ThesesProvider/context' +import type { IThesesSort } from '../../providers/ThesesProvider/context' import { useNavigate } from 'react-router' -import { IThesisOverview } from '../../requests/responses/thesis' +import type { IThesisOverview } from '../../requests/responses/thesis' import ThesisStateBadge from '../ThesisStateBadge/ThesisStateBadge' import { Center, Text, Tooltip } from '@mantine/core' import AvatarUserList from '../AvatarUserList/AvatarUserList' diff --git a/client/src/components/ThesisCommentsForm/ThesisCommentsForm.tsx b/client/src/components/ThesisCommentsForm/ThesisCommentsForm.tsx index bc85e4704..1ae27659c 100644 --- a/client/src/components/ThesisCommentsForm/ThesisCommentsForm.tsx +++ b/client/src/components/ThesisCommentsForm/ThesisCommentsForm.tsx @@ -59,7 +59,7 @@ const ThesisCommentsForm = () => { variant='subtle' color='gray' p={5} - disabled={!!file} + disabled={Boolean(file)} > { {comments && (comments.content ?? []).map((comment, idx) => ( - <> + {idx < (comments.content ?? []).length - 1 && } - + ))} {comments && comments.totalPages > 1 && ( diff --git a/client/src/components/ThesisCommentsList/components/ThesisCommentElement.tsx b/client/src/components/ThesisCommentsList/components/ThesisCommentElement.tsx index 3910068f1..6b3ad52f5 100644 --- a/client/src/components/ThesisCommentsList/components/ThesisCommentElement.tsx +++ b/client/src/components/ThesisCommentsList/components/ThesisCommentElement.tsx @@ -1,5 +1,5 @@ import { Group, Stack, Text } from '@mantine/core' -import { IThesisComment } from '../../../requests/responses/thesis' +import type { IThesisComment } from '../../../requests/responses/thesis' import { CustomAvatar } from '../../CustomAvatar/CustomAvatar' import { formatDate } from '../../../utils/format' import FileElement from '../../FileElement/FileElement' diff --git a/client/src/components/ThesisData/ThesisData.tsx b/client/src/components/ThesisData/ThesisData.tsx index 392cba7cb..0aaa7c0c1 100644 --- a/client/src/components/ThesisData/ThesisData.tsx +++ b/client/src/components/ThesisData/ThesisData.tsx @@ -1,4 +1,5 @@ -import { IPublishedThesis, isThesis, IThesis } from '../../requests/responses/thesis' +import type { IPublishedThesis, IThesis } from '../../requests/responses/thesis' +import { isThesis } from '../../requests/responses/thesis' import { Divider, Grid, Stack, Title } from '@mantine/core' import LabeledItem from '../LabeledItem/LabeledItem' import { formatDate, formatThesisType, pluralize } from '../../utils/format' diff --git a/client/src/components/ThesisStateBadge/ThesisStateBadge.tsx b/client/src/components/ThesisStateBadge/ThesisStateBadge.tsx index 2b3b84a29..68a9a6faa 100644 --- a/client/src/components/ThesisStateBadge/ThesisStateBadge.tsx +++ b/client/src/components/ThesisStateBadge/ThesisStateBadge.tsx @@ -2,7 +2,7 @@ import { ThesisStateColor } from '../../config/colors' import { formatThesisState } from '../../utils/format' import { Badge } from '@mantine/core' import React from 'react' -import { ThesisState } from '../../requests/responses/thesis' +import type { ThesisState } from '../../requests/responses/thesis' interface IThesisStateBadgeProps { state: ThesisState diff --git a/client/src/components/TopicAccordionItem/TopicAccordionItem.tsx b/client/src/components/TopicAccordionItem/TopicAccordionItem.tsx index a089764ac..4fc24cf3f 100644 --- a/client/src/components/TopicAccordionItem/TopicAccordionItem.tsx +++ b/client/src/components/TopicAccordionItem/TopicAccordionItem.tsx @@ -1,7 +1,8 @@ import { Accordion, Badge, Group, Text } from '@mantine/core' import TopicData from '../TopicData/TopicData' -import React, { PropsWithChildren } from 'react' -import { ITopic } from '../../requests/responses/topic' +import type { PropsWithChildren } from 'react' +import React from 'react' +import type { ITopic } from '../../requests/responses/topic' interface ITopicAccordionItemProps { topic: ITopic diff --git a/client/src/components/TopicData/TopicData.tsx b/client/src/components/TopicData/TopicData.tsx index 9ec820d91..2ccd24ca1 100644 --- a/client/src/components/TopicData/TopicData.tsx +++ b/client/src/components/TopicData/TopicData.tsx @@ -1,4 +1,4 @@ -import { ITopic } from '../../requests/responses/topic' +import type { ITopic } from '../../requests/responses/topic' import { Grid, Stack, Text } from '@mantine/core' import LabeledItem from '../LabeledItem/LabeledItem' import { formatDate, formatThesisType, pluralize } from '../../utils/format' diff --git a/client/src/components/TopicSearchFilters/TopicSearchFilters.tsx b/client/src/components/TopicSearchFilters/TopicSearchFilters.tsx index b90c85653..7f42007f1 100644 --- a/client/src/components/TopicSearchFilters/TopicSearchFilters.tsx +++ b/client/src/components/TopicSearchFilters/TopicSearchFilters.tsx @@ -11,12 +11,13 @@ import { Text, } from '@mantine/core' import { FadersHorizontalIcon, MagnifyingGlassIcon } from '@phosphor-icons/react' -import { JSX, useEffect, useState, Dispatch, SetStateAction } from 'react' +import type { JSX, Dispatch, SetStateAction } from 'react' +import { useEffect, useState } from 'react' import { useParams } from 'react-router' import { useIsSmallerBreakpoint } from '../../hooks/theme' import DropDownMultiSelect from '../DropDownMultiSelect/DropDownMultiSelect' import { GLOBAL_CONFIG } from '../../config/global' -import { ILightResearchGroup } from '../../requests/responses/researchGroup' +import type { ILightResearchGroup } from '../../requests/responses/researchGroup' import ThesisTypeBadge from '../../pages/LandingPage/components/ThesisTypBadge/ThesisTypBadge' interface ITopicSearchFiltersProps { diff --git a/client/src/components/TopicsFilters/TopicsFilters.tsx b/client/src/components/TopicsFilters/TopicsFilters.tsx index 4396c2aca..bf5e9d612 100644 --- a/client/src/components/TopicsFilters/TopicsFilters.tsx +++ b/client/src/components/TopicsFilters/TopicsFilters.tsx @@ -41,7 +41,7 @@ const TopicsFilters = (props: ITopicsFiltersProps) => {
{ setFilters((prev) => ({ types: [...(prev.types || []), key].filter( diff --git a/client/src/components/TopicsTable/TopicsTable.tsx b/client/src/components/TopicsTable/TopicsTable.tsx index dace4f6a0..39e748650 100644 --- a/client/src/components/TopicsTable/TopicsTable.tsx +++ b/client/src/components/TopicsTable/TopicsTable.tsx @@ -1,7 +1,9 @@ -import { DataTable, DataTableColumn } from 'mantine-datatable' +import type { DataTableColumn } from 'mantine-datatable' +import { DataTable } from 'mantine-datatable' import { formatDate } from '../../utils/format' import { useTopicsContext } from '../../providers/TopicsProvider/hooks' -import { ITopicOverview, TopicState } from '../../requests/responses/topic' +import type { ITopicOverview } from '../../requests/responses/topic' +import { TopicState } from '../../requests/responses/topic' import { Link, useNavigate } from 'react-router' import { Badge, Box, Center, Stack, Text } from '@mantine/core' import AvatarUserList from '../AvatarUserList/AvatarUserList' diff --git a/client/src/components/UploadArea/UploadArea.tsx b/client/src/components/UploadArea/UploadArea.tsx index 5f17dbe58..b0e53147d 100644 --- a/client/src/components/UploadArea/UploadArea.tsx +++ b/client/src/components/UploadArea/UploadArea.tsx @@ -12,7 +12,7 @@ import { import { ImageSquare, UploadSimple, X } from '@phosphor-icons/react' import { Dropzone, IMAGE_MIME_TYPE, PDF_MIME_TYPE } from '@mantine/dropzone' import { showSimpleError } from '../../utils/notification' -import { UploadFileType } from '../../config/types' +import type { UploadFileType } from '../../config/types' import FilePreview from '../FilePreview/FilePreview' interface IUploadAreaProps { diff --git a/client/src/components/UploadFileButton/UploadFileButton.tsx b/client/src/components/UploadFileButton/UploadFileButton.tsx index ba529685f..92af0962f 100644 --- a/client/src/components/UploadFileButton/UploadFileButton.tsx +++ b/client/src/components/UploadFileButton/UploadFileButton.tsx @@ -1,5 +1,6 @@ -import { UploadFileType } from '../../config/types' -import { PropsWithChildren, useEffect, useState } from 'react' +import type { UploadFileType } from '../../config/types' +import type { PropsWithChildren } from 'react' +import { useEffect, useState } from 'react' import { Button, Modal, Stack, type ButtonProps } from '@mantine/core' import UploadArea from '../UploadArea/UploadArea' diff --git a/client/src/components/UserCard/UserCard.tsx b/client/src/components/UserCard/UserCard.tsx index c4a6240ce..fb981d15e 100644 --- a/client/src/components/UserCard/UserCard.tsx +++ b/client/src/components/UserCard/UserCard.tsx @@ -1,5 +1,5 @@ import { Group, Paper, Stack, Title, Text } from '@mantine/core' -import { ILightUser } from '../../requests/responses/user' +import type { ILightUser } from '../../requests/responses/user' import { CustomAvatar } from '../CustomAvatar/CustomAvatar' import { formateStudyProgram, formatThesisType } from '../../utils/format' diff --git a/client/src/components/UserInformationForm/UserInformationForm.tsx b/client/src/components/UserInformationForm/UserInformationForm.tsx index 959ed7826..af116ee1f 100644 --- a/client/src/components/UserInformationForm/UserInformationForm.tsx +++ b/client/src/components/UserInformationForm/UserInformationForm.tsx @@ -1,5 +1,5 @@ import { isEmail, isNotEmpty, useForm } from '@mantine/form' -import { IUpdateUserInformationPayload } from '../../requests/payloads/user' +import type { IUpdateUserInformationPayload } from '../../requests/payloads/user' import { Anchor, Button, diff --git a/client/src/components/UserInformationForm/components/AvatarInput/AvatarInput.tsx b/client/src/components/UserInformationForm/components/AvatarInput/AvatarInput.tsx index feb0f261a..e039483fd 100644 --- a/client/src/components/UserInformationForm/components/AvatarInput/AvatarInput.tsx +++ b/client/src/components/UserInformationForm/components/AvatarInput/AvatarInput.tsx @@ -17,7 +17,7 @@ import { Dropzone, IMAGE_MIME_TYPE } from '@mantine/dropzone' import { useMemo, useRef, useState } from 'react' import { doRequest } from '../../../../requests/request' import { showSimpleError } from '../../../../utils/notification' -import { IUser } from '../../../../requests/responses/user' +import type { IUser } from '../../../../requests/responses/user' const IMPORT_TOOLTIP = 'Imports your profile picture from Gravatar (gravatar.com), a US-based service.' + @@ -119,7 +119,7 @@ const AvatarInput = (props: IAvatarInputProps) => { )} - setFile(undefined)}> + setFile(undefined)}> {file && (
diff --git a/client/src/components/UserInformationRow/UserInformationRow.tsx b/client/src/components/UserInformationRow/UserInformationRow.tsx index e7c5bfe23..4fc8c88b1 100644 --- a/client/src/components/UserInformationRow/UserInformationRow.tsx +++ b/client/src/components/UserInformationRow/UserInformationRow.tsx @@ -1,5 +1,5 @@ import { Badge, Flex, Group, Stack, Text } from '@mantine/core' -import { ILightUser } from '../../requests/responses/user' +import type { ILightUser } from '../../requests/responses/user' import { CustomAvatar } from '../CustomAvatar/CustomAvatar' type IUserInformationRowProps = { diff --git a/client/src/components/UserMultiSelect/UserMultiSelect.tsx b/client/src/components/UserMultiSelect/UserMultiSelect.tsx index 666c79c4e..9c5fa4ad8 100644 --- a/client/src/components/UserMultiSelect/UserMultiSelect.tsx +++ b/client/src/components/UserMultiSelect/UserMultiSelect.tsx @@ -1,8 +1,8 @@ import { MultiSelect } from '@mantine/core' import { useEffect, useState } from 'react' import { doRequest } from '../../requests/request' -import { PaginationResponse } from '../../requests/responses/pagination' -import { ILightUser } from '../../requests/responses/user' +import type { PaginationResponse } from '../../requests/responses/pagination' +import type { ILightUser } from '../../requests/responses/user' import { useDebouncedValue } from '@mantine/hooks' import type { GetInputPropsReturnType } from '@mantine/form' import { formatUser } from '../../utils/format' diff --git a/client/src/config/global.ts b/client/src/config/global.ts index 12ceb7915..0f6f86246 100644 --- a/client/src/config/global.ts +++ b/client/src/config/global.ts @@ -1,4 +1,4 @@ -import { Environment, IGlobalConfig } from './types' +import type { Environment, IGlobalConfig } from './types' const parseEnvironment = (value: string | undefined): Environment | undefined => { if (!value) { diff --git a/client/src/hooks/fetcher.ts b/client/src/hooks/fetcher.ts index b20068d16..3a1d530fb 100644 --- a/client/src/hooks/fetcher.ts +++ b/client/src/hooks/fetcher.ts @@ -1,10 +1,10 @@ -import { IThesis } from '../requests/responses/thesis' +import type { IThesis } from '../requests/responses/thesis' import { useEffect, useState } from 'react' import { doRequest } from '../requests/request' import { showSimpleError } from '../utils/notification' import { getApiResponseErrorMessage } from '../requests/handler' -import { ITopic, ITopicOverview } from '../requests/responses/topic' -import { PaginationResponse } from '../requests/responses/pagination' +import type { ITopic, ITopicOverview } from '../requests/responses/topic' +import type { PaginationResponse } from '../requests/responses/pagination' export function useThesis(thesisId: string | undefined) { const [thesis, setThesis] = useState() diff --git a/client/src/hooks/local-storage.ts b/client/src/hooks/local-storage.ts index 11b77582b..1a380302f 100644 --- a/client/src/hooks/local-storage.ts +++ b/client/src/hooks/local-storage.ts @@ -1,4 +1,5 @@ -import { Dispatch, useCallback, useEffect, useMemo, useState } from 'react' +import type { Dispatch } from 'react' +import { useCallback, useEffect, useMemo, useState } from 'react' interface ILocalStorageOptions { usingJson: boolean diff --git a/client/src/hooks/notification.ts b/client/src/hooks/notification.ts index 1770821e2..174caaeca 100644 --- a/client/src/hooks/notification.ts +++ b/client/src/hooks/notification.ts @@ -1,4 +1,5 @@ -import { Dispatch, SetStateAction, useState } from 'react' +import type { Dispatch, SetStateAction } from 'react' +import { useState } from 'react' import { doRequest } from '../requests/request' import { showSimpleError } from '../utils/notification' import { getApiResponseErrorMessage } from '../requests/handler' diff --git a/client/src/pages/AdminPage/AdminPage.tsx b/client/src/pages/AdminPage/AdminPage.tsx index a843efd9c..a28bf5d65 100644 --- a/client/src/pages/AdminPage/AdminPage.tsx +++ b/client/src/pages/AdminPage/AdminPage.tsx @@ -15,7 +15,7 @@ import { Warning } from '@phosphor-icons/react' import { doRequest } from '../../requests/request' import { showSimpleError, showSimpleSuccess } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' -import { IUser } from '../../requests/responses/user' +import type { IUser } from '../../requests/responses/user' interface IDataRetentionResult { deletedApplications: number diff --git a/client/src/pages/BrowseThesesPage/components/CreateThesisModal/CreateThesisModal.tsx b/client/src/pages/BrowseThesesPage/components/CreateThesisModal/CreateThesisModal.tsx index 49c226ad5..872a56e7a 100644 --- a/client/src/pages/BrowseThesesPage/components/CreateThesisModal/CreateThesisModal.tsx +++ b/client/src/pages/BrowseThesesPage/components/CreateThesisModal/CreateThesisModal.tsx @@ -5,15 +5,15 @@ import React, { useEffect, useState } from 'react' import { UserMultiSelect } from '../../../../components/UserMultiSelect/UserMultiSelect' import { useNavigate } from 'react-router' import { doRequest } from '../../../../requests/request' -import { IThesis } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' import { isNotEmptyUserList } from '../../../../utils/validation' import { showSimpleError } from '../../../../utils/notification' import { getApiResponseErrorMessage } from '../../../../requests/handler' import { formatThesisType, getDefaultLanguage } from '../../../../utils/format' import LanguageSelect from '../../../../components/LanguageSelect/LanguageSelect' -import { PaginationResponse } from '../../../../requests/responses/pagination' -import { ILightResearchGroup } from '../../../../requests/responses/researchGroup' -import { ILightUser } from '../../../../requests/responses/user' +import type { PaginationResponse } from '../../../../requests/responses/pagination' +import type { ILightResearchGroup } from '../../../../requests/responses/researchGroup' +import type { ILightUser } from '../../../../requests/responses/user' import { useHasGroupAccess } from '../../../../hooks/authentication' interface ICreateThesisModalProps { diff --git a/client/src/pages/DashboardPage/DashboardPage.tsx b/client/src/pages/DashboardPage/DashboardPage.tsx index f670e53e4..ff94938d7 100644 --- a/client/src/pages/DashboardPage/DashboardPage.tsx +++ b/client/src/pages/DashboardPage/DashboardPage.tsx @@ -5,7 +5,8 @@ import ThesesTable from '../../components/ThesesTable/ThesesTable' import ApplicationsProvider from '../../providers/ApplicationsProvider/ApplicationsProvider' import ThesesProvider from '../../providers/ThesesProvider/ThesesProvider' import { Button, Center, Group, Stack, Title } from '@mantine/core' -import { ApplicationState, IApplication } from '../../requests/responses/application' +import type { IApplication } from '../../requests/responses/application' +import { ApplicationState } from '../../requests/responses/application' import ThesesGanttChart from '../../components/ThesesGanttChart/ThesesGanttChart' import { useManagementAccess } from '../../hooks/authentication' import { Link } from 'react-router' diff --git a/client/src/pages/DashboardPage/components/MyTasksSection/MyTasksSection.tsx b/client/src/pages/DashboardPage/components/MyTasksSection/MyTasksSection.tsx index 7db1fda7a..24621778f 100644 --- a/client/src/pages/DashboardPage/components/MyTasksSection/MyTasksSection.tsx +++ b/client/src/pages/DashboardPage/components/MyTasksSection/MyTasksSection.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import { doRequest } from '../../../../requests/request' import { showSimpleError } from '../../../../utils/notification' import { getApiResponseErrorMessage } from '../../../../requests/handler' -import { ITask } from '../../../../requests/responses/dashboard' +import type { ITask } from '../../../../requests/responses/dashboard' import { DataTable } from 'mantine-datatable' import { useNavigate } from 'react-router' import { Link as LinkIcon } from '@phosphor-icons/react' diff --git a/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx b/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx index b3608877b..b29a2c5e8 100644 --- a/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx +++ b/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx @@ -12,7 +12,7 @@ import { Paper, } from '@mantine/core' import { useIsSmallerBreakpoint } from '../../hooks/theme' -import { IInterviewSlot } from '../../requests/responses/interview' +import type { IInterviewSlot } from '../../requests/responses/interview' import { useEffect, useState } from 'react' import SummaryCard from './components/SummaryCard' import { @@ -29,12 +29,54 @@ import { useParams } from 'react-router' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' import { useAuthenticationContext, useUser } from '../../hooks/authentication' -import { ITopic } from '../../requests/responses/topic' +import type { ITopic } from '../../requests/responses/topic' import AvatarUserList from '../../components/AvatarUserList/AvatarUserList' import InterviewProcessProvider from '../../providers/InterviewProcessProvider/InterviewProcessProvider' import SelectSlotCarousel from './components/SelectSlotCarousel' import CancelSlotConfirmationModal from '../InterviewTopicOverviewPage/components/CancelSlotConfirmationModal' +interface ISlotInformationProps { + slot: IInterviewSlot + title?: string +} + +const SlotInformation = ({ slot, title }: ISlotInformationProps) => ( + + {slot.startDate.toLocaleDateString()} + + ), + icon: , + }, + { + title: 'Time', + content: ( + + {`${slot.startDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}` + + ` - ${slot.endDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}` + + `, ${Math.round((slot.endDate.getTime() - slot.startDate.getTime()) / 60000)} min`} + + ), + icon: , + }, + { + title: 'Location', + content: ( + + {slot.location || slot.streamUrl || 'Not specified'} + + ), + icon: , + }, + ]} + /> +) + const InterviewBookingPage = () => { const { processId } = useParams<{ processId: string }>() @@ -199,43 +241,6 @@ const InterviewBookingPage = () => { /> ) : null - const SlotInformation = (slot: IInterviewSlot, title?: string) => ( - - {slot.startDate.toLocaleDateString()} - - ), - icon: , - }, - { - title: 'Time', - content: ( - - {`${slot.startDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}` + - ` - ${slot.endDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}` + - `, ${Math.round((slot.endDate.getTime() - slot.startDate.getTime()) / 60000)} min`} - - ), - icon: , - }, - { - title: 'Location', - content: ( - - {slot.location || slot.streamUrl || 'Not specified'} - - ), - icon: , - }, - ]} - > - ) - if (pageLoading) { return (
@@ -286,7 +291,7 @@ const InterviewBookingPage = () => { {TopicInformation} - {SlotInformation(myBooking)} + @@ -350,7 +355,7 @@ const InterviewBookingPage = () => { > - {selectedSlot && SlotInformation(selectedSlot)} + {selectedSlot && } {TopicInformation} diff --git a/client/src/pages/InterviewBookingPage/components/SelectSlotCarousel.tsx b/client/src/pages/InterviewBookingPage/components/SelectSlotCarousel.tsx index 652ae8e16..241671ac0 100644 --- a/client/src/pages/InterviewBookingPage/components/SelectSlotCarousel.tsx +++ b/client/src/pages/InterviewBookingPage/components/SelectSlotCarousel.tsx @@ -5,7 +5,7 @@ import { useIsSmallerBreakpoint } from '../../../hooks/theme' import { useInterviewProcessContext } from '../../../providers/InterviewProcessProvider/hooks' import SlotItem from '../../InterviewTopicOverviewPage/components/SlotItem' import { useState } from 'react' -import { IInterviewSlot } from '../../../requests/responses/interview' +import type { IInterviewSlot } from '../../../requests/responses/interview' interface ISelectSlotCarouselProps { selectedSlot: IInterviewSlot | null diff --git a/client/src/pages/InterviewOverviewPage/InterviewOverviewPage.tsx b/client/src/pages/InterviewOverviewPage/InterviewOverviewPage.tsx index 3a067c7bf..feaf44112 100644 --- a/client/src/pages/InterviewOverviewPage/InterviewOverviewPage.tsx +++ b/client/src/pages/InterviewOverviewPage/InterviewOverviewPage.tsx @@ -12,7 +12,7 @@ import { Pagination, } from '@mantine/core' import { ChatCircleSlashIcon, PlusIcon } from '@phosphor-icons/react' -import { IInterviewProcess, IUpcomingInterview } from '../../requests/responses/interview' +import type { IInterviewProcess, IUpcomingInterview } from '../../requests/responses/interview' import InterviewProcessCard from './components/InterviewProcessCard' import { useIsSmallerBreakpoint } from '../../hooks/theme' import UpcomingInterviewCard from './components/UpcomingInterviewCard' @@ -22,7 +22,7 @@ import { useEffect, useState } from 'react' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' import { doRequest } from '../../requests/request' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { PaginationResponse } from '../../requests/responses/pagination' const InterviewOverviewPage = () => { const [upcomingInterviews, setUpcomingInterviews] = useState([]) diff --git a/client/src/pages/InterviewOverviewPage/components/CreateInterviewProcess.tsx b/client/src/pages/InterviewOverviewPage/components/CreateInterviewProcess.tsx index da6f74746..ce3b3a1fb 100644 --- a/client/src/pages/InterviewOverviewPage/components/CreateInterviewProcess.tsx +++ b/client/src/pages/InterviewOverviewPage/components/CreateInterviewProcess.tsx @@ -15,8 +15,8 @@ import { useMantineColorScheme, } from '@mantine/core' import { useEffect, useState } from 'react' -import { PaginationResponse } from '../../../requests/responses/pagination' -import { +import type { PaginationResponse } from '../../../requests/responses/pagination' +import type { IApplicationInterviewProcess, IInterviewProcess, ITopicInterviewProcess, diff --git a/client/src/pages/InterviewOverviewPage/components/InterviewProcessCard.tsx b/client/src/pages/InterviewOverviewPage/components/InterviewProcessCard.tsx index 8e6876fb7..545537413 100644 --- a/client/src/pages/InterviewOverviewPage/components/InterviewProcessCard.tsx +++ b/client/src/pages/InterviewOverviewPage/components/InterviewProcessCard.tsx @@ -11,7 +11,7 @@ import { Badge, useMantineColorScheme, } from '@mantine/core' -import { IInterviewProcess, InterviewState } from '../../../requests/responses/interview' +import type { IInterviewProcess, InterviewState } from '../../../requests/responses/interview' import { useHover } from '@mantine/hooks' import { getInterviewStateColor } from '../../../utils/format' @@ -80,7 +80,10 @@ const InterviewProcessCard = ({ interviewProcess, onClick }: IInterviewProcessCa @@ -105,7 +108,10 @@ const InterviewProcessCard = ({ interviewProcess, onClick }: IInterviewProcessCa ) })} diff --git a/client/src/pages/InterviewOverviewPage/components/SelectApplicantsList.tsx b/client/src/pages/InterviewOverviewPage/components/SelectApplicantsList.tsx index 86d314d19..bb73a6faf 100644 --- a/client/src/pages/InterviewOverviewPage/components/SelectApplicantsList.tsx +++ b/client/src/pages/InterviewOverviewPage/components/SelectApplicantsList.tsx @@ -10,7 +10,7 @@ import { } from '@mantine/core' import { CheckCircleIcon, CircleIcon } from '@phosphor-icons/react' import { ApplicationState } from '../../../requests/responses/application' -import { IApplicationInterviewProcess } from '../../../requests/responses/interview' +import type { IApplicationInterviewProcess } from '../../../requests/responses/interview' interface ISelectApplicantsListProps { possibleInterviewApplicants: IApplicationInterviewProcess[] diff --git a/client/src/pages/InterviewOverviewPage/components/SelectTopicInterviewProcessItem.tsx b/client/src/pages/InterviewOverviewPage/components/SelectTopicInterviewProcessItem.tsx index 65474223e..1ec26bff7 100644 --- a/client/src/pages/InterviewOverviewPage/components/SelectTopicInterviewProcessItem.tsx +++ b/client/src/pages/InterviewOverviewPage/components/SelectTopicInterviewProcessItem.tsx @@ -1,5 +1,5 @@ import { Badge, Divider, Group, Stack, Text, useMantineColorScheme } from '@mantine/core' -import { ITopicInterviewProcess } from '../../../requests/responses/interview' +import type { ITopicInterviewProcess } from '../../../requests/responses/interview' import { useHover } from '@mantine/hooks' interface ISelectTopicInterviewProcessItemProps { diff --git a/client/src/pages/InterviewOverviewPage/components/UpcomingInterviewCard.tsx b/client/src/pages/InterviewOverviewPage/components/UpcomingInterviewCard.tsx index a146f7534..396134917 100644 --- a/client/src/pages/InterviewOverviewPage/components/UpcomingInterviewCard.tsx +++ b/client/src/pages/InterviewOverviewPage/components/UpcomingInterviewCard.tsx @@ -1,6 +1,6 @@ import { Card, Group, Stack, Title, Text, Divider } from '@mantine/core' import { useHover } from '@mantine/hooks' -import { IUpcomingInterview } from '../../../requests/responses/interview' +import type { IUpcomingInterview } from '../../../requests/responses/interview' import { CustomAvatar } from '../../../components/CustomAvatar/CustomAvatar' import InterviewSlotInformation from '../../../components/InterviewSlotInformation/InterviewSlotInformation' diff --git a/client/src/pages/InterviewTopicOverviewPage/InterviewTopicOverviewPage.tsx b/client/src/pages/InterviewTopicOverviewPage/InterviewTopicOverviewPage.tsx index 04c1656e3..edb76ac44 100644 --- a/client/src/pages/InterviewTopicOverviewPage/InterviewTopicOverviewPage.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/InterviewTopicOverviewPage.tsx @@ -5,7 +5,7 @@ import InterviewProcessProvider from '../../providers/InterviewProcessProvider/I import { useParams } from 'react-router' import { doRequest } from '../../requests/request' import { useEffect, useState } from 'react' -import { IInterviewProcess } from '../../requests/responses/interview' +import type { IInterviewProcess } from '../../requests/responses/interview' const InterviewTopicOverviewPage = () => { const { processId } = useParams<{ processId: string }>() diff --git a/client/src/pages/InterviewTopicOverviewPage/components/AcceptApplicantModal.tsx b/client/src/pages/InterviewTopicOverviewPage/components/AcceptApplicantModal.tsx index 14b283520..232410f18 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/AcceptApplicantModal.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/AcceptApplicantModal.tsx @@ -1,7 +1,7 @@ import { Loader, Modal, Title, Group, Button } from '@mantine/core' -import { IIntervieweeLightWithNextSlot } from '../../../requests/responses/interview' +import type { IIntervieweeLightWithNextSlot } from '../../../requests/responses/interview' import ApplicationReviewForm from '../../../components/ApplicationReviewForm/ApplicationReviewForm' -import { IApplication } from '../../../requests/responses/application' +import type { IApplication } from '../../../requests/responses/application' import { useEffect, useState } from 'react' import { useApplicationsContext } from '../../../providers/ApplicationsProvider/hooks' import ApplicationRejectButton from '../../../components/ApplicationRejectButton/ApplicationRejectButton' diff --git a/client/src/pages/InterviewTopicOverviewPage/components/AddIntervieweesModal.tsx b/client/src/pages/InterviewTopicOverviewPage/components/AddIntervieweesModal.tsx index b16a07379..5072c287a 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/AddIntervieweesModal.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/AddIntervieweesModal.tsx @@ -11,10 +11,10 @@ import { Stack, } from '@mantine/core' import { useEffect, useState } from 'react' -import { IApplicationInterviewProcess } from '../../../requests/responses/interview' +import type { IApplicationInterviewProcess } from '../../../requests/responses/interview' import SelectApplicantsList from '../../InterviewOverviewPage/components/SelectApplicantsList' import { doRequest } from '../../../requests/request' -import { PaginationResponse } from '../../../requests/responses/pagination' +import type { PaginationResponse } from '../../../requests/responses/pagination' import { showSimpleError } from '../../../utils/notification' import { getApiResponseErrorMessage } from '../../../requests/handler' import { useParams } from 'react-router' diff --git a/client/src/pages/InterviewTopicOverviewPage/components/AddSlotsModal.tsx b/client/src/pages/InterviewTopicOverviewPage/components/AddSlotsModal.tsx index 7ae6adb4a..f2e42e493 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/AddSlotsModal.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/AddSlotsModal.tsx @@ -20,7 +20,7 @@ import dayjs from 'dayjs' import { CalendarBlankIcon } from '@phosphor-icons/react' import CollapsibleDateCard from './CollapsibleDateCard' import { useIsSmallerBreakpoint } from '../../../hooks/theme' -import { IInterviewSlot } from '../../../requests/responses/interview' +import type { IInterviewSlot } from '../../../requests/responses/interview' import { doRequest } from '../../../requests/request' import { useParams } from 'react-router' import { showSimpleError, showSimpleSuccess } from '../../../utils/notification' diff --git a/client/src/pages/InterviewTopicOverviewPage/components/AssignIntervieweeToSlotModal.tsx b/client/src/pages/InterviewTopicOverviewPage/components/AssignIntervieweeToSlotModal.tsx index 2996a5f61..bc3e7b378 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/AssignIntervieweeToSlotModal.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/AssignIntervieweeToSlotModal.tsx @@ -11,7 +11,7 @@ import { Title, Text, } from '@mantine/core' -import { +import type { IIntervieweeLightWithNextSlot, IInterviewSlot, } from '../../../requests/responses/interview' diff --git a/client/src/pages/InterviewTopicOverviewPage/components/CalendarCarousel.tsx b/client/src/pages/InterviewTopicOverviewPage/components/CalendarCarousel.tsx index 629191398..d47812ad5 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/CalendarCarousel.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/CalendarCarousel.tsx @@ -17,11 +17,11 @@ import { CheckIcon, } from '@mantine/core' import { CalendarDotsIcon, ClockUserIcon, CopyIcon, PlusIcon } from '@phosphor-icons/react' -import { IInterviewSlot } from '../../../requests/responses/interview' +import type { IInterviewSlot } from '../../../requests/responses/interview' import { DateHeaderItem } from './DateHeaderItem' import SlotItem from './SlotItem' import { useIsSmallerBreakpoint } from '../../../hooks/theme' -import { useEffect, useState } from 'react' +import { Fragment, useEffect, useState } from 'react' import AddSlotsModal from './AddSlotsModal' import { useInterviewProcessContext } from '../../../providers/InterviewProcessProvider/hooks' import { GLOBAL_CONFIG } from '../../../config/global' @@ -216,7 +216,7 @@ const CalendarCarousel = ({ disabled = false }: ICalendarCarouselProps) => { } return ( - <> + {chunks.map((chunk, chunkIndex) => ( @@ -268,7 +268,7 @@ const CalendarCarousel = ({ disabled = false }: ICalendarCarouselProps) => { ))} - + ) })} diff --git a/client/src/pages/InterviewTopicOverviewPage/components/CancelSlotConfirmationModal.tsx b/client/src/pages/InterviewTopicOverviewPage/components/CancelSlotConfirmationModal.tsx index 6541e2116..84fa1f73c 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/CancelSlotConfirmationModal.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/CancelSlotConfirmationModal.tsx @@ -1,6 +1,6 @@ import { Modal, Stack, Title, Text, Paper, Group, Button, Input } from '@mantine/core' import { useIsSmallerBreakpoint } from '../../../hooks/theme' -import { IInterviewSlot } from '../../../requests/responses/interview' +import type { IInterviewSlot } from '../../../requests/responses/interview' import { useInterviewProcessContext } from '../../../providers/InterviewProcessProvider/hooks' import SlotItem from './SlotItem' import AvatarUser from '../../../components/AvatarUser/AvatarUser' diff --git a/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx b/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx index 578c55d87..f36c65808 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx @@ -12,7 +12,7 @@ import { Title, } from '@mantine/core' import dayjs from 'dayjs' -import { IInterviewSlot } from '../../../requests/responses/interview' +import type { IInterviewSlot } from '../../../requests/responses/interview' import { useEffect, useState } from 'react' import { CardsIcon } from '@phosphor-icons/react' import { TimeInput } from '@mantine/dates' @@ -430,16 +430,13 @@ const CollapsibleDateCard = ({ //When it is single also set end time if (slotRange.type === 'single') { - newRanges[index].endTime = (() => { - const newEndTime = new Date(date) - const [endHours, endMinutes] = newTime.target.value - .split(':') - .map(Number) - newEndTime.setHours(endHours, endMinutes, 0, 0) - newEndTime.setMinutes(newEndTime.getMinutes() + duration) - - return newEndTime - })() + const newEndTime = new Date(date) + const [endHours, endMinutes] = newTime.target.value + .split(':') + .map(Number) + newEndTime.setHours(endHours, endMinutes, 0, 0) + newEndTime.setMinutes(newEndTime.getMinutes() + duration) + newRanges[index].endTime = newEndTime } if (newRanges[index].endTime && newRanges[index].startTime) { diff --git a/client/src/pages/InterviewTopicOverviewPage/components/IntervieweeCard.tsx b/client/src/pages/InterviewTopicOverviewPage/components/IntervieweeCard.tsx index b1ee6493c..3c6869b7f 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/IntervieweeCard.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/IntervieweeCard.tsx @@ -11,10 +11,8 @@ import { Button, Box, } from '@mantine/core' -import { - IIntervieweeLightWithNextSlot, - InterviewState, -} from '../../../requests/responses/interview' +import type { IIntervieweeLightWithNextSlot } from '../../../requests/responses/interview' +import { InterviewState } from '../../../requests/responses/interview' import { CustomAvatar } from '../../../components/CustomAvatar/CustomAvatar' import { createScoreLabel, @@ -111,7 +109,11 @@ const IntervieweeCard = ({ - + - {(() => { - const minutes = Math.round( - (slot.endDate.getTime() - slot.startDate.getTime()) / 60000, - ) - return `${minutes} min` - })()} + {`${Math.round((slot.endDate.getTime() - slot.startDate.getTime()) / 60000)} min`} )} diff --git a/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx b/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx index 54f94aeb4..3c18c5a03 100644 --- a/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx +++ b/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx @@ -1,5 +1,5 @@ import { Center, Divider, Flex, Group, Loader, ScrollArea, Stack, Title } from '@mantine/core' -import { IInterviewee } from '../../requests/responses/interview' +import type { IInterviewee } from '../../requests/responses/interview' import { useIsSmallerBreakpoint } from '../../hooks/theme' import ScoreCard from './components/ScoreCard' import { useEffect, useState } from 'react' diff --git a/client/src/pages/LandingPage/LandingPage.tsx b/client/src/pages/LandingPage/LandingPage.tsx index 582875b14..f30ca990b 100644 --- a/client/src/pages/LandingPage/LandingPage.tsx +++ b/client/src/pages/LandingPage/LandingPage.tsx @@ -11,7 +11,7 @@ import { useEffect, useMemo, useState } from 'react' import { useDebouncedValue } from '@mantine/hooks' import { GLOBAL_CONFIG } from '../../config/global' import TopicCardGrid from './components/TopicCardGrid/TopicCardGrid' -import { ILightResearchGroup } from '../../requests/responses/researchGroup' +import type { ILightResearchGroup } from '../../requests/responses/researchGroup' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' diff --git a/client/src/pages/LandingPage/components/LandingPageHeader/LandingPageHeader.tsx b/client/src/pages/LandingPage/components/LandingPageHeader/LandingPageHeader.tsx index e35296098..60d69978e 100644 --- a/client/src/pages/LandingPage/components/LandingPageHeader/LandingPageHeader.tsx +++ b/client/src/pages/LandingPage/components/LandingPageHeader/LandingPageHeader.tsx @@ -1,7 +1,7 @@ import { Card, Title, Flex, useComputedColorScheme } from '@mantine/core' import LogoCircle from './LogoCircle' import { useEffect, useState } from 'react' -import { IResearchGroup } from '../../../../requests/responses/researchGroup' +import type { IResearchGroup } from '../../../../requests/responses/researchGroup' import { doRequest } from '../../../../requests/request' import { showSimpleError } from '../../../../utils/notification' import { getApiResponseErrorMessage } from '../../../../requests/handler' diff --git a/client/src/pages/LandingPage/components/PublishedTheses/PublishedTheses.tsx b/client/src/pages/LandingPage/components/PublishedTheses/PublishedTheses.tsx index 8bb8068ab..74d5ca612 100644 --- a/client/src/pages/LandingPage/components/PublishedTheses/PublishedTheses.tsx +++ b/client/src/pages/LandingPage/components/PublishedTheses/PublishedTheses.tsx @@ -1,8 +1,8 @@ import { DataTable } from 'mantine-datatable' import { ActionIcon, Anchor, Center, Group, Modal, Stack, Text, Tooltip } from '@mantine/core' import React, { useEffect, useState } from 'react' -import { PaginationResponse } from '../../../../requests/responses/pagination' -import { IPublishedThesis } from '../../../../requests/responses/thesis' +import type { PaginationResponse } from '../../../../requests/responses/pagination' +import type { IPublishedThesis } from '../../../../requests/responses/thesis' import { doRequest } from '../../../../requests/request' import { showSimpleError } from '../../../../utils/notification' import { getApiResponseErrorMessage } from '../../../../requests/handler' @@ -178,7 +178,7 @@ const PublishedTheses = ({ search, representationType, filters, limit }: Publish {content} setOpenedThesis(undefined)} size='xl' > diff --git a/client/src/pages/LandingPage/components/TopicCardGrid/TopicCard/TopicCard.tsx b/client/src/pages/LandingPage/components/TopicCardGrid/TopicCard/TopicCard.tsx index 3e9940058..d2d6d9037 100644 --- a/client/src/pages/LandingPage/components/TopicCardGrid/TopicCard/TopicCard.tsx +++ b/client/src/pages/LandingPage/components/TopicCardGrid/TopicCard/TopicCard.tsx @@ -1,11 +1,12 @@ import { Card, Flex, Text, Group, Stack, Button, Tooltip, Anchor, Box } from '@mantine/core' -import { ITopicOverview } from '../../../../../requests/responses/topic' +import type { ITopicOverview } from '../../../../../requests/responses/topic' import { useHover, useMediaQuery } from '@mantine/hooks' import { DownloadSimple, Users } from '@phosphor-icons/react' import AvatarUserList from '../../../../../components/AvatarUserList/AvatarUserList' -import { IPublishedThesis } from '../../../../../requests/responses/thesis' -import { Dispatch, useEffect, useState } from 'react' -import { IMinimalUser } from '../../../../../requests/responses/user' +import type { IPublishedThesis } from '../../../../../requests/responses/thesis' +import type { Dispatch } from 'react' +import { useEffect, useState } from 'react' +import type { IMinimalUser } from '../../../../../requests/responses/user' import { Link } from 'react-router' import { GLOBAL_CONFIG } from '../../../../../config/global' import ThesisTypeBadge from '../../ThesisTypBadge/ThesisTypBadge' diff --git a/client/src/pages/LandingPage/components/TopicCardGrid/TopicCardGrid.tsx b/client/src/pages/LandingPage/components/TopicCardGrid/TopicCardGrid.tsx index ffb68efcb..c12b7d434 100644 --- a/client/src/pages/LandingPage/components/TopicCardGrid/TopicCardGrid.tsx +++ b/client/src/pages/LandingPage/components/TopicCardGrid/TopicCardGrid.tsx @@ -14,12 +14,13 @@ import { Title, } from '@mantine/core' import TopicCard from './TopicCard/TopicCard' -import { useTopicsContext } from '../../../../providers/TopicsProvider/hooks' +import { TopicsContext } from '../../../../providers/TopicsProvider/context' import { Database } from '@phosphor-icons/react' -import { Dispatch, useEffect, useState } from 'react' -import { ITopic, ITopicOverview } from '../../../../requests/responses/topic' -import { IPublishedThesis } from '../../../../requests/responses/thesis' -import { PaginationResponse } from '../../../../requests/responses/pagination' +import type { Dispatch } from 'react' +import { useContext, useEffect, useState } from 'react' +import type { ITopic, ITopicOverview } from '../../../../requests/responses/topic' +import type { IPublishedThesis } from '../../../../requests/responses/thesis' +import type { PaginationResponse } from '../../../../requests/responses/pagination' import CollapsibleTopicElement from '../../../ReplaceApplicationPage/components/SelectTopicStep/components/CollapsibleTopicElement' import { GLOBAL_CONFIG } from '../../../../config/global' @@ -46,7 +47,12 @@ const TopicCardGrid = ({ showSuggestedTopic = false, onApply, }: ITopicCardGridContentProps) => { - const { topics, page, setPage, limit, isLoading } = gridContent ?? useTopicsContext() + const contextData = useContext(TopicsContext) + const source = gridContent ?? contextData + if (!source) { + throw new Error('TopicCardGrid requires either a gridContent prop or a TopicsProvider ancestor') + } + const { topics, page, setPage, limit, isLoading } = source //Prevent flickering spinner for short loading times const [showSpinner, setShowSpinner] = useState(false) diff --git a/client/src/pages/ManageTopicsPage/ManageTopicsPage.tsx b/client/src/pages/ManageTopicsPage/ManageTopicsPage.tsx index 90748208e..fbc457253 100644 --- a/client/src/pages/ManageTopicsPage/ManageTopicsPage.tsx +++ b/client/src/pages/ManageTopicsPage/ManageTopicsPage.tsx @@ -26,7 +26,7 @@ const ManageTopicsPage = () => { setCreateTopicModal(false)} /> setEditingTopicId(undefined)} topicId={editingTopicId} /> diff --git a/client/src/pages/ManageTopicsPage/components/CloseTopicButton/CloseTopicButton.tsx b/client/src/pages/ManageTopicsPage/components/CloseTopicButton/CloseTopicButton.tsx index bc4ee65d6..fb4610e45 100644 --- a/client/src/pages/ManageTopicsPage/components/CloseTopicButton/CloseTopicButton.tsx +++ b/client/src/pages/ManageTopicsPage/components/CloseTopicButton/CloseTopicButton.tsx @@ -1,9 +1,5 @@ -import { - ITopic, - ITopicOverview, - TopicState, - toTopicOverview, -} from '../../../../requests/responses/topic' +import type { ITopic, ITopicOverview } from '../../../../requests/responses/topic' +import { TopicState, toTopicOverview } from '../../../../requests/responses/topic' import { X } from '@phosphor-icons/react' import React, { useEffect, useState } from 'react' import { useTopicsContext } from '../../../../providers/TopicsProvider/hooks' diff --git a/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx b/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx index db06b73ae..ad174c45c 100644 --- a/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx +++ b/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx @@ -10,7 +10,8 @@ import { Text, TextInput, } from '@mantine/core' -import { ITopic, TopicState, toTopicOverview } from '../../../../requests/responses/topic' +import type { ITopic } from '../../../../requests/responses/topic' +import { TopicState, toTopicOverview } from '../../../../requests/responses/topic' import { isNotEmpty, useForm } from '@mantine/form' import { isNotEmptyUserList } from '../../../../utils/validation' import { useEffect, useState } from 'react' @@ -23,9 +24,9 @@ import { getApiResponseErrorMessage } from '../../../../requests/handler' import { UserMultiSelect } from '../../../../components/UserMultiSelect/UserMultiSelect' import { useTopicsContext } from '../../../../providers/TopicsProvider/hooks' import { formatThesisType } from '../../../../utils/format' -import { PaginationResponse } from '../../../../requests/responses/pagination' -import { ILightResearchGroup } from '../../../../requests/responses/researchGroup' -import { ILightUser } from '../../../../requests/responses/user' +import type { PaginationResponse } from '../../../../requests/responses/pagination' +import type { ILightResearchGroup } from '../../../../requests/responses/researchGroup' +import type { ILightUser } from '../../../../requests/responses/user' import { useHasGroupAccess } from '../../../../hooks/authentication' import { DateInput } from '@mantine/dates' @@ -40,8 +41,8 @@ const ReplaceTopicModal = (props: ICreateTopicModalProps) => { const fetchedTopic = useTopic(opened ? topicId : undefined) const topic = fetchedTopic === false ? undefined : fetchedTopic || undefined - const fetchError = fetchedTopic === false && !!topicId - const isTopicLoading = !!topicId && opened && fetchedTopic === undefined + const fetchError = fetchedTopic === false && Boolean(topicId) + const isTopicLoading = Boolean(topicId) && opened && fetchedTopic === undefined const { addTopic, updateTopic } = useTopicsContext() const [researchGroups, setResearchGroups] = useState>() diff --git a/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx b/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx index 05a0af643..8469ad839 100644 --- a/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx +++ b/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx @@ -20,12 +20,12 @@ import { useIsSmallerBreakpoint, usePageTitle } from '../../hooks/theme' import { GLOBAL_CONFIG } from '../../config/global' import { CopyIcon, CheckIcon } from '@phosphor-icons/react' import { useEffect, useRef, useState } from 'react' -import { ILightResearchGroup } from '../../requests/responses/researchGroup' +import type { ILightResearchGroup } from '../../requests/responses/researchGroup' import { useAuthenticationContext, useUser } from '../../hooks/authentication' import { Calendar } from '@mantine/dates' import dayjs from 'dayjs' -import { PaginationResponse } from '../../requests/responses/pagination' -import { IPublishedPresentation, IThesisPresentation } from '../../requests/responses/thesis' +import type { PaginationResponse } from '../../requests/responses/pagination' +import type { IPublishedPresentation, IThesisPresentation } from '../../requests/responses/thesis' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' @@ -304,7 +304,7 @@ const PresentationOverviewPage = () => { - {presentations && presentations.size === 0 && ( + {presentations?.size === 0 && ( No Presentations Scheduled diff --git a/client/src/pages/PresentationPage/PresentationPage.tsx b/client/src/pages/PresentationPage/PresentationPage.tsx index 1b7f4f559..4527d50d5 100644 --- a/client/src/pages/PresentationPage/PresentationPage.tsx +++ b/client/src/pages/PresentationPage/PresentationPage.tsx @@ -1,6 +1,6 @@ import { Link, useParams } from 'react-router' import React, { useEffect, useState } from 'react' -import { IPublishedPresentation } from '../../requests/responses/thesis' +import type { IPublishedPresentation } from '../../requests/responses/thesis' import { doRequest } from '../../requests/request' import ThesisData from '../../components/ThesisData/ThesisData' import { showSimpleError } from '../../utils/notification' diff --git a/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx b/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx index b641fdf14..0e07c2e99 100644 --- a/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx +++ b/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx @@ -5,7 +5,7 @@ import { useEffect, useState } from 'react' import SelectTopicStep from './components/SelectTopicStep/SelectTopicStep' import StudentInformationStep from './components/StudentInformationStep/StudentInformationStep' import MotivationStep from './components/MotivationStep/MotivationStep' -import { IApplication } from '../../requests/responses/application' +import type { IApplication } from '../../requests/responses/application' import { doRequest } from '../../requests/request' import { usePageTitle } from '../../hooks/theme' diff --git a/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx b/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx index bf92ae443..df5b0015e 100644 --- a/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx +++ b/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx @@ -1,4 +1,4 @@ -import { ITopic } from '../../../../requests/responses/topic' +import type { ITopic } from '../../../../requests/responses/topic' import { isNotEmpty, useForm } from '@mantine/form' import { Accordion, Button, Select, Stack, TextInput } from '@mantine/core' import DocumentEditor from '../../../../components/DocumentEditor/DocumentEditor' @@ -9,11 +9,11 @@ import { getApiResponseErrorMessage } from '../../../../requests/handler' import { DateInput } from '@mantine/dates' import { getHtmlTextLength } from '../../../../utils/validation' import { GLOBAL_CONFIG } from '../../../../config/global' -import { IApplication } from '../../../../requests/responses/application' +import type { IApplication } from '../../../../requests/responses/application' import TopicAccordionItem from '../../../../components/TopicAccordionItem/TopicAccordionItem' import { formatThesisType } from '../../../../utils/format' -import { PaginationResponse } from '../../../../requests/responses/pagination' -import { ILightResearchGroup } from '../../../../requests/responses/researchGroup' +import type { PaginationResponse } from '../../../../requests/responses/pagination' +import type { ILightResearchGroup } from '../../../../requests/responses/researchGroup' interface IMotivationStepProps { topic: ITopic | undefined @@ -183,7 +183,7 @@ const MotivationStep = (props: IMotivationStepProps) => { label='Research Group' required nothingFoundMessage={!loading ? 'Nothing found...' : 'Loading...'} - disabled={!!mergedTopic} + disabled={Boolean(mergedTopic)} data={(researchGroups?.content ?? []).map((researchGroup: ILightResearchGroup) => ({ label: researchGroup.name, value: researchGroup.id, diff --git a/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/SelectTopicStep.tsx b/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/SelectTopicStep.tsx index f0a21787c..a2215b2e6 100644 --- a/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/SelectTopicStep.tsx +++ b/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/SelectTopicStep.tsx @@ -1,4 +1,4 @@ -import { ITopic } from '../../../../requests/responses/topic' +import type { ITopic } from '../../../../requests/responses/topic' import { Alert, Stack } from '@mantine/core' import { InfoIcon } from '@phosphor-icons/react' import React, { useEffect, useState } from 'react' @@ -9,7 +9,7 @@ import { useDebouncedValue } from '@mantine/hooks' import TopicsProvider from '../../../../providers/TopicsProvider/TopicsProvider' import TopicSearchFilters from '../../../../components/TopicSearchFilters/TopicSearchFilters' import { doRequest } from '../../../../requests/request' -import { ILightResearchGroup } from '../../../../requests/responses/researchGroup' +import type { ILightResearchGroup } from '../../../../requests/responses/researchGroup' import { showSimpleError } from '../../../../utils/notification' import { getApiResponseErrorMessage } from '../../../../requests/handler' import TopicCardGrid from '../../../LandingPage/components/TopicCardGrid/TopicCardGrid' diff --git a/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/components/CollapsibleTopicElement.tsx b/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/components/CollapsibleTopicElement.tsx index cabb3a4a7..94f1e55c5 100644 --- a/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/components/CollapsibleTopicElement.tsx +++ b/client/src/pages/ReplaceApplicationPage/components/SelectTopicStep/components/CollapsibleTopicElement.tsx @@ -11,9 +11,9 @@ import { Center, Loader, } from '@mantine/core' -import { ITopicOverview, ITopic } from '../../../../../requests/responses/topic' +import type { ITopicOverview, ITopic } from '../../../../../requests/responses/topic' import ThesisTypeBadge from '../../../../LandingPage/components/ThesisTypBadge/ThesisTypBadge' -import { IPublishedThesis } from '../../../../../requests/responses/thesis' +import type { IPublishedThesis } from '../../../../../requests/responses/thesis' import { useHover } from '@mantine/hooks' import AvatarUserList from '../../../../../components/AvatarUserList/AvatarUserList' import DocumentEditor from '../../../../../components/DocumentEditor/DocumentEditor' @@ -34,6 +34,11 @@ const CollapsibleTopicElement = ({ topic, onApply }: ICollapsibleTopicElementPro const isTopicOverview = 'topicId' in topic const fullTopic = useTopic(isTopicOverview && expanded ? topic.topicId : undefined) + const deadlinePassed = + !!fullTopic && + !!fullTopic.applicationDeadline && + new Date(fullTopic.applicationDeadline) < new Date() + return ( )} - {onApply && - isTopicOverview && - (() => { - const deadlinePassed = - !!fullTopic && - !!fullTopic.applicationDeadline && - new Date(fullTopic.applicationDeadline) < new Date() - return ( - - - {deadlinePassed && ( - - Application deadline has passed. - - )} - - ) - })()} + {onApply && isTopicOverview && ( + + + {deadlinePassed && ( + + Application deadline has passed. + + )} + + )} diff --git a/client/src/pages/ResearchGroupAdminPage/ResearchGroupAdminPage.tsx b/client/src/pages/ResearchGroupAdminPage/ResearchGroupAdminPage.tsx index 6ccb56928..4a9e4917d 100644 --- a/client/src/pages/ResearchGroupAdminPage/ResearchGroupAdminPage.tsx +++ b/client/src/pages/ResearchGroupAdminPage/ResearchGroupAdminPage.tsx @@ -14,14 +14,13 @@ import { } from '@mantine/core' import { MagnifyingGlass, Plus, UsersThree } from '@phosphor-icons/react' import { doRequest } from '../../requests/request' -import { PaginationResponse } from '../../requests/responses/pagination' -import { IResearchGroup } from '../../requests/responses/researchGroup' +import type { PaginationResponse } from '../../requests/responses/pagination' +import type { IResearchGroup } from '../../requests/responses/researchGroup' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' import ResearchGroupCard from './components/ResearchGroupCard' -import CreateResearchGroupModal, { - ResearchGroupFormValues, -} from './components/CreateResearchGroupModal' +import type { ResearchGroupFormValues } from './components/CreateResearchGroupModal' +import CreateResearchGroupModal from './components/CreateResearchGroupModal' import { useDebouncedValue } from '@mantine/hooks' import { showNotification } from '@mantine/notifications' import NoContentFoundCard from '../../components/NoContentFoundCard/NoContentFoundCard' @@ -163,7 +162,7 @@ const ResearchGroupAdminPage = () => { verticalSpacing={{ base: 'xs', sm: 'sm', xl: 'md' }} > {(researchGroups?.content ?? []).map((group) => ( - + ))} )} diff --git a/client/src/pages/ResearchGroupAdminPage/components/ResearchGroupCard.tsx b/client/src/pages/ResearchGroupAdminPage/components/ResearchGroupCard.tsx index 2267dde7e..4be1827c2 100644 --- a/client/src/pages/ResearchGroupAdminPage/components/ResearchGroupCard.tsx +++ b/client/src/pages/ResearchGroupAdminPage/components/ResearchGroupCard.tsx @@ -1,6 +1,6 @@ import { Badge, Box, Card, Flex, Group, Stack, Text } from '@mantine/core' import { Buildings, Users } from '@phosphor-icons/react' -import { IResearchGroup } from '../../../requests/responses/researchGroup' +import type { IResearchGroup } from '../../../requests/responses/researchGroup' import { CustomAvatar } from '../../../components/CustomAvatar/CustomAvatar' import { formatUser } from '../../../utils/format' import { useHover } from '@mantine/hooks' diff --git a/client/src/pages/ResearchGroupSettingPage/ResearchGroupSettingPage.tsx b/client/src/pages/ResearchGroupSettingPage/ResearchGroupSettingPage.tsx index 2416c86fe..2ab17282e 100644 --- a/client/src/pages/ResearchGroupSettingPage/ResearchGroupSettingPage.tsx +++ b/client/src/pages/ResearchGroupSettingPage/ResearchGroupSettingPage.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react' import { useParams, useSearchParams } from 'react-router' -import { IResearchGroup } from '../../requests/responses/researchGroup' +import type { IResearchGroup } from '../../requests/responses/researchGroup' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' @@ -10,7 +10,7 @@ import ResearchGroupMembers from './components/MemberSettings/ResearchGroupMembe import EmailTemplatesOverview from './components/EmailTemplateSettings/EmailTemplatesOverview' import { useUser } from '../../hooks/authentication' import ApplicationPhaseSettingsCard from './components/ApplicationPhaseSettingsCard' -import { IResearchGroupSettings } from '../../requests/responses/researchGroupSettings' +import type { IResearchGroupSettings } from '../../requests/responses/researchGroupSettings' import PresentationSettingsCard from './components/PresentationSettingsCard' import ProposalSettingsCard from './components/ProposalSettingsCard' import EmailSettingsCard from './components/EmailSettingsCard' @@ -37,7 +37,7 @@ const ResearchGroupSettingPage = () => { useEffect(() => { const params = new URLSearchParams(searchParams) - if (selectedTab != 'general') { + if (selectedTab !== 'general') { params.set('setting', selectedTab) } else { params.delete('setting') diff --git a/client/src/pages/ResearchGroupSettingPage/components/ApplicationEmailContentSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/ApplicationEmailContentSettingsCard.tsx index f698ad2ee..5f05b4b52 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/ApplicationEmailContentSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/ApplicationEmailContentSettingsCard.tsx @@ -4,7 +4,7 @@ import { doRequest } from '../../../requests/request' import { useParams } from 'react-router' import { showSimpleError } from '../../../utils/notification' import { getApiResponseErrorMessage } from '../../../requests/handler' -import { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' +import type { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' import { Info } from '@phosphor-icons/react' interface ApplicationEmailContentSettingsCardProps { diff --git a/client/src/pages/ResearchGroupSettingPage/components/ApplicationPhaseSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/ApplicationPhaseSettingsCard.tsx index 0c628fb85..a2a99a8d2 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/ApplicationPhaseSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/ApplicationPhaseSettingsCard.tsx @@ -4,7 +4,7 @@ import { doRequest } from '../../../requests/request' import { useParams } from 'react-router' import { showSimpleError } from '../../../utils/notification' import { getApiResponseErrorMessage } from '../../../requests/handler' -import { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' +import type { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' import { WarningCircleIcon } from '@phosphor-icons/react' interface ApplicationPhaseSettingsCard { diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailSettingsCard.tsx index 8c2317155..439f7a96a 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailSettingsCard.tsx @@ -7,7 +7,7 @@ import { getApiResponseErrorMessage } from '../../../requests/handler' import { showSimpleError } from '../../../utils/notification' import { showNotification } from '@mantine/notifications' import { useParams } from 'react-router' -import { +import type { IResearchGroupSettings, IResearchGroupSettingsEmail, } from '../../../requests/responses/researchGroupSettings' diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateCard.tsx index 3e940eaeb..84cb4d012 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateCard.tsx @@ -1,5 +1,5 @@ import { Badge, Card, Text, Stack, Title, Group, Button, Flex, Tooltip } from '@mantine/core' -import { IEmailTemplate } from '../../../../requests/responses/emailtemplate' +import type { IEmailTemplate } from '../../../../requests/responses/emailtemplate' import { useState } from 'react' import EmailTemplatePreviewModal from './EmailTemplatePreviewModal' import { EyeIcon, NotePencilIcon } from '@phosphor-icons/react' diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateEditPage.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateEditPage.tsx index e91f6c937..393c17955 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateEditPage.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplateEditPage.tsx @@ -4,8 +4,8 @@ import { useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router' import { getApiResponseErrorMessage } from '../../../../requests/handler' import { doRequest } from '../../../../requests/request' -import { IEmailTemplate } from '../../../../requests/responses/emailtemplate' -import { PaginationResponse } from '../../../../requests/responses/pagination' +import type { IEmailTemplate } from '../../../../requests/responses/emailtemplate' +import type { PaginationResponse } from '../../../../requests/responses/pagination' import { showSimpleError, showSimpleSuccess } from '../../../../utils/notification' import EmailTextEditor from './EmailTextEditor/EmailTextEditor' import DOMPurify from 'dompurify' @@ -59,11 +59,11 @@ const EmailTemplateEditPage = () => { ) }, [templateCase, researchGroupId]) - const deleteTemplate = async () => { + const deleteTemplate = () => { if (!researchGroupTemplate) return setLoading(true) - await doRequest( + doRequest( `/v2/email-templates/${researchGroupTemplate.id}`, { method: 'DELETE', @@ -82,7 +82,7 @@ const EmailTemplateEditPage = () => { ) } - const saveChanges = async () => { + const saveChanges = () => { if (!editingTemplate) return if (editingTemplate === defaultTemplate) { @@ -99,7 +99,7 @@ const EmailTemplateEditPage = () => { ? editingTemplate.researchGroup.id : researchGroupId - await doRequest( + doRequest( url, { method, diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatePreviewModal.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatePreviewModal.tsx index f11a01845..c1a2c54e2 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatePreviewModal.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatePreviewModal.tsx @@ -3,7 +3,7 @@ import { useEffect, useMemo, useState } from 'react' import DOMPurify from 'dompurify' import { getApiResponseErrorMessage } from '../../../../requests/handler' import { doRequest } from '../../../../requests/request' -import { IEmailTemplate, IMailVariableDto } from '../../../../requests/responses/emailtemplate' +import type { IEmailTemplate, IMailVariableDto } from '../../../../requests/responses/emailtemplate' import { showSimpleError } from '../../../../utils/notification' interface IEmailTemplatePreviewModalProps { diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatesOverview.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatesOverview.tsx index 9c1f8e0bc..9f17a1fb6 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatesOverview.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTemplatesOverview.tsx @@ -1,8 +1,8 @@ import { useEffect, useState } from 'react' import { getApiResponseErrorMessage } from '../../../../requests/handler' import { doRequest } from '../../../../requests/request' -import { IEmailTemplate } from '../../../../requests/responses/emailtemplate' -import { PaginationResponse } from '../../../../requests/responses/pagination' +import type { IEmailTemplate } from '../../../../requests/responses/emailtemplate' +import type { PaginationResponse } from '../../../../requests/responses/pagination' import { showSimpleError } from '../../../../utils/notification' import { Box, Divider, Flex, Loader, Stack, TextInput, Title } from '@mantine/core' import { ResearchGroupSettingsCard } from '../ResearchGroupSettingsCard' diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/EmailTextEditor.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/EmailTextEditor.tsx index 399db0aa3..30ffd2c5a 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/EmailTextEditor.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/EmailTextEditor.tsx @@ -1,11 +1,15 @@ import { Link, RichTextEditor, useRichTextEditorContext } from '@mantine/tiptap' import TextAlign from '@tiptap/extension-text-align' import Underline from '@tiptap/extension-underline' -import { Editor, useEditor } from '@tiptap/react' +import type { Editor } from '@tiptap/react' +import { useEditor } from '@tiptap/react' import StarterKit from '@tiptap/starter-kit' import { Combobox, Group, useCombobox } from '@mantine/core' import ReactComponent from './Extension' -import { IEmailTemplate, IMailVariableDto } from '../../../../../requests/responses/emailtemplate' +import type { + IEmailTemplate, + IMailVariableDto, +} from '../../../../../requests/responses/emailtemplate' import { useEffect, useMemo, useState } from 'react' import { CaretDownIcon, CaretUpIcon, Plus } from '@phosphor-icons/react' import { FontSize, TextStyle } from '@tiptap/extension-text-style' @@ -86,7 +90,7 @@ const EmailTextEditor = ({ onUpdate: ({ editor: ed }) => { if (setEditingTemplate && editingTemplate) { setEditingTemplate({ - ...editingTemplate!, + ...editingTemplate, bodyHtml: convertHtmlToTemplateVariables(ed.getHTML(), templateVariables), }) } diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/Extension.ts b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/Extension.ts index 4d244febf..65b4efe23 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/Extension.ts +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/Extension.ts @@ -1,7 +1,7 @@ import { Node } from '@tiptap/core' import { ReactNodeViewRenderer } from '@tiptap/react' import VariableComponent from './VariableComponent' -import { IMailVariableDto } from '../../../../../requests/responses/emailtemplate' +import type { IMailVariableDto } from '../../../../../requests/responses/emailtemplate' export default Node.create({ name: 'react-component', diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComboboxOptions.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComboboxOptions.tsx index ee3eb5bf9..0c36c00d0 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComboboxOptions.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComboboxOptions.tsx @@ -1,6 +1,6 @@ import { Combobox } from '@mantine/core' import { useMemo } from 'react' -import { IMailVariableDto } from '../../../../../requests/responses/emailtemplate' +import type { IMailVariableDto } from '../../../../../requests/responses/emailtemplate' import { MagnifyingGlassIcon } from '@phosphor-icons/react' interface IVariableComboboxOptionsProps { diff --git a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComponent.tsx b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComponent.tsx index 36c3264a7..a3a71c5e1 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComponent.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/EmailTemplateSettings/EmailTextEditor/VariableComponent.tsx @@ -1,8 +1,9 @@ import { Badge, Combobox, Group, useCombobox } from '@mantine/core' import { CaretDownIcon, CaretUpIcon } from '@phosphor-icons/react' -import { NodeViewWrapper, NodeViewProps } from '@tiptap/react' +import type { NodeViewProps } from '@tiptap/react' +import { NodeViewWrapper } from '@tiptap/react' import { useEffect, useState } from 'react' -import { IMailVariableDto } from '../../../../../requests/responses/emailtemplate' +import type { IMailVariableDto } from '../../../../../requests/responses/emailtemplate' import VariableComboboxOptions from './VariableComboboxOptions' export default function VariableComponent(props: NodeViewProps) { diff --git a/client/src/pages/ResearchGroupSettingPage/components/GeneralResearchGroupSettings.tsx b/client/src/pages/ResearchGroupSettingPage/components/GeneralResearchGroupSettings.tsx index 64cf48726..adac427bb 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/GeneralResearchGroupSettings.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/GeneralResearchGroupSettings.tsx @@ -3,8 +3,8 @@ import { doRequest } from '../../../requests/request' import { showNotification } from '@mantine/notifications' import { showSimpleError } from '../../../utils/notification' import { getApiResponseErrorMessage } from '../../../requests/handler' -import { IResearchGroup } from '../../../requests/responses/researchGroup' -import { ResearchGroupFormValues } from '../../ResearchGroupAdminPage/components/CreateResearchGroupModal' +import type { IResearchGroup } from '../../../requests/responses/researchGroup' +import type { ResearchGroupFormValues } from '../../ResearchGroupAdminPage/components/CreateResearchGroupModal' import ResearchGroupForm from '../../../components/ResearchGroupForm/ResearchGroupForm' interface IGeneralResearchGroupSettingsProps { diff --git a/client/src/pages/ResearchGroupSettingPage/components/GradingSchemeSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/GradingSchemeSettingsCard.tsx index 6c727d929..1e3f3f44a 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/GradingSchemeSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/GradingSchemeSettingsCard.tsx @@ -15,7 +15,7 @@ import { useParams } from 'react-router' import { doRequest } from '../../../requests/request' import { showSimpleError } from '../../../utils/notification' import { getApiResponseErrorMessage } from '../../../requests/handler' -import { +import type { IGradingSchemeComponent, IResearchGroupSettings, IResearchGroupSettingsGradingScheme, diff --git a/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/DeleteMemberModal.tsx b/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/DeleteMemberModal.tsx index 0bfe9073b..8a51b3af4 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/DeleteMemberModal.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/DeleteMemberModal.tsx @@ -1,5 +1,5 @@ import { Modal, Text, Button, Group, Alert, Stack } from '@mantine/core' -import { ILightUser } from '../../../../requests/responses/user' +import type { ILightUser } from '../../../../requests/responses/user' import { WarningCircleIcon } from '@phosphor-icons/react' type IDeleteMemberModalProps = { diff --git a/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/ResearchGroupMembers.tsx b/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/ResearchGroupMembers.tsx index ab8e5eab3..86f2b153d 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/ResearchGroupMembers.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/MemberSettings/ResearchGroupMembers.tsx @@ -21,7 +21,7 @@ import { } from '@phosphor-icons/react' import AddResearchGroupMemberModal from './AddResearchGroupMemberModal' import { useEffect, useState } from 'react' -import { ILightUser } from '../../../../requests/responses/user' +import type { ILightUser } from '../../../../requests/responses/user' import { doRequest } from '../../../../requests/request' import { showSimpleError } from '../../../../utils/notification' import { getApiResponseErrorMessage } from '../../../../requests/handler' @@ -29,7 +29,7 @@ import { showNotification } from '@mantine/notifications' import UserInformationRow from '../../../../components/UserInformationRow/UserInformationRow' import DeleteMemberModal from './DeleteMemberModal' import { ResearchGroupSettingsCard } from '../ResearchGroupSettingsCard' -import { IResearchGroup } from '../../../../requests/responses/researchGroup' +import type { IResearchGroup } from '../../../../requests/responses/researchGroup' interface IResearchGroupMembersProps { researchGroupData: IResearchGroup | undefined diff --git a/client/src/pages/ResearchGroupSettingPage/components/PresentationSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/PresentationSettingsCard.tsx index d73a734d2..95f1a68e2 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/PresentationSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/PresentationSettingsCard.tsx @@ -4,7 +4,7 @@ import { doRequest } from '../../../requests/request' import { useParams } from 'react-router' import { showSimpleError } from '../../../utils/notification' import { getApiResponseErrorMessage } from '../../../requests/handler' -import { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' +import type { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' interface PresentaionSettingsProps { presentationDurationSettings: number diff --git a/client/src/pages/ResearchGroupSettingPage/components/ProposalSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/ProposalSettingsCard.tsx index 7424ad112..74d151d1d 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/ProposalSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/ProposalSettingsCard.tsx @@ -4,7 +4,7 @@ import { doRequest } from '../../../requests/request' import { useParams } from 'react-router' import { showSimpleError } from '../../../utils/notification' import { getApiResponseErrorMessage } from '../../../requests/handler' -import { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' +import type { IResearchGroupSettings } from '../../../requests/responses/researchGroupSettings' interface ProposalSettingsCardProps { proposalPhaseActive: boolean diff --git a/client/src/pages/ResearchGroupSettingPage/components/ResearchGroupSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/ResearchGroupSettingsCard.tsx index 1f8881fdd..8f6c2f174 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/ResearchGroupSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/ResearchGroupSettingsCard.tsx @@ -1,5 +1,5 @@ import { Card, Stack, Title, Text } from '@mantine/core' -import { ReactNode } from 'react' +import type { ReactNode } from 'react' interface IResearchGroupSettingsCardProps { title: string diff --git a/client/src/pages/ResearchGroupSettingPage/components/ScientificWritingGuideSettingsCard.tsx b/client/src/pages/ResearchGroupSettingPage/components/ScientificWritingGuideSettingsCard.tsx index ababc167f..322b3a74e 100644 --- a/client/src/pages/ResearchGroupSettingPage/components/ScientificWritingGuideSettingsCard.tsx +++ b/client/src/pages/ResearchGroupSettingPage/components/ScientificWritingGuideSettingsCard.tsx @@ -7,7 +7,7 @@ import { getApiResponseErrorMessage } from '../../../requests/handler' import { showSimpleError } from '../../../utils/notification' import { showNotification } from '@mantine/notifications' import { useParams } from 'react-router' -import { +import type { IResearchGroupSettings, IResearchGroupSettingsWritingGuide, } from '../../../requests/responses/researchGroupSettings' diff --git a/client/src/pages/ReviewApplicationPage/ReviewApplicationPage.tsx b/client/src/pages/ReviewApplicationPage/ReviewApplicationPage.tsx index 02b565334..9ebbec70a 100644 --- a/client/src/pages/ReviewApplicationPage/ReviewApplicationPage.tsx +++ b/client/src/pages/ReviewApplicationPage/ReviewApplicationPage.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router' -import { ApplicationState, IApplication } from '../../requests/responses/application' +import type { IApplication } from '../../requests/responses/application' +import { ApplicationState } from '../../requests/responses/application' import { doRequest } from '../../requests/request' import ApplicationsProvider from '../../providers/ApplicationsProvider/ApplicationsProvider' import { Grid, Text, Center } from '@mantine/core' diff --git a/client/src/pages/ReviewApplicationPage/components/ApplicationListItem/ApplicationListItem.tsx b/client/src/pages/ReviewApplicationPage/components/ApplicationListItem/ApplicationListItem.tsx index f89561e5b..6a833ddae 100644 --- a/client/src/pages/ReviewApplicationPage/components/ApplicationListItem/ApplicationListItem.tsx +++ b/client/src/pages/ReviewApplicationPage/components/ApplicationListItem/ApplicationListItem.tsx @@ -1,5 +1,5 @@ import { Badge, Group, Stack, Text, Paper } from '@mantine/core' -import { IApplication } from '../../../../requests/responses/application' +import type { IApplication } from '../../../../requests/responses/application' import { ApplicationStateColor } from '../../../../config/colors' import { formatApplicationState, formatDate } from '../../../../utils/format' import React from 'react' diff --git a/client/src/pages/ReviewApplicationPage/components/ApplicationReviewBody/ApplicationReviewBody.tsx b/client/src/pages/ReviewApplicationPage/components/ApplicationReviewBody/ApplicationReviewBody.tsx index 1167484cf..d59952c5e 100644 --- a/client/src/pages/ReviewApplicationPage/components/ApplicationReviewBody/ApplicationReviewBody.tsx +++ b/client/src/pages/ReviewApplicationPage/components/ApplicationReviewBody/ApplicationReviewBody.tsx @@ -2,7 +2,7 @@ import ApplicationData from '../../../../components/ApplicationData/ApplicationD import ApplicationReviewForm from '../../../../components/ApplicationReviewForm/ApplicationReviewForm' import { Divider, Group, Stack } from '@mantine/core' import React, { useEffect } from 'react' -import { IApplication } from '../../../../requests/responses/application' +import type { IApplication } from '../../../../requests/responses/application' import ApplicationRejectButton from '../../../../components/ApplicationRejectButton/ApplicationRejectButton' import ApplicationDeleteButton from '../../../../components/ApplicationDeleteButton/ApplicationDeleteButton' diff --git a/client/src/pages/ReviewApplicationPage/components/ApplicationsSidebar/ApplicationsSidebar.tsx b/client/src/pages/ReviewApplicationPage/components/ApplicationsSidebar/ApplicationsSidebar.tsx index 4940c840c..572b43bc8 100644 --- a/client/src/pages/ReviewApplicationPage/components/ApplicationsSidebar/ApplicationsSidebar.tsx +++ b/client/src/pages/ReviewApplicationPage/components/ApplicationsSidebar/ApplicationsSidebar.tsx @@ -2,7 +2,7 @@ import { Center, Pagination, Stack, Text } from '@mantine/core' import ApplicationsFilters from '../../../../components/ApplicationsFilters/ApplicationsFilters' import React, { useEffect, useRef, useState } from 'react' import { shouldIgnoreArrowKey } from './keyNavigationFilter' -import { IApplication } from '../../../../requests/responses/application' +import type { IApplication } from '../../../../requests/responses/application' import { useApplicationsContext } from '../../../../providers/ApplicationsProvider/hooks' import ApplicationListItem from '../ApplicationListItem/ApplicationListItem' diff --git a/client/src/pages/SettingsPage/components/NotificationSettings/components/NotificationToggleSwitch/NotificationToggleSwitch.tsx b/client/src/pages/SettingsPage/components/NotificationSettings/components/NotificationToggleSwitch/NotificationToggleSwitch.tsx index 3790e3600..34c48a9cf 100644 --- a/client/src/pages/SettingsPage/components/NotificationSettings/components/NotificationToggleSwitch/NotificationToggleSwitch.tsx +++ b/client/src/pages/SettingsPage/components/NotificationSettings/components/NotificationToggleSwitch/NotificationToggleSwitch.tsx @@ -1,4 +1,5 @@ -import React, { Dispatch, SetStateAction } from 'react' +import type { Dispatch, SetStateAction } from 'react' +import React from 'react' import { Switch, type BoxProps } from '@mantine/core' import { useNotificationSetting } from '../../../../../../hooks/notification' diff --git a/client/src/pages/ThesisPage/components/FileHistoryTable/FileHistoryTable.tsx b/client/src/pages/ThesisPage/components/FileHistoryTable/FileHistoryTable.tsx index d08db6626..8f00b1a2c 100644 --- a/client/src/pages/ThesisPage/components/FileHistoryTable/FileHistoryTable.tsx +++ b/client/src/pages/ThesisPage/components/FileHistoryTable/FileHistoryTable.tsx @@ -1,5 +1,5 @@ -import { ILightUser } from '../../../../requests/responses/user' -import { UploadFileType } from '../../../../config/types' +import type { ILightUser } from '../../../../requests/responses/user' +import type { UploadFileType } from '../../../../config/types' import { Button, Center, Group, Input, Table, Text } from '@mantine/core' import { formatDate } from '../../../../utils/format' import { AuthenticatedFilePreviewButton } from '../../../../components/AuthenticatedFilePreviewButton/AuthenticatedFilePreviewButton' diff --git a/client/src/pages/ThesisPage/components/ThesisAssessmentSection/components/ReplaceAssessmentModal/ReplaceAssessmentModal.tsx b/client/src/pages/ThesisPage/components/ThesisAssessmentSection/components/ReplaceAssessmentModal/ReplaceAssessmentModal.tsx index 4c659197a..e0f9d06ba 100644 --- a/client/src/pages/ThesisPage/components/ThesisAssessmentSection/components/ReplaceAssessmentModal/ReplaceAssessmentModal.tsx +++ b/client/src/pages/ThesisPage/components/ThesisAssessmentSection/components/ReplaceAssessmentModal/ReplaceAssessmentModal.tsx @@ -15,13 +15,13 @@ import { Plus, Trash } from '@phosphor-icons/react' import { useEffect, useState } from 'react' import DocumentEditor from '../../../../../../components/DocumentEditor/DocumentEditor' import { doRequest } from '../../../../../../requests/request' -import { IThesis } from '../../../../../../requests/responses/thesis' +import type { IThesis } from '../../../../../../requests/responses/thesis' import { useLoadedThesisContext, useThesisUpdateAction, } from '../../../../../../providers/ThesisProvider/hooks' import { ApiError } from '../../../../../../requests/handler' -import { IResearchGroupSettingsGradingScheme } from '../../../../../../requests/responses/researchGroupSettings' +import type { IResearchGroupSettingsGradingScheme } from '../../../../../../requests/responses/researchGroupSettings' import { calculateGradeFromComponents } from '../../../../../../utils/grade' interface IGradeComponent { diff --git a/client/src/pages/ThesisPage/components/ThesisConfigSection/ThesisConfigSection.tsx b/client/src/pages/ThesisPage/components/ThesisConfigSection/ThesisConfigSection.tsx index c9d4dbbe1..2aefa6223 100644 --- a/client/src/pages/ThesisPage/components/ThesisConfigSection/ThesisConfigSection.tsx +++ b/client/src/pages/ThesisPage/components/ThesisConfigSection/ThesisConfigSection.tsx @@ -1,4 +1,4 @@ -import { IThesis, ThesisState } from '../../../../requests/responses/thesis' +import type { IThesis, ThesisState } from '../../../../requests/responses/thesis' import { Accordion, Alert, @@ -31,8 +31,8 @@ import ThesisStateBadge from '../../../../components/ThesisStateBadge/ThesisStat import ThesisVisibilitySelect from '../ThesisVisibilitySelect/ThesisVisibilitySelect' import { formatThesisType } from '../../../../utils/format' import LanguageSelect from '../../../../components/LanguageSelect/LanguageSelect' -import { PaginationResponse } from '../../../../requests/responses/pagination' -import { ILightResearchGroup } from '../../../../requests/responses/researchGroup' +import type { PaginationResponse } from '../../../../requests/responses/pagination' +import type { ILightResearchGroup } from '../../../../requests/responses/researchGroup' import { showSimpleError, showSimpleSuccess } from '../../../../utils/notification' import { useHasGroupAccess } from '../../../../hooks/authentication' import { Warning } from '@phosphor-icons/react' diff --git a/client/src/pages/ThesisPage/components/ThesisFeedbackOverview/ThesisFeedbackOverview.tsx b/client/src/pages/ThesisPage/components/ThesisFeedbackOverview/ThesisFeedbackOverview.tsx index a161e29c2..79d52bb70 100644 --- a/client/src/pages/ThesisPage/components/ThesisFeedbackOverview/ThesisFeedbackOverview.tsx +++ b/client/src/pages/ThesisPage/components/ThesisFeedbackOverview/ThesisFeedbackOverview.tsx @@ -3,7 +3,7 @@ import { useThesisUpdateAction, } from '../../../../providers/ThesisProvider/hooks' import { Center, Checkbox, Input, Table, Text } from '@mantine/core' -import { IThesis } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' import React from 'react' import AvatarUser from '../../../../components/AvatarUser/AvatarUser' import { formatDate } from '../../../../utils/format' @@ -86,7 +86,7 @@ const ThesisFeedbackOverview = (props: IThesisFeedbackOverviewProps) => { toggleFeedback(item)} /> diff --git a/client/src/pages/ThesisPage/components/ThesisFeedbackRequestButton/ThesisFeedbackRequestButton.tsx b/client/src/pages/ThesisPage/components/ThesisFeedbackRequestButton/ThesisFeedbackRequestButton.tsx index 19827a27a..1da32f73a 100644 --- a/client/src/pages/ThesisPage/components/ThesisFeedbackRequestButton/ThesisFeedbackRequestButton.tsx +++ b/client/src/pages/ThesisPage/components/ThesisFeedbackRequestButton/ThesisFeedbackRequestButton.tsx @@ -5,7 +5,7 @@ import { } from '../../../../providers/ThesisProvider/hooks' import { Button, Checkbox, Modal, Stack, Textarea, Text, Title, Group } from '@mantine/core' import { doRequest } from '../../../../requests/request' -import { IThesis } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' import { ApiError } from '../../../../requests/handler' interface IThesisFeedbackRequestButtonProps { @@ -132,10 +132,10 @@ const ThesisFeedbackRequestButton = (props: IThesisFeedbackRequestButtonProps) = label={change.feedback} checked={ editChanges.find((item) => item.feedbackId === change.feedbackId)?.completed ?? - !!change.completedAt + Boolean(change.completedAt) } onChange={(e) => { - if (e.target.checked === !!change.completedAt) { + if (e.target.checked === Boolean(change.completedAt)) { setEditChanges((prev) => prev.filter((item) => item.feedbackId !== change.feedbackId), ) diff --git a/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/ThesisFinalGradeSection.tsx b/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/ThesisFinalGradeSection.tsx index f8a8f5697..275e87c42 100644 --- a/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/ThesisFinalGradeSection.tsx +++ b/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/ThesisFinalGradeSection.tsx @@ -1,4 +1,5 @@ -import { IThesis, ThesisState } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' +import { ThesisState } from '../../../../requests/responses/thesis' import { useState } from 'react' import { Accordion, Button, Group, Stack, Text } from '@mantine/core' import SubmitFinalGradeModal from './components/SubmitFinalGradeModal/SubmitFinalGradeModal' diff --git a/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/components/SubmitFinalGradeModal/SubmitFinalGradeModal.tsx b/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/components/SubmitFinalGradeModal/SubmitFinalGradeModal.tsx index e38aef3ec..6dcb5f434 100644 --- a/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/components/SubmitFinalGradeModal/SubmitFinalGradeModal.tsx +++ b/client/src/pages/ThesisPage/components/ThesisFinalGradeSection/components/SubmitFinalGradeModal/SubmitFinalGradeModal.tsx @@ -1,4 +1,4 @@ -import { IThesis } from '../../../../../../requests/responses/thesis' +import type { IThesis } from '../../../../../../requests/responses/thesis' import { Alert, Button, Modal, Stack, Text, TextInput } from '@mantine/core' import { doRequest } from '../../../../../../requests/request' import { useEffect, useState } from 'react' diff --git a/client/src/pages/ThesisPage/components/ThesisInfoSection/ThesisInfoSection.tsx b/client/src/pages/ThesisPage/components/ThesisInfoSection/ThesisInfoSection.tsx index 042af5fd5..161d79a01 100644 --- a/client/src/pages/ThesisPage/components/ThesisInfoSection/ThesisInfoSection.tsx +++ b/client/src/pages/ThesisPage/components/ThesisInfoSection/ThesisInfoSection.tsx @@ -1,4 +1,4 @@ -import { IThesis } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' import React, { useEffect, useState } from 'react' import { Accordion, Button, Flex, Grid, Group, Stack, TextInput } from '@mantine/core' import DocumentEditor from '../../../../components/DocumentEditor/DocumentEditor' diff --git a/client/src/pages/ThesisPage/components/ThesisInfoSection/components/DownloadAllFilesButton/DownloadAllFilesButton.tsx b/client/src/pages/ThesisPage/components/ThesisInfoSection/components/DownloadAllFilesButton/DownloadAllFilesButton.tsx index e402692d5..fdf29259d 100644 --- a/client/src/pages/ThesisPage/components/ThesisInfoSection/components/DownloadAllFilesButton/DownloadAllFilesButton.tsx +++ b/client/src/pages/ThesisPage/components/ThesisInfoSection/components/DownloadAllFilesButton/DownloadAllFilesButton.tsx @@ -8,8 +8,8 @@ import { showSimpleError } from '../../../../../../utils/notification' import { getApiResponseErrorMessage } from '../../../../../../requests/handler' import JSZip from 'jszip' import { downloadFile } from '../../../../../../utils/blob' -import { IThesisComment } from '../../../../../../requests/responses/thesis' -import { PaginationResponse } from '../../../../../../requests/responses/pagination' +import type { IThesisComment } from '../../../../../../requests/responses/thesis' +import type { PaginationResponse } from '../../../../../../requests/responses/pagination' const DownloadAllFilesButton = () => { const { thesis, access } = useLoadedThesisContext() diff --git a/client/src/pages/ThesisPage/components/ThesisPresentationSection/components/PresentationCard.tsx b/client/src/pages/ThesisPage/components/ThesisPresentationSection/components/PresentationCard.tsx index 9bf671b06..859039072 100644 --- a/client/src/pages/ThesisPage/components/ThesisPresentationSection/components/PresentationCard.tsx +++ b/client/src/pages/ThesisPage/components/ThesisPresentationSection/components/PresentationCard.tsx @@ -13,7 +13,7 @@ import { Alert, Transition, } from '@mantine/core' -import { +import type { IPublishedPresentation, IPublishedThesis, IThesis, diff --git a/client/src/pages/ThesisPage/components/ThesisProposalSection/ThesisProposalSection.tsx b/client/src/pages/ThesisPage/components/ThesisProposalSection/ThesisProposalSection.tsx index 9740841e6..5c4b0f4fb 100644 --- a/client/src/pages/ThesisPage/components/ThesisProposalSection/ThesisProposalSection.tsx +++ b/client/src/pages/ThesisPage/components/ThesisProposalSection/ThesisProposalSection.tsx @@ -1,4 +1,5 @@ -import { IThesis, ThesisState } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' +import { ThesisState } from '../../../../requests/responses/thesis' import { Accordion, Center, Group, Stack, Text } from '@mantine/core' import { doRequest } from '../../../../requests/request' import { showSimpleError, showSimpleSuccess } from '../../../../utils/notification' diff --git a/client/src/pages/ThesisPage/components/ThesisStudentInfoSection/ThesisStudentInfoSection.tsx b/client/src/pages/ThesisPage/components/ThesisStudentInfoSection/ThesisStudentInfoSection.tsx index eab90aea5..7cf038946 100644 --- a/client/src/pages/ThesisPage/components/ThesisStudentInfoSection/ThesisStudentInfoSection.tsx +++ b/client/src/pages/ThesisPage/components/ThesisStudentInfoSection/ThesisStudentInfoSection.tsx @@ -1,5 +1,5 @@ import { Accordion, Button, Grid, Group, NumberInput, Paper, Stack } from '@mantine/core' -import { IThesis } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' import LabeledItem from '../../../../components/LabeledItem/LabeledItem' import { GLOBAL_CONFIG } from '../../../../config/global' import { useHighlightedBackgroundColor } from '../../../../hooks/theme' diff --git a/client/src/pages/ThesisPage/components/ThesisVisibilitySelect/ThesisVisibilitySelect.tsx b/client/src/pages/ThesisPage/components/ThesisVisibilitySelect/ThesisVisibilitySelect.tsx index 9a6d74c1f..3f4f888d8 100644 --- a/client/src/pages/ThesisPage/components/ThesisVisibilitySelect/ThesisVisibilitySelect.tsx +++ b/client/src/pages/ThesisPage/components/ThesisVisibilitySelect/ThesisVisibilitySelect.tsx @@ -1,4 +1,5 @@ -import { Select, SelectProps, Text } from '@mantine/core' +import type { SelectProps } from '@mantine/core' +import { Select, Text } from '@mantine/core' const ThesisVisibilitySelect = (props: SelectProps) => { const { ...others } = props diff --git a/client/src/pages/ThesisPage/components/ThesisWritingSection/ThesisWritingSection.tsx b/client/src/pages/ThesisPage/components/ThesisWritingSection/ThesisWritingSection.tsx index 2134b6048..ad86fdc34 100644 --- a/client/src/pages/ThesisPage/components/ThesisWritingSection/ThesisWritingSection.tsx +++ b/client/src/pages/ThesisPage/components/ThesisWritingSection/ThesisWritingSection.tsx @@ -1,4 +1,5 @@ -import { IThesis, ThesisState } from '../../../../requests/responses/thesis' +import type { IThesis } from '../../../../requests/responses/thesis' +import { ThesisState } from '../../../../requests/responses/thesis' import { Accordion, Center, Grid, Group, Stack, Text, Table, Alert } from '@mantine/core' import ConfirmationButton from '../../../../components/ConfirmationButton/ConfirmationButton' import { doRequest } from '../../../../requests/request' @@ -90,7 +91,7 @@ const ThesisWritingSection = () => { ]), ) const requiredFilesUploaded = - !!thesisFile && + Boolean(thesisFile) && !Object.entries(GLOBAL_CONFIG.thesis_files) .filter(([, value]) => value.required) .some(([key]) => !customFiles[key]) diff --git a/client/src/pages/TopicPage/components/TopicAdittionalInformationCard.tsx b/client/src/pages/TopicPage/components/TopicAdittionalInformationCard.tsx index a9e82fa94..4b0398a5e 100644 --- a/client/src/pages/TopicPage/components/TopicAdittionalInformationCard.tsx +++ b/client/src/pages/TopicPage/components/TopicAdittionalInformationCard.tsx @@ -1,5 +1,5 @@ import { Card, Stack, Text, Divider, useMantineColorScheme } from '@mantine/core' -import { ITopic } from '../../../requests/responses/topic' +import type { ITopic } from '../../../requests/responses/topic' import { Buildings, Clock, GraduationCapIcon, Users } from '@phosphor-icons/react' import TopicAdittionalInformationSection from './TopicAdditionalInformationSection' import ThesisTypeBadge from '../../LandingPage/components/ThesisTypBadge/ThesisTypBadge' diff --git a/client/src/providers/ApplicationsProvider/ApplicationsProvider.tsx b/client/src/providers/ApplicationsProvider/ApplicationsProvider.tsx index 959ae232a..065eae74c 100644 --- a/client/src/providers/ApplicationsProvider/ApplicationsProvider.tsx +++ b/client/src/providers/ApplicationsProvider/ApplicationsProvider.tsx @@ -1,13 +1,10 @@ -import React, { PropsWithChildren, ReactNode, useEffect, useMemo, useRef, useState } from 'react' +import type { PropsWithChildren, ReactNode } from 'react' +import React, { useEffect, useMemo, useRef, useState } from 'react' import { doRequest } from '../../requests/request' -import { PaginationResponse } from '../../requests/responses/pagination' -import { - ApplicationsContext, - IApplicationsContext, - IApplicationsFilters, - IApplicationsSort, -} from './context' -import { ApplicationState, IApplication } from '../../requests/responses/application' +import type { PaginationResponse } from '../../requests/responses/pagination' +import type { IApplicationsContext, IApplicationsFilters, IApplicationsSort } from './context' +import { ApplicationsContext } from './context' +import type { ApplicationState, IApplication } from '../../requests/responses/application' import { useDebouncedValue } from '@mantine/hooks' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' diff --git a/client/src/providers/ApplicationsProvider/context.ts b/client/src/providers/ApplicationsProvider/context.ts index a517f7be0..fdc5b5aa7 100644 --- a/client/src/providers/ApplicationsProvider/context.ts +++ b/client/src/providers/ApplicationsProvider/context.ts @@ -1,7 +1,8 @@ -import React, { Dispatch, SetStateAction } from 'react' -import { PaginationResponse } from '../../requests/responses/pagination' -import { ApplicationState, IApplication } from '../../requests/responses/application' -import { ITopicOverview } from '../../requests/responses/topic' +import type { Dispatch, SetStateAction } from 'react' +import React from 'react' +import type { PaginationResponse } from '../../requests/responses/pagination' +import type { ApplicationState, IApplication } from '../../requests/responses/application' +import type { ITopicOverview } from '../../requests/responses/topic' export interface IApplicationsFilters { search?: string diff --git a/client/src/providers/ApplicationsProvider/hooks.ts b/client/src/providers/ApplicationsProvider/hooks.ts index 962161cff..5ea6dd026 100644 --- a/client/src/providers/ApplicationsProvider/hooks.ts +++ b/client/src/providers/ApplicationsProvider/hooks.ts @@ -1,6 +1,6 @@ import { useContext } from 'react' import { ApplicationsContext } from './context' -import { IApplication } from '../../requests/responses/application' +import type { IApplication } from '../../requests/responses/application' export function useApplicationsContext() { const data = useContext(ApplicationsContext) diff --git a/client/src/providers/AuthenticationContext/AuthenticationProvider.tsx b/client/src/providers/AuthenticationContext/AuthenticationProvider.tsx index 002ded176..060936d9c 100644 --- a/client/src/providers/AuthenticationContext/AuthenticationProvider.tsx +++ b/client/src/providers/AuthenticationContext/AuthenticationProvider.tsx @@ -1,20 +1,17 @@ -import { PropsWithChildren, useEffect, useMemo, useState } from 'react' -import { - AuthenticationContext, - IAuthenticationContext, - IDecodedAccessToken, - IDecodedRefreshToken, -} from './context' +import type { PropsWithChildren } from 'react' +import { useEffect, useMemo, useState } from 'react' +import type { IAuthenticationContext, IDecodedAccessToken, IDecodedRefreshToken } from './context' +import { AuthenticationContext } from './context' import Keycloak from 'keycloak-js' import { GLOBAL_CONFIG } from '../../config/global' import { jwtDecode } from 'jwt-decode' import { getAuthenticationTokens, useAuthenticationTokens } from '../../hooks/authentication' import { useSignal } from '../../hooks/utility' -import { IUser } from '../../requests/responses/user' +import type { IUser } from '../../requests/responses/user' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { ApiError, getApiResponseErrorMessage } from '../../requests/handler' -import { ILightResearchGroup } from '../../requests/responses/researchGroup' +import type { ILightResearchGroup } from '../../requests/responses/researchGroup' export const keycloak = new Keycloak({ realm: GLOBAL_CONFIG.keycloak.realm, @@ -195,7 +192,7 @@ const AuthenticationProvider = (props: PropsWithChildren) => { const contextValue = useMemo(() => { return { - isAuthenticated: !!authenticationTokens?.access_token, + isAuthenticated: Boolean(authenticationTokens?.access_token), user: authenticationTokens?.access_token ? user : undefined, groups: [], updateUser: setUser, @@ -209,7 +206,7 @@ const AuthenticationProvider = (props: PropsWithChildren) => { } if (examinationReport) { - formData.append('examinationReport', examinationReport!) + formData.append('examinationReport', examinationReport) } if (cv) { @@ -261,7 +258,7 @@ const AuthenticationProvider = (props: PropsWithChildren) => { } }, [ user, - !!authenticationTokens?.access_token, + Boolean(authenticationTokens?.access_token), authenticationTokens?.refresh_token, location.origin, ]) diff --git a/client/src/providers/AuthenticationContext/context.ts b/client/src/providers/AuthenticationContext/context.ts index 3d224e54d..dc7222256 100644 --- a/client/src/providers/AuthenticationContext/context.ts +++ b/client/src/providers/AuthenticationContext/context.ts @@ -1,9 +1,9 @@ import { createContext } from 'react' -import { JwtPayload } from 'jwt-decode' -import { IUser } from '../../requests/responses/user' -import { IUpdateUserInformationPayload } from '../../requests/payloads/user' -import { PartialNull } from '../../utils/validation' -import { ILightResearchGroup } from '../../requests/responses/researchGroup' +import type { JwtPayload } from 'jwt-decode' +import type { IUser } from '../../requests/responses/user' +import type { IUpdateUserInformationPayload } from '../../requests/payloads/user' +import type { PartialNull } from '../../utils/validation' +import type { ILightResearchGroup } from '../../requests/responses/researchGroup' export interface IAuthenticationContext { isAuthenticated: boolean diff --git a/client/src/providers/InterviewProcessProvider/InterviewProcessProvider.tsx b/client/src/providers/InterviewProcessProvider/InterviewProcessProvider.tsx index cf206ab8d..9d2ee9ad8 100644 --- a/client/src/providers/InterviewProcessProvider/InterviewProcessProvider.tsx +++ b/client/src/providers/InterviewProcessProvider/InterviewProcessProvider.tsx @@ -1,10 +1,15 @@ -import React, { PropsWithChildren, useCallback, useEffect, useMemo, useState } from 'react' -import { InterviewProcessContext, IInterviewProcessContext } from './context' +import type { PropsWithChildren } from 'react' +import React, { useCallback, useEffect, useMemo, useState } from 'react' +import type { IInterviewProcessContext } from './context' +import { InterviewProcessContext } from './context' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' -import { IIntervieweeLightWithNextSlot, IInterviewSlot } from '../../requests/responses/interview' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { + IIntervieweeLightWithNextSlot, + IInterviewSlot, +} from '../../requests/responses/interview' +import type { PaginationResponse } from '../../requests/responses/pagination' import { useParams } from 'react-router' interface IInterviewProcessProviderProps { diff --git a/client/src/providers/InterviewProcessProvider/context.ts b/client/src/providers/InterviewProcessProvider/context.ts index 486ecda19..f9c55cfcf 100644 --- a/client/src/providers/InterviewProcessProvider/context.ts +++ b/client/src/providers/InterviewProcessProvider/context.ts @@ -1,5 +1,9 @@ -import React, { Dispatch, SetStateAction } from 'react' -import { IIntervieweeLightWithNextSlot, IInterviewSlot } from '../../requests/responses/interview' // adjust path if needed +import type { Dispatch, SetStateAction } from 'react' +import React from 'react' +import type { + IIntervieweeLightWithNextSlot, + IInterviewSlot, +} from '../../requests/responses/interview' // adjust path if needed export interface IInterviewProcessContext { processId: string | undefined diff --git a/client/src/providers/ThesesProvider/ThesesProvider.tsx b/client/src/providers/ThesesProvider/ThesesProvider.tsx index 4a0da5a46..3e5e6f4b1 100644 --- a/client/src/providers/ThesesProvider/ThesesProvider.tsx +++ b/client/src/providers/ThesesProvider/ThesesProvider.tsx @@ -1,8 +1,10 @@ -import React, { PropsWithChildren, useEffect, useMemo, useState } from 'react' -import { ThesesContext, IThesesContext, IThesesFilters, IThesesSort } from './context' -import { IThesisOverview, ThesisState } from '../../requests/responses/thesis' +import type { PropsWithChildren } from 'react' +import React, { useEffect, useMemo, useState } from 'react' +import type { IThesesContext, IThesesFilters, IThesesSort } from './context' +import { ThesesContext } from './context' +import type { IThesisOverview, ThesisState } from '../../requests/responses/thesis' import { doRequest } from '../../requests/request' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { PaginationResponse } from '../../requests/responses/pagination' import { useDebouncedValue } from '@mantine/hooks' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' diff --git a/client/src/providers/ThesesProvider/context.ts b/client/src/providers/ThesesProvider/context.ts index f728bd5f9..2e3ff17f8 100644 --- a/client/src/providers/ThesesProvider/context.ts +++ b/client/src/providers/ThesesProvider/context.ts @@ -1,6 +1,7 @@ -import React, { Dispatch, SetStateAction } from 'react' -import { IThesisOverview, ThesisState } from '../../requests/responses/thesis' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { Dispatch, SetStateAction } from 'react' +import React from 'react' +import type { IThesisOverview, ThesisState } from '../../requests/responses/thesis' +import type { PaginationResponse } from '../../requests/responses/pagination' export interface IThesesFilters { search?: string diff --git a/client/src/providers/ThesisCommentsProvider/ThesisCommentsProvider.tsx b/client/src/providers/ThesisCommentsProvider/ThesisCommentsProvider.tsx index 560e373c8..6f3400bac 100644 --- a/client/src/providers/ThesisCommentsProvider/ThesisCommentsProvider.tsx +++ b/client/src/providers/ThesisCommentsProvider/ThesisCommentsProvider.tsx @@ -1,7 +1,9 @@ -import React, { PropsWithChildren, useEffect, useMemo, useState } from 'react' -import { IThesis, IThesisComment } from '../../requests/responses/thesis' -import { IThesisCommentsContext, ThesisCommentsContext } from './context' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { PropsWithChildren } from 'react' +import React, { useEffect, useMemo, useState } from 'react' +import type { IThesis, IThesisComment } from '../../requests/responses/thesis' +import type { IThesisCommentsContext } from './context' +import { ThesisCommentsContext } from './context' +import type { PaginationResponse } from '../../requests/responses/pagination' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' import { getApiResponseErrorMessage } from '../../requests/handler' diff --git a/client/src/providers/ThesisCommentsProvider/context.ts b/client/src/providers/ThesisCommentsProvider/context.ts index 627e6c295..72b8d1197 100644 --- a/client/src/providers/ThesisCommentsProvider/context.ts +++ b/client/src/providers/ThesisCommentsProvider/context.ts @@ -1,6 +1,7 @@ -import { IThesis, IThesisComment } from '../../requests/responses/thesis' -import React, { Dispatch, SetStateAction } from 'react' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { IThesis, IThesisComment } from '../../requests/responses/thesis' +import type { Dispatch, SetStateAction } from 'react' +import React from 'react' +import type { PaginationResponse } from '../../requests/responses/pagination' export interface IThesisCommentsContext { thesis: IThesis diff --git a/client/src/providers/ThesisProvider/ThesisProvider.tsx b/client/src/providers/ThesisProvider/ThesisProvider.tsx index c2c48c211..ba973e284 100644 --- a/client/src/providers/ThesisProvider/ThesisProvider.tsx +++ b/client/src/providers/ThesisProvider/ThesisProvider.tsx @@ -1,7 +1,9 @@ -import React, { PropsWithChildren, useEffect, useMemo, useState } from 'react' -import { IThesis } from '../../requests/responses/thesis' +import type { PropsWithChildren } from 'react' +import React, { useEffect, useMemo, useState } from 'react' +import type { IThesis } from '../../requests/responses/thesis' import { useThesis } from '../../hooks/fetcher' -import { IThesisContext, ThesisContext } from './context' +import type { IThesisContext } from './context' +import { ThesisContext } from './context' import NotFound from '../../components/NotFound/NotFound' import PageLoader from '../../components/PageLoader/PageLoader' import { useThesisAccess } from './hooks' diff --git a/client/src/providers/ThesisProvider/context.ts b/client/src/providers/ThesisProvider/context.ts index 3dd599699..ada93dc35 100644 --- a/client/src/providers/ThesisProvider/context.ts +++ b/client/src/providers/ThesisProvider/context.ts @@ -1,4 +1,4 @@ -import { IThesis } from '../../requests/responses/thesis' +import type { IThesis } from '../../requests/responses/thesis' import React from 'react' export interface IThesisContext { diff --git a/client/src/providers/ThesisProvider/hooks.ts b/client/src/providers/ThesisProvider/hooks.ts index 0ad61cb97..8bfd6f690 100644 --- a/client/src/providers/ThesisProvider/hooks.ts +++ b/client/src/providers/ThesisProvider/hooks.ts @@ -1,6 +1,6 @@ import { useContext, useMemo, useState } from 'react' import { ThesisContext } from './context' -import { IPublishedThesis, IThesis } from '../../requests/responses/thesis' +import type { IPublishedThesis, IThesis } from '../../requests/responses/thesis' import { showSimpleError, showSimpleSuccess } from '../../utils/notification' import { useUser } from '../../hooks/authentication' diff --git a/client/src/providers/TopicsProvider/TopicsProvider.tsx b/client/src/providers/TopicsProvider/TopicsProvider.tsx index 6748d9c71..08bf316d0 100644 --- a/client/src/providers/TopicsProvider/TopicsProvider.tsx +++ b/client/src/providers/TopicsProvider/TopicsProvider.tsx @@ -1,9 +1,12 @@ -import React, { PropsWithChildren, useEffect, useMemo, useRef, useState } from 'react' +import type { PropsWithChildren } from 'react' +import React, { useEffect, useMemo, useRef, useState } from 'react' import { doRequest } from '../../requests/request' import { showSimpleError } from '../../utils/notification' -import { ITopicOverview, TopicState } from '../../requests/responses/topic' -import { ITopicsContext, ITopicsFilters, TopicsContext } from './context' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { ITopicOverview } from '../../requests/responses/topic' +import { TopicState } from '../../requests/responses/topic' +import type { ITopicsContext, ITopicsFilters } from './context' +import { TopicsContext } from './context' +import type { PaginationResponse } from '../../requests/responses/pagination' interface ITopicsProviderProps { limit: number diff --git a/client/src/providers/TopicsProvider/context.ts b/client/src/providers/TopicsProvider/context.ts index d52dafd3f..5aec50437 100644 --- a/client/src/providers/TopicsProvider/context.ts +++ b/client/src/providers/TopicsProvider/context.ts @@ -1,6 +1,7 @@ -import React, { Dispatch, SetStateAction } from 'react' -import { ITopicOverview } from '../../requests/responses/topic' -import { PaginationResponse } from '../../requests/responses/pagination' +import type { Dispatch, SetStateAction } from 'react' +import React from 'react' +import type { ITopicOverview } from '../../requests/responses/topic' +import type { PaginationResponse } from '../../requests/responses/pagination' export interface ITopicsFilters { types?: string[] diff --git a/client/src/requests/handler.ts b/client/src/requests/handler.ts index 607151efc..a428e9bdc 100644 --- a/client/src/requests/handler.ts +++ b/client/src/requests/handler.ts @@ -1,4 +1,4 @@ -import { ApiResponse } from './request' +import type { ApiResponse } from './request' export function getApiResponseErrorMessage(response: ApiResponse) { if (response.status === 1005) { @@ -19,8 +19,6 @@ export function getApiResponseErrorMessage(response: ApiResponse) { message = 'You are not authorized to access this resource' } else if (response.status === 404) { message = 'Requested resource not found' - } else if (response.status === 404) { - message = 'Requested resource not found' } else if (response.status === 409) { message = 'Resource already exists' } else if (response.status === 501) { diff --git a/client/src/requests/responses/application.ts b/client/src/requests/responses/application.ts index a7e549597..d8b522e38 100644 --- a/client/src/requests/responses/application.ts +++ b/client/src/requests/responses/application.ts @@ -1,6 +1,6 @@ -import { ILightUser, IUser } from './user' -import { ITopic } from './topic' -import { ILightResearchGroup } from './researchGroup' +import type { ILightUser, IUser } from './user' +import type { ITopic } from './topic' +import type { ILightResearchGroup } from './researchGroup' export enum ApplicationState { NOT_ASSESSED = 'NOT_ASSESSED', diff --git a/client/src/requests/responses/emailtemplate.ts b/client/src/requests/responses/emailtemplate.ts index 8712178c5..ad1865864 100644 --- a/client/src/requests/responses/emailtemplate.ts +++ b/client/src/requests/responses/emailtemplate.ts @@ -1,4 +1,4 @@ -import { ILightResearchGroup } from './researchGroup' +import type { ILightResearchGroup } from './researchGroup' export interface IEmailTemplate { id: string diff --git a/client/src/requests/responses/interview.ts b/client/src/requests/responses/interview.ts index d6b8d21d7..771d9e72f 100644 --- a/client/src/requests/responses/interview.ts +++ b/client/src/requests/responses/interview.ts @@ -1,5 +1,5 @@ -import { ApplicationState, IApplicationSummary } from './application' -import { ILightUser } from './user' +import type { ApplicationState, IApplicationSummary } from './application' +import type { ILightUser } from './user' export enum InterviewState { UNCONTACTED = 'Uncontacted', diff --git a/client/src/requests/responses/researchGroup.ts b/client/src/requests/responses/researchGroup.ts index a0f68f319..fb0dc9416 100644 --- a/client/src/requests/responses/researchGroup.ts +++ b/client/src/requests/responses/researchGroup.ts @@ -1,4 +1,4 @@ -import { ILightUser } from './user' +import type { ILightUser } from './user' export interface IMinimalResearchGroup { id: string diff --git a/client/src/requests/responses/thesis.ts b/client/src/requests/responses/thesis.ts index d0ff62c71..4314cff4f 100644 --- a/client/src/requests/responses/thesis.ts +++ b/client/src/requests/responses/thesis.ts @@ -1,5 +1,5 @@ -import { ILightResearchGroup, IMinimalResearchGroup } from './researchGroup' -import { ILightUser, IMinimalUser } from './user' +import type { ILightResearchGroup, IMinimalResearchGroup } from './researchGroup' +import type { ILightUser, IMinimalUser } from './user' export enum ThesisState { PROPOSAL = 'PROPOSAL', @@ -153,7 +153,7 @@ export interface IPublishedPresentation { } export function isThesis(thesis: any): thesis is IThesis { - return thesis.thesisId && !!thesis.states && 'language' in thesis + return !!thesis.thesisId && !!thesis.states && 'language' in thesis } export function isThesisPresentation(presentation: any): presentation is IThesisPresentation { diff --git a/client/src/requests/responses/topic.ts b/client/src/requests/responses/topic.ts index d4aeb602d..6dac20708 100644 --- a/client/src/requests/responses/topic.ts +++ b/client/src/requests/responses/topic.ts @@ -1,5 +1,5 @@ -import { ILightResearchGroup, IMinimalResearchGroup } from './researchGroup' -import { ILightUser, IMinimalUser } from './user' +import type { ILightResearchGroup, IMinimalResearchGroup } from './researchGroup' +import type { ILightUser, IMinimalUser } from './user' export enum TopicState { OPEN = 'OPEN', diff --git a/client/src/utils/customDataLink.tsx b/client/src/utils/customDataLink.tsx index a6705f328..4f62b8989 100644 --- a/client/src/utils/customDataLink.tsx +++ b/client/src/utils/customDataLink.tsx @@ -1,5 +1,5 @@ import { Anchor, Text } from '@mantine/core' -import { ReactNode } from 'react' +import type { ReactNode } from 'react' // GitHub username rules (from the GitHub UI): // - 1-39 characters diff --git a/client/src/utils/file.ts b/client/src/utils/file.ts index 95752495a..be0aeb768 100644 --- a/client/src/utils/file.ts +++ b/client/src/utils/file.ts @@ -1,4 +1,4 @@ -import { UploadFileType } from '../config/types' +import type { UploadFileType } from '../config/types' export function getAdjustedFileType(filename: string, type: UploadFileType) { let adjustedType: UploadFileType = type diff --git a/client/src/utils/format.ts b/client/src/utils/format.ts index 2df0b0426..00c4cc91a 100644 --- a/client/src/utils/format.ts +++ b/client/src/utils/format.ts @@ -1,9 +1,10 @@ -import { ILightUser, IMinimalUser } from '../requests/responses/user' -import { IThesis, ThesisState } from '../requests/responses/thesis' -import { ApplicationState, IApplication } from '../requests/responses/application' +import type { ILightUser, IMinimalUser } from '../requests/responses/user' +import type { IThesis } from '../requests/responses/thesis' +import { ThesisState } from '../requests/responses/thesis' +import type { IApplication } from '../requests/responses/application' +import { ApplicationState } from '../requests/responses/application' import { GLOBAL_CONFIG } from '../config/global' import { InterviewState } from '../requests/responses/interview' -import { useMantineColorScheme } from '@mantine/core' import { TopicState } from '../requests/responses/topic' interface IFormatDateOptions { @@ -256,9 +257,7 @@ export function createInterviewStageLabel(score: number): string { } } -export function getInterviewStateColor(state: InterviewState): string { - const colorScheme = useMantineColorScheme() - +export function getInterviewStateColor(state: InterviewState, isDark: boolean): string { switch (state) { case InterviewState.UNCONTACTED: return 'primary.1' @@ -267,7 +266,7 @@ export function getInterviewStateColor(state: InterviewState): string { case InterviewState.SCHEDULED: return 'primary.5' case InterviewState.COMPLETED: - return colorScheme.colorScheme === 'dark' ? 'primary.8' : 'primary.10' + return isDark ? 'primary.8' : 'primary.10' default: return 'gray' } diff --git a/client/src/utils/thesis.ts b/client/src/utils/thesis.ts index c0db2b423..48c4f9b96 100644 --- a/client/src/utils/thesis.ts +++ b/client/src/utils/thesis.ts @@ -1,5 +1,6 @@ -import { IPublishedThesis, IThesis, ThesisState } from '../requests/responses/thesis' -import { ILightUser } from '../requests/responses/user' +import type { IPublishedThesis, IThesis } from '../requests/responses/thesis' +import { ThesisState } from '../requests/responses/thesis' +import type { ILightUser } from '../requests/responses/user' export function isThesisClosed(thesis: IThesis | IPublishedThesis) { return thesis.state === ThesisState.FINISHED || thesis.state === ThesisState.DROPPED_OUT @@ -23,9 +24,9 @@ export function hasStudentAccess( ...(thesis.examiners ?? []), ] - return !!( + return Boolean( users.some((row) => row.userId === user?.userId) || - user?.groups?.some((name) => name === 'admin') + user?.groups?.some((name) => name === 'admin'), ) } @@ -39,9 +40,9 @@ export function hasSupervisorAccess( const users = [...(thesis.supervisors ?? []), ...(thesis.examiners ?? [])] - return !!( + return Boolean( users.some((row) => row.userId === user?.userId) || - user?.groups?.some((name) => name === 'admin') + user?.groups?.some((name) => name === 'admin'), ) } @@ -49,8 +50,8 @@ export function hasExaminerAccess( thesis: IPublishedThesis | undefined, user: ILightUser | undefined, ) { - return !!( + return Boolean( (thesis?.examiners ?? []).some((row) => row.userId === user?.userId) || - user?.groups?.some((name) => name === 'admin') + user?.groups?.some((name) => name === 'admin'), ) } diff --git a/client/src/utils/user.ts b/client/src/utils/user.ts index 08013281c..55becd4e0 100644 --- a/client/src/utils/user.ts +++ b/client/src/utils/user.ts @@ -1,5 +1,5 @@ import { GLOBAL_CONFIG } from '../config/global' -import { IMinimalUser } from '../requests/responses/user' +import type { IMinimalUser } from '../requests/responses/user' export function getAvatar(user: IMinimalUser) { return user.avatar From 6b88fa858572fa126089576b01d552d098cad246 Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Mon, 11 May 2026 11:47:34 +0200 Subject: [PATCH 02/10] Apply consistent-type-imports autofix to test files Mechanical autofix from the new @typescript-eslint/consistent-type-imports rule; also drops an unnecessary type assertion on ResizeObserverMock that no-unnecessary-type-assertion flagged. tsc --noEmit is clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- client/test/render.tsx | 5 +++-- client/test/setup.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/test/render.tsx b/client/test/render.tsx index 40ef04957..1ca3630b2 100644 --- a/client/test/render.tsx +++ b/client/test/render.tsx @@ -1,6 +1,7 @@ -import { ReactElement, ReactNode } from 'react' +import type { ReactElement, ReactNode } from 'react' import { MantineProvider } from '@mantine/core' -import { render, RenderOptions, RenderResult } from '@testing-library/react' +import type { RenderOptions, RenderResult } from '@testing-library/react' +import { render } from '@testing-library/react' interface ProvidersProps { children: ReactNode diff --git a/client/test/setup.ts b/client/test/setup.ts index d9cbb00cc..52ab68594 100644 --- a/client/test/setup.ts +++ b/client/test/setup.ts @@ -30,7 +30,7 @@ class ResizeObserverMock { disconnect(): void {} } if (!('ResizeObserver' in globalThis)) { - globalThis.ResizeObserver = ResizeObserverMock as unknown as typeof ResizeObserver + globalThis.ResizeObserver = ResizeObserverMock } // 3) scrollTo — Mantine occasionally calls window.scrollTo and element.scrollTo. From 145cb43978dfce0dcae4d2eb79d95d910c912f39 Mon Sep 17 00:00:00 2001 From: Stephan Krusche Date: Mon, 11 May 2026 11:58:34 +0200 Subject: [PATCH 03/10] Adopt ?? in place of || for nullable fallbacks (prefer-nullish-coalescing) Mechanical conversion driven by the new @typescript-eslint/prefer-nullish-coalescing rule. ?? short-circuits only on null/undefined, so for typed-nullable values the change is semantically equivalent to ||. Cases where a falsy primitive value (0, '', false) is legitimately treated as "fall through" keep || with an inline disable comment. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../AuthenticatedArea/AuthenticatedArea.tsx | 1 + .../ApplicationData/ApplicationData.tsx | 20 +++++------ .../ApplicationReviewForm.tsx | 6 ++-- .../ApplicationsFilters.tsx | 12 +++---- .../components/FileElement/FileElement.tsx | 2 +- .../src/components/GanttChart/GanttChart.tsx | 4 +-- .../KeycloakUserAutocomplete.tsx | 2 +- .../PresentationsTable/PresentationsTable.tsx | 2 +- .../ReplacePresentationModal.tsx | 4 +-- .../ResearchGroupForm/ResearchGroupForm.tsx | 12 +++---- .../ThesesFilters/ThesesFilters.tsx | 10 +++--- client/src/components/TopicData/TopicData.tsx | 2 +- .../TopicsFilters/TopicsFilters.tsx | 2 +- .../UserInformationForm.tsx | 26 +++++++------- client/src/config/global.ts | 36 +++++++++---------- client/src/pages/AboutPage/AboutPage.tsx | 4 +-- .../InterviewBookingPage.tsx | 4 +-- .../components/CollapsibleDateCard.tsx | 2 +- .../components/DateHeaderItem.tsx | 2 +- .../IntervieweeAssesmentPage.tsx | 2 +- .../components/InterviewNoteCard.tsx | 2 +- .../components/ScoreCard.tsx | 2 +- .../ReplaceTopicModal/ReplaceTopicModal.tsx | 4 +-- .../PresentationOverviewPage.tsx | 6 +++- .../PresentationPage/PresentationPage.tsx | 23 ++++++------ .../ReplaceApplicationPage.tsx | 3 +- .../MotivationStep/MotivationStep.tsx | 4 +-- .../components/CollapsibleTopicElement.tsx | 1 + .../ResearchGroupSettingPage.tsx | 10 +++--- .../EmailTemplatesOverview.tsx | 2 ++ .../ApplicationsSidebar.tsx | 2 +- .../src/pages/SettingsPage/SettingsPage.tsx | 2 +- .../ReplaceAssessmentModal.tsx | 8 ++--- .../SubmitFinalGradeModal.tsx | 4 +-- .../components/PresentationCard.tsx | 2 +- .../ApplicationsProvider.tsx | 2 +- .../ThesesProvider/ThesesProvider.tsx | 2 +- .../TopicsProvider/TopicsProvider.tsx | 6 ++-- client/src/requests/request.ts | 2 +- 39 files changed, 127 insertions(+), 115 deletions(-) diff --git a/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx index 9b2bf19c5..28e912358 100644 --- a/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx +++ b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx @@ -138,6 +138,7 @@ const AuthenticatedArea = (props: PropsWithChildren) => minimizeAnimationDuration, ) // only use debounced State if value is false because otherwise the text is formatted weirdly if you expand the navigation + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentionally fall through on `false` so the debounced value is used while collapsing const minimized = opened ? false : minimizedState || Boolean(debouncedMinimized) const location = useLocation() diff --git a/client/src/components/ApplicationData/ApplicationData.tsx b/client/src/components/ApplicationData/ApplicationData.tsx index ff6b2a24a..78f99ba6b 100644 --- a/client/src/components/ApplicationData/ApplicationData.tsx +++ b/client/src/components/ApplicationData/ApplicationData.tsx @@ -45,22 +45,22 @@ const ApplicationData = (props: IApplicationDataProps) => { )} - - - + + + @@ -68,7 +68,7 @@ const ApplicationData = (props: IApplicationDataProps) => { @@ -84,14 +84,14 @@ const ApplicationData = (props: IApplicationDataProps) => { @@ -100,7 +100,7 @@ const ApplicationData = (props: IApplicationDataProps) => { @@ -108,7 +108,7 @@ const ApplicationData = (props: IApplicationDataProps) => { diff --git a/client/src/components/ApplicationReviewForm/ApplicationReviewForm.tsx b/client/src/components/ApplicationReviewForm/ApplicationReviewForm.tsx index 21631b954..25d070e92 100644 --- a/client/src/components/ApplicationReviewForm/ApplicationReviewForm.tsx +++ b/client/src/components/ApplicationReviewForm/ApplicationReviewForm.tsx @@ -90,10 +90,10 @@ const ApplicationReviewForm = (props: IApplicationReviewFormProps) => { if (application) { form.setInitialValues({ applicationId: application.applicationId, - title: application.topic?.title || application.thesisTitle || '', + title: application.topic?.title ?? application.thesisTitle ?? '', comment: application.comment || '', type: - application.thesisType || GLOBAL_CONFIG.thesis_types[application.user.studyDegree || ''] + application.thesisType || GLOBAL_CONFIG.thesis_types[application.user.studyDegree ?? ''] ? application.user.studyDegree : null, language: getDefaultLanguage(), @@ -247,7 +247,7 @@ const ApplicationReviewForm = (props: IApplicationReviewFormProps) => { ) } - const reviewers = application.reviewers || [] + const reviewers = application.reviewers ?? [] if (!reviewers.some((row) => row.user.userId === user.userId)) { reviewers.unshift({ diff --git a/client/src/components/ApplicationsFilters/ApplicationsFilters.tsx b/client/src/components/ApplicationsFilters/ApplicationsFilters.tsx index 4e5b551d6..20a167557 100644 --- a/client/src/components/ApplicationsFilters/ApplicationsFilters.tsx +++ b/client/src/components/ApplicationsFilters/ApplicationsFilters.tsx @@ -21,7 +21,7 @@ const ApplicationsFilters = (props: IApplicationsFiltersProps) => { } - value={filters.search || ''} + value={filters.search ?? ''} onChange={(e) => { setFilters((prev) => ({ ...prev, search: e.currentTarget.value })) }} @@ -44,7 +44,7 @@ const ApplicationsFilters = (props: IApplicationsFiltersProps) => { })) : [] } - value={filters.topics || []} + value={filters.topics ?? []} onChange={(value) => { setFilters((prev) => ({ ...prev, @@ -63,7 +63,7 @@ const ApplicationsFilters = (props: IApplicationsFiltersProps) => { value: key, label: formatThesisType(key), }))} - value={filters.types || []} + value={filters.types ?? []} onChange={(value) => { setFilters((prev) => ({ ...prev, @@ -82,7 +82,7 @@ const ApplicationsFilters = (props: IApplicationsFiltersProps) => { value: value, label: formatApplicationState(value), }))} - value={filters.states || []} + value={filters.states ?? []} onChange={(value) => { setFilters((prev) => ({ ...prev, @@ -102,8 +102,8 @@ const ApplicationsFilters = (props: IApplicationsFiltersProps) => { value={sort.column + ':' + sort.direction} onChange={(x) => setSort({ - column: (x?.split(':')[0] || 'createdAt') as any, - direction: (x?.split(':')[1] || 'asc') as any, + column: (x?.split(':')[0] ?? 'createdAt') as any, + direction: (x?.split(':')[1] ?? 'asc') as any, }) } /> diff --git a/client/src/components/FileElement/FileElement.tsx b/client/src/components/FileElement/FileElement.tsx index d8771638d..f4f891ce3 100644 --- a/client/src/components/FileElement/FileElement.tsx +++ b/client/src/components/FileElement/FileElement.tsx @@ -54,7 +54,7 @@ const FileElement = ({ return ( { data?.map((row) => ({ groupId: row.groupId, groupNode: row.groupNode, - })) || [], + })) ?? [], (a, b) => a.groupId === b.groupId, ) @@ -134,7 +134,7 @@ const GanttChart = (props: IGanttChartProps) => { } return { - data: data || [], + data: data ?? [], currentTime, totalRange, filteredRange, diff --git a/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx b/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx index b966952ba..91f6f2ae3 100644 --- a/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx +++ b/client/src/components/KeycloakUserAutocomplete.tsx/KeycloakUserAutocomplete.tsx @@ -29,7 +29,7 @@ const KeycloakUserAutocomplete = ({ const [debouncedSearchKey] = useDebouncedValue(searchKey, 300) const [userOptions, setUserOptions] = useState([]) const [loadingUsers, setLoadingUsers] = useState(false) - const [selectedUsername, setSelectedUsername] = useState(previousUser?.universityId || '') + const [selectedUsername, setSelectedUsername] = useState(previousUser?.universityId ?? '') const getUserOptionValue = (user: { firstName: string diff --git a/client/src/components/PresentationsTable/PresentationsTable.tsx b/client/src/components/PresentationsTable/PresentationsTable.tsx index 5740efbd5..6d3ee42eb 100644 --- a/client/src/components/PresentationsTable/PresentationsTable.tsx +++ b/client/src/components/PresentationsTable/PresentationsTable.tsx @@ -137,7 +137,7 @@ const PresentationsTable = presentation.location || 'Not available', + render: (presentation) => presentation.location ?? 'Not available', }, streamUrl: { accessor: 'streamUrl', diff --git a/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx b/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx index 2b9b0c784..2ea27b985 100644 --- a/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx +++ b/client/src/components/PresentationsTable/components/ReplacePresentationModal/ReplacePresentationModal.tsx @@ -78,8 +78,8 @@ const ReplacePresentationModal = (props: IReplacePresentationModalProps) => { form.setInitialValues({ type: presentation.type, visibility: presentation.visibility, - location: presentation.location || '', - streamUrl: presentation.streamUrl || '', + location: presentation.location ?? '', + streamUrl: presentation.streamUrl ?? '', language: presentation.language, date: new Date(presentation.scheduledAt), }) diff --git a/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx b/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx index c44277808..c3936d5fc 100644 --- a/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx +++ b/client/src/components/ResearchGroupForm/ResearchGroupForm.tsx @@ -14,12 +14,12 @@ interface IResearchGroupFormProps { } const getInitialValues = (initial: Partial | undefined) => ({ - name: initial?.name || '', - abbreviation: initial?.abbreviation || '', - campus: initial?.campus || '', - description: initial?.description || '', - websiteUrl: initial?.websiteUrl || '', - headUsername: initial?.head?.universityId || '', + name: initial?.name ?? '', + abbreviation: initial?.abbreviation ?? '', + campus: initial?.campus ?? '', + description: initial?.description ?? '', + websiteUrl: initial?.websiteUrl ?? '', + headUsername: initial?.head?.universityId ?? '', }) const getInitialHeadLabel = (initial: Partial | undefined): string => diff --git a/client/src/components/ThesesFilters/ThesesFilters.tsx b/client/src/components/ThesesFilters/ThesesFilters.tsx index 4ba086726..ffaed5a22 100644 --- a/client/src/components/ThesesFilters/ThesesFilters.tsx +++ b/client/src/components/ThesesFilters/ThesesFilters.tsx @@ -16,7 +16,7 @@ const ThesesFilters = () => { label='Search' placeholder='Search theses...' leftSection={} - value={filters.search || ''} + value={filters.search ?? ''} onChange={(x) => setFilters((prev) => ({ ...prev, search: x.target.value || undefined }))} /> @@ -32,8 +32,8 @@ const ThesesFilters = () => { value={sort.column + ':' + sort.direction} onChange={(x) => setSort({ - column: (x?.split(':')[0] || 'startDate') as any, - direction: (x?.split(':')[1] || 'asc') as any, + column: (x?.split(':')[0] ?? 'startDate') as any, + direction: (x?.split(':')[1] ?? 'asc') as any, }) } /> @@ -47,7 +47,7 @@ const ThesesFilters = () => { value: key, label: formatThesisType(key), }))} - value={filters.types || []} + value={filters.types ?? []} onChange={(x) => setFilters((prev) => ({ ...prev, @@ -65,7 +65,7 @@ const ThesesFilters = () => { value: value, label: formatThesisState(value), }))} - value={filters.states || []} + value={filters.states ?? []} onChange={(x) => setFilters((prev) => ({ ...prev, diff --git a/client/src/components/TopicData/TopicData.tsx b/client/src/components/TopicData/TopicData.tsx index 2ccd24ca1..f28e8eeec 100644 --- a/client/src/components/TopicData/TopicData.tsx +++ b/client/src/components/TopicData/TopicData.tsx @@ -36,7 +36,7 @@ const TopicData = (props: ITopicDataProps) => { {topic.thesisTypes ? ( diff --git a/client/src/components/TopicsFilters/TopicsFilters.tsx b/client/src/components/TopicsFilters/TopicsFilters.tsx index bf5e9d612..7cb23116d 100644 --- a/client/src/components/TopicsFilters/TopicsFilters.tsx +++ b/client/src/components/TopicsFilters/TopicsFilters.tsx @@ -44,7 +44,7 @@ const TopicsFilters = (props: ITopicsFiltersProps) => { checked={Boolean(filters.types?.includes(key))} onChange={(e) => { setFilters((prev) => ({ - types: [...(prev.types || []), key].filter( + types: [...(prev.types ?? []), key].filter( (row) => e.target.checked || row !== key, ), })) diff --git a/client/src/components/UserInformationForm/UserInformationForm.tsx b/client/src/components/UserInformationForm/UserInformationForm.tsx index af116ee1f..15501847d 100644 --- a/client/src/components/UserInformationForm/UserInformationForm.tsx +++ b/client/src/components/UserInformationForm/UserInformationForm.tsx @@ -159,21 +159,21 @@ const UserInformationForm = (props: IUserInformationFormProps) => { useEffect(() => { form.setValues({ - email: user?.email || '', - matriculationNumber: user?.matriculationNumber || '', - firstName: user?.firstName || '', - lastName: user?.lastName || '', - gender: user?.gender || '', - nationality: user?.nationality || '', - studyDegree: user?.studyDegree || '', - studyProgram: user?.studyProgram || '', + email: user?.email ?? '', + matriculationNumber: user?.matriculationNumber ?? '', + firstName: user?.firstName ?? '', + lastName: user?.lastName ?? '', + gender: user?.gender ?? '', + nationality: user?.nationality ?? '', + studyDegree: user?.studyDegree ?? '', + studyProgram: user?.studyProgram ?? '', semester: user?.enrolledAt ? enrollmentDateToSemester(user.enrolledAt).toString() : '', - researchGroupName: user?.researchGroupName || '', - specialSkills: user?.specialSkills || '', - interests: user?.interests || '', - projects: user?.projects || '', + researchGroupName: user?.researchGroupName ?? '', + specialSkills: user?.specialSkills ?? '', + interests: user?.interests ?? '', + projects: user?.projects ?? '', customData: Object.fromEntries( - Object.keys(GLOBAL_CONFIG.custom_data).map((key) => [key, user.customData?.[key] || '']), + Object.keys(GLOBAL_CONFIG.custom_data).map((key) => [key, user.customData?.[key] ?? '']), ), }) }, [user]) diff --git a/client/src/config/global.ts b/client/src/config/global.ts index 0f6f86246..37b3bc9f6 100644 --- a/client/src/config/global.ts +++ b/client/src/config/global.ts @@ -17,7 +17,7 @@ const parseEnvironment = (value: string | undefined): Environment | undefined => } const getEnvironmentVariable = (key: string, useJson = false): T | undefined => { - const value = process.env[key] || window.RUNTIME_ENVIRONMENT_VARIABLES?.[key] + const value = process.env[key] ?? window.RUNTIME_ENVIRONMENT_VARIABLES?.[key] if (!value) { return undefined @@ -31,48 +31,48 @@ const getEnvironmentVariable = (key: string, useJson = false): T | u } export const GLOBAL_CONFIG: IGlobalConfig = { - title: getEnvironmentVariable('APPLICATION_TITLE') || 'ThesisManagement', + title: getEnvironmentVariable('APPLICATION_TITLE') ?? 'ThesisManagement', - chair_name: getEnvironmentVariable('CHAIR_NAME') || 'ThesisManagement', - chair_url: getEnvironmentVariable('CHAIR_URL') || window.origin, + chair_name: getEnvironmentVariable('CHAIR_NAME') ?? 'ThesisManagement', + chair_url: getEnvironmentVariable('CHAIR_URL') ?? window.origin, environment: parseEnvironment(getEnvironmentVariable('ENVIRONMENT')), - allow_suggested_topics: (getEnvironmentVariable('ALLOW_SUGGESTED_TOPICS') || 'true') === 'true', + allow_suggested_topics: (getEnvironmentVariable('ALLOW_SUGGESTED_TOPICS') ?? 'true') === 'true', - genders: getEnvironmentVariable>('GENDERS', true) || { + genders: getEnvironmentVariable>('GENDERS', true) ?? { MALE: 'Male', FEMALE: 'Female', OTHER: 'Other', PREFER_NOT_TO_SAY: 'Prefer not to say', }, - study_degrees: getEnvironmentVariable>('STUDY_DEGREES', true) || { + study_degrees: getEnvironmentVariable>('STUDY_DEGREES', true) ?? { BACHELOR: 'Bachelor', MASTER: 'Master', }, - study_programs: getEnvironmentVariable>('STUDY_PROGRAMS', true) || { + study_programs: getEnvironmentVariable>('STUDY_PROGRAMS', true) ?? { COMPUTER_SCIENCE: 'Computer Science', INFORMATION_SYSTEMS: 'Information Systems', GAMES_ENGINEERING: 'Games Engineering', MANAGEMENT_AND_TECHNOLOGY: 'Management and Technology', OTHER: 'Other', }, - topic_views_options: getEnvironmentVariable('TOPIC_VIEWS_OPTIONS', true) || { + topic_views_options: getEnvironmentVariable('TOPIC_VIEWS_OPTIONS', true) ?? { OPEN: 'Open Topics', PUBLISHED: 'Published Topics', }, research_groups_location: getEnvironmentVariable>( 'RESEARCH_GROUPS_LOCATION', true, - ) || { + ) ?? { GARCHING: 'Garching', MUNICH: 'Munich', HEILBRONN: 'Heilbronn', WEIHENSTEPHAN: 'Weihenstephan', }, - thesis_types: getEnvironmentVariable('THESIS_TYPES', true) || { + thesis_types: getEnvironmentVariable('THESIS_TYPES', true) ?? { BACHELOR: { long: 'Bachelor Thesis', short: 'BA', @@ -91,19 +91,19 @@ export const GLOBAL_CONFIG: IGlobalConfig = { }, }, - languages: getEnvironmentVariable>('LANGUAGES', true) || { + languages: getEnvironmentVariable>('LANGUAGES', true) ?? { ENGLISH: 'English', GERMAN: 'German', }, - custom_data: getEnvironmentVariable('CUSTOM_DATA', true) || { + custom_data: getEnvironmentVariable('CUSTOM_DATA', true) ?? { GITHUB: { label: 'Github Username', required: false, }, }, - thesis_files: getEnvironmentVariable('THESIS_FILES', true) || { + thesis_files: getEnvironmentVariable('THESIS_FILES', true) ?? { PRESENTATION: { label: 'Presentation', description: 'Presentation (PDF)', @@ -124,14 +124,14 @@ export const GLOBAL_CONFIG: IGlobalConfig = { }, }, - server_host: (getEnvironmentVariable('SERVER_HOST') || 'http://localhost:8180').replace( + server_host: (getEnvironmentVariable('SERVER_HOST') ?? 'http://localhost:8180').replace( /\/+$/, '', ), keycloak: { - host: getEnvironmentVariable('KEYCLOAK_HOST') || 'http://localhost:8181', - realm: getEnvironmentVariable('KEYCLOAK_REALM_NAME') || 'thesis-management', - client_id: getEnvironmentVariable('KEYCLOAK_CLIENT_ID') || 'thesis-management-app', + host: getEnvironmentVariable('KEYCLOAK_HOST') ?? 'http://localhost:8181', + realm: getEnvironmentVariable('KEYCLOAK_REALM_NAME') ?? 'thesis-management', + client_id: getEnvironmentVariable('KEYCLOAK_CLIENT_ID') ?? 'thesis-management-app', }, } diff --git a/client/src/pages/AboutPage/AboutPage.tsx b/client/src/pages/AboutPage/AboutPage.tsx index ae884452f..ff55b5ccf 100644 --- a/client/src/pages/AboutPage/AboutPage.tsx +++ b/client/src/pages/AboutPage/AboutPage.tsx @@ -121,10 +121,10 @@ const AboutPage = () => { Git Information - Branch: {info?.git.branch || 'unknown'} + Branch: {info?.git.branch ?? 'unknown'} - Commit: {info?.git.commit.id || 'unknown'} + Commit: {info?.git.commit.id ?? 'unknown'} diff --git a/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx b/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx index b29a2c5e8..579d70a5f 100644 --- a/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx +++ b/client/src/pages/InterviewBookingPage/InterviewBookingPage.tsx @@ -42,7 +42,7 @@ interface ISlotInformationProps { const SlotInformation = ({ slot, title }: ISlotInformationProps) => ( ( title: 'Location', content: ( - {slot.location || slot.streamUrl || 'Not specified'} + {slot.location ?? slot.streamUrl ?? 'Not specified'} ), icon: , diff --git a/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx b/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx index f36c65808..592db678a 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/CollapsibleDateCard.tsx @@ -231,7 +231,7 @@ const CollapsibleDateCard = ({ duration: s.endDate.getTime() - s.startDate.getTime(), slots: [s], locationType: s.streamUrl ? 'Online' : 'Onsite', - location: s.streamUrl ? s.streamUrl : s.location ? s.location : '', + location: s.streamUrl ?? s.location ?? '', })) // 2) compute ranges only on unscheduled diff --git a/client/src/pages/InterviewTopicOverviewPage/components/DateHeaderItem.tsx b/client/src/pages/InterviewTopicOverviewPage/components/DateHeaderItem.tsx index 7264a2cf0..62a62fdfe 100644 --- a/client/src/pages/InterviewTopicOverviewPage/components/DateHeaderItem.tsx +++ b/client/src/pages/InterviewTopicOverviewPage/components/DateHeaderItem.tsx @@ -32,7 +32,7 @@ export const DateHeaderItem = ({ } return ( - + {new Date(date).toLocaleDateString('en-US', { weekday: 'short' }).toUpperCase()} diff --git a/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx b/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx index 3c18c5a03..4e3480e1e 100644 --- a/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx +++ b/client/src/pages/IntervieweeAssementPage/IntervieweeAssesmentPage.tsx @@ -59,7 +59,7 @@ const IntervieweeAssesmentPage = () => { requiresAuth: true, data: { intervieweeNote: newNote, - score: newScore !== undefined ? newScore : interviewee.score, + score: newScore ?? interviewee.score, }, }, (res) => { diff --git a/client/src/pages/IntervieweeAssementPage/components/InterviewNoteCard.tsx b/client/src/pages/IntervieweeAssementPage/components/InterviewNoteCard.tsx index bc6a991a7..a8292f728 100644 --- a/client/src/pages/IntervieweeAssementPage/components/InterviewNoteCard.tsx +++ b/client/src/pages/IntervieweeAssementPage/components/InterviewNoteCard.tsx @@ -58,7 +58,7 @@ const InterviewNoteCard = ({ interviewNote, onInterviewNoteChange }: IInterviewN { onScoreChange?.(parseInt(value, 10)) }} diff --git a/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx b/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx index ad174c45c..49713c160 100644 --- a/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx +++ b/client/src/pages/ManageTopicsPage/components/ReplaceTopicModal/ReplaceTopicModal.tsx @@ -40,7 +40,7 @@ const ReplaceTopicModal = (props: ICreateTopicModalProps) => { const { topicId, opened, onClose } = props const fetchedTopic = useTopic(opened ? topicId : undefined) - const topic = fetchedTopic === false ? undefined : fetchedTopic || undefined + const topic = fetchedTopic === false ? undefined : (fetchedTopic ?? undefined) const fetchError = fetchedTopic === false && Boolean(topicId) const isTopicLoading = Boolean(topicId) && opened && fetchedTopic === undefined @@ -92,7 +92,7 @@ const ReplaceTopicModal = (props: ICreateTopicModalProps) => { if (opened && topic) { form.setInitialValues({ title: topic.title, - thesisTypes: topic.thesisTypes || [], + thesisTypes: topic.thesisTypes ?? [], problemStatement: topic.problemStatement ?? '', requirements: topic.requirements ?? '', goals: topic.goals ?? '', diff --git a/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx b/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx index 8469ad839..b21f4b38f 100644 --- a/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx +++ b/client/src/pages/PresentationOverviewPage/PresentationOverviewPage.tsx @@ -203,7 +203,7 @@ const PresentationOverviewPage = () => { const onDelete = (presentationId: string, date: string) => { const updatedMap = new Map(presentations) const updatedList = - updatedMap.get(date)?.filter((item) => item.presentationId !== presentationId) || [] + updatedMap.get(date)?.filter((item) => item.presentationId !== presentationId) ?? [] if (updatedList.length === 0) { updatedMap.delete(date) } else { @@ -346,6 +346,7 @@ const PresentationOverviewPage = () => { presentation={p} thesis={p.thesis} hasEditAccess={ + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- `false` must fall through to the next check user?.groups?.includes('admin') || user?.researchGroupId === p.thesis.researchGroup.id || (p.thesis.students ?? []).some( @@ -353,6 +354,7 @@ const PresentationOverviewPage = () => { ) } hasAcceptAccess={ + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- `false` must fall through to the next check user?.groups?.includes('admin') || user?.researchGroupId === p.thesis.researchGroup.id } @@ -399,6 +401,7 @@ const PresentationOverviewPage = () => { presentation={p} thesis={p.thesis} hasEditAccess={ + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- `false` must fall through to the next check user?.groups?.includes('admin') || user?.researchGroupId === p.thesis.researchGroup.id || (p.thesis.students ?? []).some( @@ -406,6 +409,7 @@ const PresentationOverviewPage = () => { ) } hasAcceptAccess={ + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- `false` must fall through to the next check user?.groups?.includes('admin') || user?.researchGroupId === p.thesis.researchGroup.id } diff --git a/client/src/pages/PresentationPage/PresentationPage.tsx b/client/src/pages/PresentationPage/PresentationPage.tsx index 4527d50d5..542343191 100644 --- a/client/src/pages/PresentationPage/PresentationPage.tsx +++ b/client/src/pages/PresentationPage/PresentationPage.tsx @@ -62,7 +62,7 @@ const PresentationPage = () => { - + { - {(user?.groups?.includes('admin') || - user?.researchGroupId === presentation.thesis.researchGroup.id || - (presentation.thesis.students ?? []).some( - (student) => student.userId === user?.userId, - )) && ( - - )} + { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- `false` must fall through to the next check + (user?.groups?.includes('admin') || + user?.researchGroupId === presentation.thesis.researchGroup.id || + (presentation.thesis.students ?? []).some( + (student) => student.userId === user?.userId, + )) && ( + + ) + } ) } diff --git a/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx b/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx index 0e07c2e99..1c6567560 100644 --- a/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx +++ b/client/src/pages/ReplaceApplicationPage/ReplaceApplicationPage.tsx @@ -61,7 +61,7 @@ const ReplaceApplicationPage = () => { { - navigate(`/submit-application/${x?.topicId || ''}`, { replace: true }) + navigate(`/submit-application/${x?.topicId ?? ''}`, { replace: true }) setStep(1) }} /> @@ -77,6 +77,7 @@ const ReplaceApplicationPage = () => { setStep(3)} + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- useTopic may return `false` (error sentinel) which must also map to undefined topic={topic || undefined} application={application} consentToPrivacyPolicy={consentToPrivacyPolicy} diff --git a/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx b/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx index df5b0015e..fa541e3bd 100644 --- a/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx +++ b/client/src/pages/ReplaceApplicationPage/components/MotivationStep/MotivationStep.tsx @@ -36,7 +36,7 @@ const MotivationStep = (props: IMotivationStepProps) => { const [researchGroups, setResearchGroups] = useState>() const [loading, setLoading] = useState(false) - const mergedTopic = application?.topic || topic + const mergedTopic = application?.topic ?? topic const form = useForm({ mode: 'controlled', @@ -193,7 +193,7 @@ const MotivationStep = (props: IMotivationStepProps) => {