From 4167a6058838806de6e0c4b94876f4ead7156ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20G=C3=B3is?= Date: Mon, 2 Oct 2023 13:25:46 +0100 Subject: [PATCH] feat: biome lint frontend (#4903) Follows up on https://github.com/Unleash/unleash/pull/4853 to add Biome to the frontend as well. ![image](https://github.com/Unleash/unleash/assets/14320932/1906faf1-fc29-4172-a4d4-b2716d72cd65) Added a few `biome-ignore` to speed up the process but we may want to check and fix them in the future. --- .gitignore | 1 - .prettierignore | 2 - .vscode/settings.json | 3 + biome.json | 9 +- frontend/.prettierignore | 2 - frontend/.prettierrc | 7 - frontend/cypress.config.ts | 2 +- frontend/cypress.d.ts | 2 +- frontend/cypress/global.d.ts | 22 +- .../cypress/integration/demo/demo.spec.ts | 8 +- .../integration/feature/feature.spec.ts | 12 +- .../cypress/integration/groups/groups.spec.ts | 8 +- .../cypress/integration/import/import.spec.ts | 10 +- .../integration/projects/access.spec.ts | 28 +- .../integration/segments/segments.spec.ts | 2 +- frontend/cypress/support/API.ts | 18 +- frontend/cypress/support/UI.ts | 62 +- frontend/cypress/support/commands.ts | 6 +- frontend/cypress/support/e2e.ts | 4 +- frontend/index.js | 2 +- frontend/package.json | 41 +- frontend/src/component/App.tsx | 56 +- frontend/src/component/admin/Admin.tsx | 34 +- frontend/src/component/admin/AdminIndex.tsx | 47 +- .../src/component/admin/AdminRedirect.tsx | 2 +- .../apiToken/ApiTokenDocs/ApiTokenDocs.tsx | 8 +- .../apiToken/ApiTokenForm/ApiTokenForm.tsx | 4 +- .../EnvironmentSelector.tsx | 10 +- .../ProjectSelector/ProjectSelector.tsx | 2 +- .../SelectAllButton/SelectAllButton.tsx | 2 +- .../SelectProjectInput.test.tsx | 14 +- .../SelectProjectInput/SelectProjectInput.tsx | 28 +- .../ApiTokenForm/TokenInfo/TokenInfo.tsx | 6 +- .../TokenTypeSelector/TokenTypeSelector.tsx | 14 +- .../apiToken/ApiTokenForm/useApiTokenForm.ts | 12 +- .../apiToken/ApiTokenPage/ApiTokenPage.tsx | 4 +- .../apiToken/ConfirmToken/ConfirmToken.tsx | 10 +- .../ConfirmToken/UserToken/UserToken.tsx | 6 +- .../CreateApiToken/CreateApiToken.tsx | 16 +- .../ProjectsList/ProjectsList.test.tsx | 6 +- .../apiToken/ProjectsList/ProjectsList.tsx | 2 +- .../src/component/admin/auth/AuthSettings.tsx | 15 +- .../auth/AutoCreateForm/AutoCreateForm.tsx | 30 +- .../admin/auth/GoogleAuth/GoogleAuth.tsx | 60 +- .../admin/auth/OidcAuth/OidcAuth.tsx | 72 +- .../admin/auth/PasswordAuth/PasswordAuth.tsx | 18 +- .../auth/PasswordAuth/PasswordAuthDialog.tsx | 8 +- .../admin/auth/SamlAuth/SamlAuth.tsx | 58 +- .../component/admin/auth/SsoGroupSettings.tsx | 12 +- .../src/component/admin/billing/Billing.tsx | 4 +- .../BillingInformation/BillingInformation.tsx | 6 +- .../BillingPlan/BillingPlan.tsx | 28 +- .../billing/BillingHistory/BillingHistory.tsx | 8 +- .../FlaggedBillingRedirect.tsx | 2 +- .../src/component/admin/cors/CorsForm.tsx | 6 +- .../component/admin/cors/CorsHelpAlert.tsx | 2 +- frontend/src/component/admin/cors/index.tsx | 2 +- .../component/admin/filterAdminRoutes.test.ts | 26 +- .../src/component/admin/filterAdminRoutes.ts | 2 +- .../admin/groups/CreateGroup/CreateGroup.tsx | 20 +- .../admin/groups/EditGroup/EditGroup.tsx | 18 +- .../Group/EditGroupUsers/EditGroupUsers.tsx | 18 +- .../component/admin/groups/Group/Group.tsx | 16 +- .../Group/RemoveGroupUser/RemoveGroupUser.tsx | 6 +- .../admin/groups/GroupForm/GroupForm.tsx | 22 +- .../GroupFormUsersSelect.tsx | 18 +- .../GroupFormUsersTable.tsx | 12 +- .../component/admin/groups/GroupsAdmin.tsx | 8 +- .../groups/GroupsList/GroupCard/GroupCard.tsx | 14 +- .../GroupCardActions/GroupCardActions.tsx | 14 +- .../GroupCardAvatars/GroupCardAvatars.tsx | 6 +- .../GroupsList/GroupEmpty/GroupEmpty.tsx | 6 +- .../admin/groups/GroupsList/GroupsList.tsx | 26 +- .../admin/groups/RemoveGroup/RemoveGroup.tsx | 6 +- .../admin/groups/hooks/useGroupForm.ts | 2 +- .../InstanceStats/InstanceStats.tsx | 30 +- .../instance-privacy/InstancePrivacy.tsx | 2 +- .../InstancePrivacySection.tsx | 4 +- .../component/admin/invoice/InvoiceList.tsx | 12 +- .../admin/maintenance/MaintenanceToggle.tsx | 2 +- .../admin/maintenance/MaintenanceTooltip.tsx | 2 +- .../src/component/admin/maintenance/index.tsx | 2 +- .../component/admin/menu/AdminTabsMenu.tsx | 16 +- .../src/component/admin/network/Network.tsx | 10 +- .../NetworkOverview/NetworkOverview.tsx | 22 +- .../network/NetworkTraffic/NetworkTraffic.tsx | 20 +- .../PermissionAccordion.tsx | 31 +- .../admin/roles/RoleForm/RoleForm.tsx | 26 +- .../admin/roles/RoleForm/useRoleForm.ts | 12 +- .../admin/roles/RoleModal/RoleModal.tsx | 8 +- frontend/src/component/admin/roles/Roles.tsx | 2 +- .../src/component/admin/roles/RolesPage.tsx | 14 +- .../RoleDeleteDialogProjectRole.tsx | 10 +- .../RoleDeleteDialogProjectRoleTable.tsx | 4 +- .../RoleDeleteDialogGroups.tsx | 4 +- .../RoleDeleteDialogRootRole.tsx | 12 +- .../RoleDeleteDialogServiceAccounts.tsx | 4 +- .../RoleDeleteDialogUsers.tsx | 8 +- .../roles/RolesTable/RolesCell/RolesCell.tsx | 2 +- .../admin/roles/RolesTable/RolesTable.tsx | 10 +- .../admin/serviceAccounts/ServiceAccounts.tsx | 2 +- .../ServiceAccountDeleteDialog.tsx | 8 +- .../ServiceAccountModal.tsx | 58 +- .../ServiceAccountCreateTokenDialog.tsx | 10 +- .../ServiceAccountTokens.tsx | 30 +- .../ServiceAccountTokenDialog.tsx | 8 +- .../ServiceAccountTokensCell.tsx | 2 +- .../ServiceAccountsActionsCell.tsx | 55 +- .../ServiceAccountsTable.tsx | 12 +- .../src/component/admin/useAdminRoutes.ts | 6 +- .../ConfirmUserEmail/ConfirmUserEmail.tsx | 6 +- .../ConfirmUserLink/ConfirmUserLink.tsx | 18 +- .../admin/users/CreateUser/CreateUser.tsx | 18 +- .../SeatCostWarning/SeatCostWarning.tsx | 5 +- .../admin/users/EditUser/EditUser.tsx | 8 +- .../admin/users/InviteLink/InviteLink.tsx | 54 +- .../users/InviteLinkBar/InviteLinkBar.tsx | 22 +- .../ConfirmUserEmail/ConfirmUserEmail.tsx | 6 +- .../admin/users/LinkField/LinkField.tsx | 8 +- .../admin/users/UserForm/UserForm.tsx | 16 +- .../src/component/admin/users/UsersAdmin.tsx | 4 +- .../ChangePassword/ChangePassword.tsx | 38 +- .../users/UsersList/DeleteUser/DeleteUser.tsx | 14 +- .../UserLimitWarning/UserLimitWarning.tsx | 7 +- .../UsersList/UserTypeCell/UserTypeCell.tsx | 4 +- .../admin/users/UsersList/UsersList.tsx | 18 +- .../admin/users/hooks/useAddUserForm.ts | 15 +- .../ApplicationEdit/ApplicationEdit.tsx | 15 +- .../ApplicationList/ApplicationList.tsx | 28 +- .../ApplicationUsageCell.test.tsx | 4 +- .../ApplicationUsageCell.tsx | 6 +- .../ApplicationUpdate/ApplicationUpdate.tsx | 36 +- .../ApplicationView/ApplicationView.tsx | 14 +- .../ArchiveTable/ArchiveBatchActions.tsx | 8 +- .../archive/ArchiveTable/ArchiveTable.tsx | 16 +- .../ArchivedFeatureDeleteConfirm.tsx | 14 +- .../FeatureArchivedCell.tsx | 8 +- .../archive/FeaturesArchiveTable.tsx | 4 +- .../archive/ProjectFeaturesArchiveTable.tsx | 4 +- .../src/component/archive/RedirectArchive.tsx | 2 +- .../changeRequest/ChangeRequest.test.tsx | 10 +- .../ChangeRequest/ChangeRequest.test.tsx | 12 +- .../ChangeRequest/ChangeRequest.tsx | 13 +- .../Changes/Change/ChangeActions.tsx | 16 +- .../Changes/Change/ConflictWarning.tsx | 2 +- .../Changes/Change/EditChange.tsx | 16 +- .../EnvironmentStrategyExecutionOrder.tsx | 8 +- .../Changes/Change/FeatureChange.tsx | 6 +- .../Changes/Change/SegmentChange.tsx | 12 +- .../Changes/Change/SegmentChangeDetails.tsx | 4 +- .../Changes/Change/StrategyChange.tsx | 24 +- .../Changes/Change/ToggleStatusChange.tsx | 2 +- .../Change/VariantPatch/VariantDiff.tsx | 2 +- .../Change/hooks/useCurrentStrategy.ts | 8 +- .../Changes/FeatureToggleChanges.tsx | 14 +- .../NameWithChangeInfo.test.tsx | 22 +- .../NameWithChangeInfo/NameWithChangeInfo.tsx | 2 +- .../StrategyTooltipLink.tsx | 2 +- .../ChangeRequestConfirmDialog.tsx | 8 +- .../CopyStrategiesMessage.tsx | 2 +- .../UpdateEnabledMessage.tsx | 2 +- .../ChangeRequestComments/AddCommentField.tsx | 6 +- .../ChangeRequestComment.tsx | 4 +- .../ChangeRequestHeader.tsx | 26 +- .../ChangeRequestOverview.tsx | 26 +- .../ChangeRequestRejectDialog.test.tsx | 4 +- .../ChangeRequestRejectDialog.tsx | 12 +- .../ChangeRequestReviewStatus.styles.ts | 2 +- .../ChangeRequestReviewStatus.tsx | 55 +- .../ChangeRequestApprovals.tsx | 4 +- .../ChangeRequestRejections.tsx | 4 +- .../ChangeRequestReviewer.tsx | 4 +- .../ChangeRequestReviewers.test.tsx | 4 +- .../ChangeRequestReviewers.tsx | 6 +- .../ChangeRequestTimeline.test.tsx | 22 +- .../ChangeRequestTimeline.tsx | 10 +- .../ReviewButton/ReviewButton.tsx | 21 +- .../ChangeRequestPermissions.test.tsx | 36 +- .../ChangeRequestSidebar.tsx | 12 +- .../ChangeRequestTitle.tsx | 18 +- .../EnvironmentChangeRequest.tsx | 30 +- .../EnvironmentChangeRequestTitle.test.tsx | 4 +- .../ReviewChangesHeader.tsx | 2 +- .../ChangeRequestStatusBadge.tsx | 12 +- .../ChangeRequestTitleCell.tsx | 2 +- .../ChangeRequestsTabs.styles.ts | 2 +- .../ChangeRequestsTabs/ChangeRequestsTabs.tsx | 51 +- .../ProjectChangeRequests.tsx | 2 +- .../component/changeRequest/UpdateCount.tsx | 18 +- .../component/changeRequest/changesCount.ts | 2 +- .../AnnouncerElement/AnnouncerElement.tsx | 4 +- .../AnnouncerProvider/AnnouncerProvider.tsx | 2 +- .../component/common/ApiError/ApiError.tsx | 4 +- .../common/ApiTokenTable/ApiTokenTable.tsx | 16 +- .../CopyApiTokenButton/CopyApiTokenButton.tsx | 2 +- .../CreateApiTokenButton.tsx | 2 +- .../RemoveApiTokenButton.tsx | 4 +- .../common/ApiTokenTable/useApiTokenTable.tsx | 6 +- .../AutocompleteBox/AutocompleteBox.styles.ts | 2 +- .../AutocompleteBox/AutocompleteBox.tsx | 8 +- frontend/src/component/common/Badge/Badge.tsx | 10 +- .../common/BreadcrumbNav/BreadcrumbNav.tsx | 10 +- .../common/CheckmarkBadge/CheckMarkBadge.tsx | 2 +- .../ConditionallyRender.tsx | 2 +- .../ConstraintAccordionEdit.tsx | 28 +- .../ConstraintAccordionEditBody.tsx | 74 +- .../DateSingleValue/DateSingleValue.test.tsx | 10 +- .../DateSingleValue/DateSingleValue.tsx | 16 +- .../FreeTextInput/FreeTextInput.tsx | 22 +- .../LegalValueLabel/LegalValueLabel.styles.ts | 2 +- .../LegalValueLabel/LegalValueLabel.tsx | 4 +- .../ResolveInput/ResolveInput.tsx | 26 +- .../RestrictiveLegalValues.test.tsx | 6 +- .../RestrictiveLegalValues.tsx | 18 +- .../SingleLegalValue.test.tsx | 6 +- .../SingleLegalValue/SingleLegalValue.tsx | 16 +- .../SingleValue/SingleValue.tsx | 6 +- .../constraintValidators.ts | 2 +- .../useConstraintInput/useConstraintInput.tsx | 4 +- .../ConstraintAccordionEditHeader.tsx | 14 +- .../CaseSensitiveButton.tsx | 4 +- .../InvertedOperatorButton.tsx | 8 +- .../ConstraintAccordionHeaderActions.tsx | 8 +- .../ConstraintAccordionList.tsx | 36 +- .../ConstraintAccordionView.tsx | 2 +- .../MultipleValues/MultipleValues.tsx | 4 +- .../SingleValue/SingleValue.tsx | 2 +- .../ConstraintAccordionViewHeader.tsx | 2 +- ...raintAccordionViewHeaderMultipleValues.tsx | 2 +- .../ConstraintViewHeaderOperator.tsx | 4 +- .../ConstraintAccordion/ConstraintIcon.tsx | 2 +- .../ConstraintOperatorSelect.tsx | 18 +- .../ConstraintValueSearch.tsx | 14 +- .../common/CreateButton/CreateButton.tsx | 2 +- .../common/DateTimePicker/DateTimePicker.tsx | 10 +- .../common/Dialogue/Dialogue.test.tsx | 2 +- .../component/common/Dialogue/Dialogue.tsx | 4 +- .../common/DividerText/DividerText.tsx | 2 +- .../common/DropdownMenu/DropdownMenu.tsx | 6 +- .../EnvironmentStrategyDialog.tsx | 12 +- .../FavoriteIconButton/FavoriteIconButton.tsx | 8 +- .../FeatureArchiveDialog.test.tsx | 10 +- .../FeatureArchiveDialog.tsx | 16 +- .../component/common/Feedback/Feedback.tsx | 14 +- .../common/FormTemplate/FormTemplate.tsx | 18 +- .../common/GeneralSelect/GeneralSelect.tsx | 6 +- .../src/component/common/GridCol/GridCol.tsx | 2 +- .../src/component/common/GridRow/GridRow.tsx | 4 +- .../component/common/HelpIcon/HelpIcon.tsx | 4 +- .../common/Highlighter/Highlighter.test.tsx | 10 +- .../common/Highlighter/Highlighter.tsx | 7 +- .../common/HtmlTooltip/HtmlTooltip.tsx | 8 +- .../component/common/Input/Input.styles.ts | 2 +- frontend/src/component/common/Input/Input.tsx | 6 +- .../common/InputCaption/InputCaption.tsx | 2 +- .../common/InputListField/InputListField.tsx | 10 +- .../common/InstanceStatus/InstanceStatus.tsx | 6 +- .../InstanceStatus/InstanceStatusBar.test.tsx | 18 +- .../InstanceStatus/InstanceStatusBar.tsx | 16 +- .../component/common/ItemList/ItemList.tsx | 15 +- .../src/component/common/Loader/Loader.tsx | 4 +- .../src/component/common/Mermaid/Mermaid.tsx | 2 +- .../common/MessageBanner/MessageBanner.tsx | 10 +- .../MessageBannerDialog.tsx | 2 +- .../MultipleRoleSelect/MultipleRoleSelect.tsx | 14 +- .../component/common/NotFound/NotFound.tsx | 6 +- .../Notifications/EmptyNotifications.tsx | 2 +- .../common/Notifications/Notification.tsx | 8 +- .../common/Notifications/Notifications.tsx | 28 +- .../Notifications/NotificationsHeader.tsx | 2 +- .../Notifications/NotificationsList.tsx | 2 +- .../OperatorUpgradeAlert.tsx | 8 +- .../common/PageContent/PageContent.styles.ts | 2 +- .../common/PageContent/PageContent.tsx | 6 +- .../common/PageHeader/PageHeader.tsx | 2 +- .../common/PasswordField/PasswordField.tsx | 10 +- .../PercentageCircle/PercentageCircle.tsx | 3 +- .../PermissionButton/PermissionButton.tsx | 16 +- .../PermissionGuard/PermissionGuard.tsx | 6 +- .../PermissionIconButton.tsx | 10 +- .../PermissionSwitch/PermissionSwitch.tsx | 6 +- .../common/PremiumFeature/PremiumFeature.tsx | 22 +- .../PrettifyLargeNumber.test.tsx | 4 +- .../common/Proclamation/Proclamation.tsx | 6 +- .../ResponsiveButton/ResponsiveButton.tsx | 4 +- .../component/common/RoleBadge/RoleBadge.tsx | 4 +- .../RoleDescription/RoleDescription.tsx | 8 +- .../common/RoleSelect/RoleSelect.tsx | 10 +- .../component/common/ScrollTop/ScrollTop.tsx | 2 +- .../component/common/Search/Search.test.tsx | 2 +- .../src/component/common/Search/Search.tsx | 22 +- .../SearchDescription/SearchDescription.tsx | 4 +- .../SearchInstructions/SearchInstructions.tsx | 6 +- .../SearchSuggestions.test.tsx | 26 +- .../SearchSuggestions/SearchSuggestions.tsx | 24 +- .../component/common/Search/useSavedQuery.ts | 2 +- .../common/SegmentItem/SegmentItem.tsx | 10 +- .../common/SidebarModal/SidebarModal.tsx | 6 +- .../StaleDataNotification.tsx | 8 +- .../StrategyItemContainer.test.tsx | 2 +- .../StrategyItemContainer.tsx | 22 +- .../StrategyVariantsUpgradeAlert.tsx | 16 +- .../common/TabNav/TabPanel/TabPanel.tsx | 2 +- .../FavoriteIconHeader/FavoriteIconHeader.tsx | 6 +- .../CellSortable/CellSortable.styles.ts | 4 +- .../CellSortable/CellSortable.tsx | 10 +- .../CellSortable/SortArrow/SortArrow.tsx | 12 +- .../SortableTableHeader.tsx | 4 +- .../component/common/Table/Table/Table.tsx | 4 +- .../common/Table/TableCell/TableCell.tsx | 2 +- .../TablePlaceholder/TablePlaceholder.tsx | 2 +- .../VirtualizedTable/VirtualizedTable.tsx | 12 +- .../Table/cells/ActionCell/ActionCell.tsx | 2 +- .../FavoriteIconCell/FavoriteIconCell.tsx | 10 +- .../FeatureEnvironmentSeenCell.tsx | 2 +- .../cells/FeatureSeenCell/FeatureSeenCell.tsx | 6 +- .../cells/FeatureSeenCell/LastSeenTooltip.tsx | 16 +- .../cells/FeatureTagCell/FeatureTagCell.tsx | 2 +- .../FeatureTypeCell/FeatureTypeCell.styles.ts | 2 +- .../cells/FeatureTypeCell/FeatureTypeCell.tsx | 4 +- .../cells/HighlightCell/HighlightCell.tsx | 4 +- .../common/Table/cells/LinkCell/LinkCell.tsx | 8 +- .../common/Table/cells/RoleCell/RoleCell.tsx | 2 +- .../common/Table/cells/TextCell/TextCell.tsx | 4 +- .../Table/cells/TimeAgoCell/TimeAgoCell.tsx | 4 +- .../ToastRenderer/Toast/Toast.styles.ts | 2 +- .../common/ToastRenderer/Toast/Toast.tsx | 5 +- .../common/ToastRenderer/ToastRenderer.tsx | 4 +- .../common/TooltipLink/TooltipLink.tsx | 2 +- .../common/UpdateButton/UpdateButton.tsx | 2 +- .../common/UserAvatar/UserAvatar.tsx | 4 +- .../VariantInfoAlert/VariantInfoAlert.tsx | 2 +- .../VerticalTabs/VerticalTab/VerticalTab.tsx | 2 +- .../common/VerticalTabs/VerticalTabs.tsx | 4 +- frontend/src/component/common/index.jsx | 24 +- frontend/src/component/common/select.tsx | 4 +- frontend/src/component/common/util.test.ts | 12 +- frontend/src/component/common/util.ts | 16 +- .../ContectFormChip/ContextFormChip.tsx | 2 +- .../ContextFieldUsage.test.tsx | 4 +- .../ContextFieldUsage/ContextFieldUsage.tsx | 23 +- .../context/ContextForm/ContextForm.tsx | 54 +- .../context/ContextList/AddContextButton.tsx | 8 +- .../ContextList/ContextActionsCell.tsx | 4 +- .../ContextList/ContextList.test.tsx | 2 +- .../ContextList/ContextList/ContextList.tsx | 28 +- .../CreateUnleashContext.tsx | 18 +- .../context/EditContext/EditContext.tsx | 14 +- .../component/context/hooks/useContextForm.ts | 8 +- frontend/src/component/demo/Demo.tsx | 10 +- .../component/demo/DemoBanner/DemoBanner.tsx | 12 +- .../component/demo/DemoDialog/DemoDialog.tsx | 2 +- .../DemoDialogFinish/DemoDialogFinish.tsx | 12 +- .../DemoDialogPlans/DemoDialogPlans.tsx | 58 +- .../DemoDialogWelcome/DemoDialogWelcome.tsx | 22 +- .../DemoStepTooltip/DemoStepTooltip.tsx | 20 +- .../component/demo/DemoSteps/DemoSteps.tsx | 22 +- .../component/demo/DemoTopics/DemoTopics.tsx | 22 +- frontend/src/component/demo/demo-setup.ts | 46 +- frontend/src/component/demo/demo-topics.tsx | 120 +- .../CreateEnvironment/CreateEnvironment.tsx | 26 +- .../CreateEnvironmentButton.tsx | 4 +- .../EditEnvironment/EditEnvironment.tsx | 12 +- .../EnvironmentForm/EnvironmentForm.tsx | 6 +- .../EnvironmentTypeSelector.tsx | 18 +- .../EnvironmentActionCellPopover.tsx | 14 +- .../EnvironmentCloneModal.tsx | 53 +- .../EnvironmentProjectSelect.tsx | 20 +- .../EnvironmentDeleteDialog.tsx | 12 +- .../EnvironmentDeprecateToggleDialog.tsx | 6 +- .../EnvironmentTokenDialog.tsx | 10 +- .../EnvironmentIconCell.tsx | 6 +- .../EnvironmentNameCell.tsx | 8 +- .../EnvironmentRow/EnvironmentRow.tsx | 4 +- .../EnvironmentTable/EnvironmentTable.tsx | 12 +- .../EnvironmentTableSingle.tsx | 12 +- .../environments/hooks/useEnvironmentForm.ts | 4 +- .../component/events/EventCard/EventCard.tsx | 2 +- .../events/EventDiff/EventDiff.test.tsx | 6 +- .../component/events/EventDiff/EventDiff.tsx | 1 + .../component/events/EventLog/EventLog.tsx | 16 +- .../component/events/EventPage/EventPage.tsx | 2 +- .../feature/CopyFeature/CopyFeature.tsx | 24 +- .../feature/CreateFeature/CreateFeature.tsx | 20 +- .../CreateFeatureButton.tsx | 6 +- .../AddDependencyDialogue.test.tsx | 18 +- .../Dependencies/AddDependencyDialogue.tsx | 9 +- .../feature/EditFeature/EditFeature.tsx | 14 +- .../feature/FeatureForm/FeatureForm.tsx | 41 +- .../FeatureNamingPatternInfo.tsx | 2 +- .../FeatureStrategyConstraints.tsx | 6 +- .../FeatureStrategyCreate.test.tsx | 4 +- .../FeatureStrategyCreate.tsx | 16 +- .../FeatureStrategyEdit.test.tsx | 4 +- .../FeatureStrategyEdit.tsx | 24 +- .../CopyButton/CopyButton.tsx | 16 +- .../FeatureStrategyEmpty.tsx | 22 +- .../FeatureStrategyChangeRequestAlert.tsx | 2 +- .../FeatureStrategyEnabled.tsx | 6 +- .../FeatureStrategyEnabledDisabled.tsx | 4 +- .../FeatureStrategyForm.tsx | 34 +- .../FeatureStrategyTitle.tsx | 10 +- .../FeatureStrategyIcons.tsx | 10 +- .../FeatureStrategyMenu.tsx | 12 +- .../FeatureStrategyMenuCard.tsx | 4 +- .../FeatureStrategyMenuCards.tsx | 14 +- .../FeatureStrategyProdGuard.tsx | 14 +- .../FeatureStrategySegment.tsx | 18 +- .../FeatureStrategySegmentChip.tsx | 24 +- .../FeatureStrategyType.tsx | 4 +- .../FeatureStrategy/featureStrategy.utils.ts | 2 +- .../BulkDisableDialog.test.tsx | 10 +- .../FeatureToggleList/BulkDisableDialog.tsx | 24 +- .../BulkEnableDialog.test.tsx | 10 +- .../FeatureToggleList/BulkEnableDialog.tsx | 24 +- .../FeatureToggleList/ExportDialog.tsx | 10 +- .../FeatureStaleCell/FeatureStaleCell.tsx | 4 +- .../FeatureToggleListTable.tsx | 34 +- .../FeatureEnvironmentSeen.tsx | 6 +- .../FeatureView/FeatureLog/FeatureLog.tsx | 2 +- .../FeatureMetrics/FeatureMetrics.tsx | 18 +- .../FeatureMetricsChart.tsx | 6 +- .../FeatureMetricsChart/createChartData.ts | 12 +- .../createChartOptions.tsx | 14 +- .../FeatureMetricsChips.tsx | 2 +- .../FeatureMetricsContent.tsx | 8 +- .../FeatureMetricsHours.tsx | 6 +- .../FeatureMetricsStats.tsx | 4 +- .../FeatureMetricsTable.tsx | 12 +- .../FeatureNotFound/FeatureNotFound.tsx | 2 +- .../FeatureOverview/FeatureOverview.tsx | 8 +- .../EnvironmentAccordionBody.tsx | 22 +- .../StrategyDraggableItem.tsx | 12 +- .../CopyStrategyIconMenu.tsx | 22 +- .../DialogStrategyRemove.tsx | 47 +- .../DisableEnableStrategyDialog.test.tsx | 6 +- .../DisableEnableStrategyDialog.tsx | 4 +- .../hooks/useEnableDisable.ts | 2 +- .../MenuStrategyRemove/MenuStrategyRemove.tsx | 16 +- .../ConstraintItem/ConstraintItem.tsx | 2 +- .../StrategyExecution/StrategyExecution.tsx | 57 +- .../StrategyItem/StrategyItem.tsx | 4 +- .../useStrategyChangeFromRequest.tsx | 8 +- .../FeatureOverviewEnvironment.tsx | 32 +- .../FeatureOverviewEnvironmentMetrics.tsx | 2 +- .../FeatureOverviewEnvironments.tsx | 2 +- .../FeatureOverviewMetaData.tsx | 6 +- .../FeatureOverviewSegment.tsx | 2 +- .../FeatureOverviewSidePanel.tsx | 6 +- .../ChildrenTooltip.tsx | 2 +- .../DependencyActions.tsx | 10 +- .../DependencyRow.tsx | 1 - .../FeatureOverviewSidePanelDetails.test.tsx | 14 +- .../FeatureOverviewSidePanelDetails.tsx | 4 +- .../EnableEnvironmentDialog.tsx | 16 +- ...atureOverviewSidePanelEnvironmentHider.tsx | 2 +- ...tureOverviewSidePanelEnvironmentSwitch.tsx | 2 +- ...reOverviewSidePanelEnvironmentSwitches.tsx | 10 +- .../FeatureOverviewSidePanelTags.tsx | 14 +- .../ManageTagsDialog/ManageBulkTagsDialog.tsx | 38 +- .../ManageTagsDialog/ManageTagsDialog.tsx | 52 +- .../ManageTagsDialog/TagTypeSelect.tsx | 14 +- .../ManageTagsDialog/TagsInput.tsx | 40 +- .../FeatureSettings/FeatureSettings.tsx | 4 +- .../FeatureTypeSelect/FeatureTypeSelect.tsx | 4 +- .../FeatureProjectSelect.tsx | 6 +- .../FeatureSettingsProject.tsx | 12 +- .../FeatureSettingsProjectConfirm.tsx | 46 +- .../EnvironmentVariantsCard.tsx | 10 +- .../EnvironmentVariantsTable.tsx | 20 +- .../EnvironmentVariantsCopyFrom.tsx | 12 +- .../EnvironmentVariantsModal.tsx | 86 +- .../VariantForm/ReactJSONEditor.tsx | 6 +- .../VariantForm/VariantForm.tsx | 94 +- .../VariantOverrides/VariantOverrides.tsx | 42 +- .../VariantOverrides/useOverrides.test.ts | 14 +- .../VariantOverrides/useOverrides.ts | 12 +- .../FeatureEnvironmentVariants.tsx | 56 +- .../PermissionCheckboxMenuItem.tsx | 29 +- .../PushVariantsButton/PushVariantsButton.tsx | 36 +- .../VariantsTooltipWarning.tsx | 6 +- .../feature/FeatureView/FeatureView.tsx | 21 +- .../RedirectFeatureView.tsx | 2 +- .../FlexibleStrategy/FlexibleStrategy.tsx | 24 +- .../StickinessSelect/StickinessSelect.tsx | 18 +- .../GeneralStrategy/GeneralStrategy.tsx | 1 + .../RolloutSlider/RolloutSlider.tsx | 14 +- .../SplitPreviewSlider/SplitPreviewSlider.tsx | 24 +- .../StrategyInputList/StrategyInputList.tsx | 28 +- .../StrategyParameter/StrategyParameter.tsx | 14 +- .../StrategyTypes/StrategyVariants.test.tsx | 2 +- .../StrategyTypes/StrategyVariants.tsx | 42 +- .../UserWithIdStrategy/UserWithId.tsx | 2 +- .../component/feature/hooks/useFeatureForm.ts | 8 +- .../FeatureTypeEdit/FeatureTypeEdit.tsx | 2 +- .../FeatureTypeForm/FeatureTypeForm.test.tsx | 12 +- .../FeatureTypeForm/FeatureTypeForm.tsx | 50 +- .../featureTypes/FeatureTypesList.tsx | 34 +- .../feedback/FeedbackCES/FeedbackCES.tsx | 4 +- .../FeedbackCES/FeedbackCESForm.test.tsx | 2 +- .../feedback/FeedbackCES/FeedbackCESForm.tsx | 16 +- .../feedback/FeedbackCES/FeedbackCESScore.tsx | 10 +- .../feedback/FeedbackCES/sendFeedbackInput.ts | 4 +- .../FeedbackCESProvider.tsx | 8 +- .../FeedbackCESContext/useFeedbackCESSeen.ts | 6 +- .../feedback/FeedbackNPS/FeedbackNPS.tsx | 18 +- .../feedback/FeedbackNPS/showNPSFeedback.ts | 4 +- .../AddonRedirect/AddonRedirect.tsx | 2 +- .../CreateIntegration/CreateIntegration.tsx | 2 +- .../EditIntegration/EditIntegration.tsx | 4 +- .../IntegrationDelete/IntegrationDelete.tsx | 10 +- .../IntegrationForm.styles.tsx | 8 +- .../IntegrationForm/IntegrationForm.tsx | 88 +- .../IntegrationInstall/IntegrationInstall.tsx | 8 +- .../IntegrationMultiSelector.test.tsx | 2 +- .../IntegrationMultiSelector.tsx | 16 +- .../IntegrationParameterTextField.tsx | 8 +- .../IntegrationParameters.tsx | 2 +- .../IntegrationStateSwitch.tsx | 6 +- .../IntegrationHowToSection.tsx | 6 +- .../AvailableIntegrations.tsx | 86 +- .../ConfiguredIntegrations.tsx | 8 +- .../IntegrationCard/IntegrationCard.tsx | 10 +- .../IntegrationCardMenu.tsx | 14 +- .../IntegrationIcon/IntegrationIcon.tsx | 4 +- .../IntegrationList.styles.tsx | 2 +- .../RequestIntegrationCard.tsx | 10 +- .../EdgeIntegration/EdgeIntegration.tsx | 52 +- .../JiraIntegration/JiraIntegration.tsx | 10 +- .../ViewIntegration/ViewIntegration.tsx | 2 +- frontend/src/component/layout/Error/Error.tsx | 13 +- .../MainLayout/DraftBanner/DraftBanner.tsx | 16 +- .../layout/MainLayout/MainLayout.tsx | 10 +- .../component/loginHistory/LoginHistory.tsx | 2 +- .../LoginHistorySuccessfulCell.tsx | 43 +- .../LoginHistoryTable/LoginHistoryTable.tsx | 12 +- .../menu/Footer/ApiDetails/ApiDetails.tsx | 2 +- .../Footer/ApiDetails/apidetails.helpers.tsx | 2 +- .../src/component/menu/Footer/Footer.test.tsx | 4 +- frontend/src/component/menu/Footer/Footer.tsx | 142 +- .../menu/Header/DrawerMenu/DrawerMenu.tsx | 22 +- frontend/src/component/menu/Header/Header.tsx | 46 +- .../Header/NavigationLink/NavigationLink.tsx | 4 +- .../Header/NavigationMenu/NavigationMenu.tsx | 9 +- frontend/src/component/menu/routes.ts | 12 +- .../Playground/AdvancedPlayground.test.tsx | 16 +- .../Playground/AdvancedPlayground.tsx | 25 +- .../AdvancedPlaygroundEnvironmentCell.tsx | 10 +- .../AdvancedPlaygroundEnvironmentDiffCell.tsx | 4 +- .../AdvancedPlaygroundResultsTable.test.tsx | 2 +- .../AdvancedPlaygroundResultsTable.tsx | 10 +- .../combinationCounter.test.ts | 12 +- .../combinationCounter.ts | 9 +- .../PlaygroundEnvironmentDiffTable.test.tsx | 2 +- .../PlaygroundEnvironmentDiffTable.tsx | 16 +- .../PlaygroundEnvironmentTable.test.tsx | 2 +- .../PlaygroundEnvironmentTable.tsx | 10 +- .../PlaygroundCodeFieldset.tsx | 64 +- .../PlaygroundEditor/PlaygroundEditor.tsx | 16 +- .../PlaygroundConnectionFieldset.tsx | 26 +- .../PlaygroundForm/PlaygroundForm.tsx | 10 +- .../PlaygroundForm/renderOption.tsx | 6 +- .../PlaygroundGuidance/PlaygroundGuidance.tsx | 24 +- .../PlaygroundGuidanceSection.tsx | 63 +- .../PlaygroundGuidancePopper.tsx | 4 +- .../FeatureDetails/FeatureDetails.tsx | 10 +- .../FeatureDetails/helpers.ts | 10 +- .../FeatureResultInfoPopoverCell.tsx | 2 +- .../PlaygroundResultFeatureStrategyList.tsx | 2 +- .../ConstraintError/ConstraintError.tsx | 2 +- .../ConstraintExecution.tsx | 2 +- .../ConstraintOk/ConstraintOk.tsx | 2 +- .../CustomParameterItem.tsx | 14 +- .../CustomStrategyParams.tsx | 22 +- .../PlaygroundParameterItem.tsx | 8 +- .../SegmentExecution.styles.ts | 2 +- .../SegmentExecution/SegmentExecution.tsx | 4 +- .../StrategyExecution/StrategyExecution.tsx | 5 +- .../StrategyExecutionParameters.tsx | 42 +- .../playgroundResultStrategyLists.tsx | 2 +- .../PlaygroundResultChip.tsx | 12 +- .../VariantInformation/VariantInformation.tsx | 38 +- .../playground/Playground/playground.utils.ts | 14 +- .../Project/CreateProject/CreateProject.tsx | 16 +- .../DeleteProject/DeleteProjectDialogue.tsx | 2 +- .../Project/EditProject/EditProject.tsx | 14 +- .../project/Project/Import/ImportModal.tsx | 2 +- .../project/Project/Import/ImportTimeline.tsx | 14 +- .../project/Project/Import/PulsingAvatar.tsx | 2 +- .../Import/configure/ConfigurationStage.tsx | 30 +- .../Import/configure/ImportOptions.tsx | 2 +- .../Project/Import/import/ImportStage.tsx | 16 +- .../Import/validate/ValidationStage.tsx | 28 +- .../project/Project/Project.styles.ts | 2 +- .../src/component/project/Project/Project.tsx | 44 +- .../ProjectDoraFeedback.tsx | 32 +- .../ProjectDoraMetrics/ProjectDoraMetrics.tsx | 28 +- .../ActionsCell/ActionsCell.tsx | 14 +- .../ColumnsMenu/ColumnsMenu.tsx | 32 +- .../FeatureToggleSwitch.tsx | 26 +- .../hooks/useOptimisticUpdate.test.ts | 8 +- .../ProjectFeatureToggles.styles.ts | 2 +- .../ProjectFeatureToggles.tsx | 78 +- .../ArchiveButton.tsx | 12 +- .../ManageTags.tsx | 16 +- .../MoreActions.tsx | 16 +- .../ProjectFeaturesBatchActions.tsx | 22 +- .../hooks/useEnvironmentsRef.ts | 6 +- .../Project/ProjectForm/ProjectForm.tsx | 83 +- .../validate-feature-naming.test.ts | 6 +- .../Project/ProjectHealth/ProjectHealth.tsx | 2 +- .../ReportTable/ReportCard/ReportCard.tsx | 2 +- .../ReportExpiredCell/ReportExpiredCell.tsx | 2 +- .../ReportExpiredCell/formatExpiredAt.ts | 2 +- .../ReportStatusCell/formatStatus.ts | 2 +- .../ProjectHealth/ReportTable/ReportTable.tsx | 14 +- .../ProjectInfo/ChangeRequestsWidget.tsx | 16 +- .../Project/ProjectInfo/HealthWidget.tsx | 2 +- .../Project/ProjectInfo/MetaWidget.tsx | 12 +- .../Project/ProjectInfo/ToggleTypesWidget.tsx | 21 +- .../Project/ProjectInfo/WidgetFooterLink.tsx | 6 +- .../project/Project/ProjectLog/ProjectLog.tsx | 6 +- .../ChangeRequestConfiguration.tsx | 8 +- .../ChangeRequestProcessHelp.tsx | 177 +- .../ChangeRequestTable.tsx | 36 +- .../CreateProjectApiTokenForm.tsx | 16 +- .../ProjectApiAccess/ProjectApiAccess.tsx | 10 +- .../ProjectDefaultStrategySettings.tsx | 12 +- .../ProjectEnvironment/ProjectEnvironment.tsx | 10 +- .../EditDefaultStrategy.test.tsx | 2 +- .../EditDefaultStrategy.tsx | 20 +- .../ProjectDefaultStrategyForm.tsx | 26 +- .../ProjectEnvironmentDefaultStrategy.tsx | 4 +- .../ProjectSegments/ProjectSegments.tsx | 14 +- .../ProjectSettings/ProjectSettings.tsx | 18 +- .../ProjectSettings/Settings/EditProject.tsx | 16 +- .../ProjectSettings/Settings/Settings.tsx | 8 +- .../Project/ProjectStats/HelpPopper.tsx | 18 +- .../Project/ProjectStats/ProjectStats.tsx | 16 +- .../project/Project/hooks/useProjectForm.ts | 16 +- .../project/ProjectAccess/ProjectAccess.tsx | 8 +- .../ProjectAccessAssign.tsx | 62 +- .../ProjectAccessEditGroup.tsx | 4 +- .../ProjectAccessEditUser.tsx | 4 +- .../ProjectAccessTable/ProjectAccessTable.tsx | 22 +- .../ProjectGroupView/ProjectGroupView.tsx | 10 +- .../project/ProjectCard/ProjectCard.tsx | 10 +- .../EnvironmentHideDialog.tsx | 12 +- .../ProjectEnvironmentTableSingle.tsx | 10 +- .../ProjectEnvironment/ProjectEnvironment.tsx | 28 +- .../project/ProjectList/ProjectList.tsx | 20 +- .../AccessProvider/AccessProvider.tsx | 16 +- .../AccessProvider/AccessProviderMock.tsx | 2 +- .../PlausibleProvider/PlausibleProvider.tsx | 4 +- .../providers/UIProvider/UIProvider.tsx | 6 +- .../segments/CreateSegment/CreateSegment.tsx | 14 +- .../segments/EditSegment/EditSegment.tsx | 10 +- .../EditSegmentButton/EditSegmentButton.tsx | 2 +- .../SegmentDeleteConfirm.tsx | 8 +- .../SegmentDeleteUsedSegment.tsx | 10 +- .../src/component/segments/SegmentDocs.tsx | 24 +- .../src/component/segments/SegmentEmpty.tsx | 2 +- .../segments/SegmentFormStepList.tsx | 4 +- .../component/segments/SegmentFormStepOne.tsx | 30 +- .../component/segments/SegmentFormStepTwo.tsx | 16 +- .../segments/SegmentProjectAlert.tsx | 19 +- .../SegmentTable/SegmentTable.test.tsx | 2 +- .../segments/SegmentTable/SegmentTable.tsx | 18 +- .../segments/hooks/useSegmentForm.ts | 4 +- .../segments/hooks/useSegmentValuesCount.ts | 2 +- .../splash/SplashPage/SplashPage.tsx | 2 +- .../component/splash/SplashPageOperators.tsx | 16 +- .../SplashPageRedirect/SplashPageRedirect.tsx | 2 +- .../CreateStrategy/CreateStrategy.tsx | 14 +- .../CustomStrategyInfo/CustomStrategyInfo.tsx | 10 +- .../strategies/EditStrategy/EditStrategy.tsx | 10 +- .../AddStrategyButton/AddStrategyButton.tsx | 4 +- .../StrategiesList/StrategiesList.tsx | 60 +- .../StrategyDeleteButton.tsx | 4 +- .../StrategyEditButton/StrategyEditButton.tsx | 4 +- .../strategies/StrategyForm/StrategyForm.tsx | 22 +- .../StrategyParameter/StrategyParameter.tsx | 18 +- .../StrategyParameters/StrategyParameters.tsx | 3 +- .../StrategyDetails/StrategyDetails.tsx | 4 +- .../strategies/StrategyView/StrategyView.tsx | 6 +- .../TogglesLinkList/TogglesLinkList.tsx | 4 +- .../strategies/hooks/useStrategyForm.ts | 10 +- .../tags/CreateTagType/CreateTagType.tsx | 16 +- .../tags/EditTagType/EditTagType.tsx | 10 +- .../tags/TagTypeForm/TagTypeForm.tsx | 10 +- .../tags/TagTypeForm/useTagTypeForm.ts | 6 +- .../AddTagTypeButton/AddTagTypeButton.tsx | 2 +- .../tags/TagTypeList/TagTypeList.tsx | 20 +- .../__tests__/TagTypeList.test.tsx | 2 +- .../Authentication/Authentication.test.tsx | 10 +- .../user/Authentication/Authentication.tsx | 2 +- .../user/AuthenticationCustomComponent.tsx | 4 +- .../src/component/user/DemoAuth/DemoAuth.tsx | 36 +- .../ForgottenPassword/ForgottenPassword.tsx | 30 +- frontend/src/component/user/HostedAuth.tsx | 46 +- frontend/src/component/user/Login/Login.tsx | 4 +- .../user/Login/parseRedirectParam.test.ts | 4 +- .../user/Login/parseRedirectParam.ts | 2 +- .../src/component/user/NewUser/NewUser.tsx | 36 +- .../NewUser/NewUserWrapper/NewUserWrapper.tsx | 7 +- frontend/src/component/user/PasswordAuth.tsx | 48 +- .../Profile/PasswordTab/PasswordTab.test.tsx | 4 +- .../user/Profile/PasswordTab/PasswordTab.tsx | 34 +- .../CreatePersonalAPIToken.tsx | 28 +- .../PersonalAPITokenForm.tsx | 36 +- .../DeletePersonalAPIToken.tsx | 6 +- .../PersonalAPITokenDialog.tsx | 8 +- .../PersonalAPITokensTab.tsx | 22 +- .../user/Profile/ProfileTab/ProfileTab.tsx | 36 +- .../user/ResetPassword/ResetPassword.tsx | 2 +- .../component/user/SimpleAuth/SimpleAuth.tsx | 28 +- .../src/component/user/StandaloneBanner.tsx | 6 +- .../user/UserProfile/UserProfile.tsx | 4 +- .../UserProfileContent/UserProfileContent.tsx | 26 +- .../user/common/AuthOptions/AuthOptions.tsx | 10 +- .../user/common/InvalidToken/InvalidToken.tsx | 22 +- .../ResetPasswordError/ResetPasswordError.tsx | 2 +- .../ResetPasswordForm/PasswordChecker.tsx | 14 +- .../ResetPasswordForm/PasswordMatcher.tsx | 4 +- .../ResetPasswordForm/ResetPasswordForm.tsx | 14 +- .../user/common/SecondaryLoginActions.tsx | 12 +- .../user/common/StandaloneLayout.tsx | 2 +- frontend/src/contexts/AccessContext.ts | 2 +- .../useAccessOverviewApi.tsx | 2 +- .../api/actions/useAddonsApi/useAddonsApi.ts | 2 +- .../actions/useAdminUsersApi/errorHandlers.ts | 16 +- .../useAdminUsersApi/useAdminUsersApi.ts | 10 +- .../src/hooks/api/actions/useApi/useApi.ts | 20 +- .../useApiTokensApi/useApiTokensApi.ts | 16 +- .../useApplicationsApi/useApplicationsApi.ts | 17 +- .../api/actions/useAuthApi/useAuthApi.tsx | 2 +- .../useAuthFeedbackApi/useAuthFeedbackApi.ts | 6 +- .../useAuthResetPasswordApi.ts | 2 +- .../useAuthSettingsApi/useAuthSettingsApi.ts | 8 +- .../useChangeRequestApi.ts | 69 +- .../actions/useContextsApi/useContextsApi.ts | 31 +- .../useDependentFeaturesApi.ts | 10 +- .../useEnvironmentApi/useEnvironmentApi.ts | 80 +- .../api/actions/useExportApi/useExportApi.ts | 18 +- .../useFavoriteFeaturesApi.ts | 8 +- .../useFavoriteProjectsApi.ts | 8 +- .../actions/useFeatureApi/useFeatureApi.ts | 165 +- .../useFeatureStrategyApi.ts | 20 +- .../useFeatureTypeApi/useFeatureTypeApi.ts | 9 +- .../api/actions/useGroupApi/useGroupApi.ts | 25 +- .../useInviteTokenApi/useInviteTokenApi.ts | 6 +- .../useLoginHistoryApi/useLoginHistoryApi.ts | 2 +- .../useMaintenanceApi/useMaintenanceApi.ts | 7 +- .../useNotificationsApi.ts | 6 +- .../actions/usePasswordApi/usePasswordApi.ts | 7 +- .../usePersonalAPITokensApi.ts | 18 +- .../actions/usePlayground/usePlayground.ts | 13 +- .../actions/useProjectApi/useProjectApi.ts | 67 +- .../useProjectApiTokensApi.ts | 16 +- .../api/actions/useRolesApi/useRolesApi.ts | 8 +- .../actions/useSegmentsApi/useSegmentsApi.ts | 2 +- .../useServiceAccountTokensApi.ts | 24 +- .../useServiceAccountsApi.ts | 10 +- .../useStrategiesApi/useStrategiesApi.ts | 42 +- .../hooks/api/actions/useTagApi/useTagApi.ts | 14 +- .../actions/useTagTypesApi/useTagTypesApi.ts | 30 +- .../actions/useUiConfigApi/useUiConfigApi.ts | 4 +- .../useValidateImportApi.ts | 11 +- .../api/getters/httpErrorResponseHandler.ts | 2 +- .../hooks/api/getters/useAccess/useAccess.ts | 8 +- .../getters/useAdminCount/useAdminCount.ts | 4 +- .../api/getters/useApiGetter/useApiGetter.ts | 2 +- .../getters/useApplication/useApplication.ts | 4 +- .../useApplications/useApplications.ts | 4 +- .../api/getters/useAuth/useAuthEndpoint.ts | 4 +- .../api/getters/useAuth/useAuthPermissions.ts | 4 +- .../useChangeRequest/useChangeRequest.ts | 4 +- .../useChangeRequestConfig.ts | 4 +- .../useConditionalSWR/useConditionalSWR.ts | 2 +- .../useConstraintsValidation.test.tsx | 2 +- .../useConstraintsValidation.ts | 6 +- .../api/getters/useContext/useContext.ts | 2 +- .../useDefaultProject/useDefaultProjectId.ts | 2 +- .../useEnterpriseSWR/useEnterpriseSWR.ts | 4 +- .../getters/useEnvironment/useEnvironment.ts | 2 +- .../useEnvironments/useEnvironments.ts | 6 +- .../getters/useEventSearch/useEventSearch.ts | 8 +- .../api/getters/useFeature/useFeature.ts | 10 +- .../getters/useFeature/useFeatureImmutable.ts | 4 +- .../useFeatureMetrics/useFeatureMetrics.ts | 6 +- .../useFeatureMetricsRaw.ts | 8 +- .../getters/useFeatureTags/useFeatureTags.ts | 2 +- .../api/getters/useFeatures/useFeatures.ts | 4 +- .../useFeaturesArchive/useFeaturesArchive.ts | 8 +- .../hooks/api/getters/useGroup/useGroup.ts | 8 +- .../hooks/api/getters/useGroups/useGroups.ts | 6 +- .../useHealthReport/useHealthReport.ts | 6 +- .../useInstanceMetrics/useInstanceMetrics.ts | 8 +- .../useInstanceStats/useInstanceStats.ts | 6 +- .../useInstanceStatus/useInstanceStatus.ts | 4 +- .../useInviteTokens/useInviteTokens.ts | 4 +- .../api/getters/useInvoices/useInvoices.ts | 2 +- .../useLoginHistory/useLoginHistory.ts | 6 +- .../getters/useMaintenance/useMaintenance.ts | 6 +- .../useNotifications/useNotifications.ts | 2 +- .../useParentOptions/useParentOptions.ts | 4 +- .../usePendingChangeRequests.ts | 4 +- .../usePendingChangeRequestsForFeature.ts | 8 +- .../getters/usePermissions/usePermissions.ts | 4 +- .../usePersonalAPITokens.ts | 4 +- .../api/getters/useProfile/useProfile.ts | 4 +- .../getters/useProject/getProjectFetcher.ts | 2 +- .../useProjectAccess/useProjectAccess.ts | 8 +- .../useProjectApiTokens.ts | 4 +- .../useProjectChangeRequests.ts | 6 +- .../useProjectDoraMetrics.ts | 4 +- .../useProjectEnvironments.ts | 6 +- .../useProjectRoleAccessUsage.ts | 6 +- .../api/getters/useProjects/useProjects.ts | 4 +- .../useResetPassword/useResetPassword.ts | 2 +- .../src/hooks/api/getters/useRole/useRole.ts | 8 +- .../hooks/api/getters/useRoles/useRoles.ts | 6 +- .../api/getters/useSegment/useSegment.ts | 2 +- .../useSegmentValidation.ts | 4 +- .../api/getters/useSegments/useSegments.ts | 4 +- .../useServiceAccountTokens.ts | 6 +- .../useServiceAccounts/useServiceAccounts.ts | 6 +- .../getters/useStrategies/useStrategies.ts | 2 +- .../useStrategiesByContext.ts | 6 +- .../useStrategiesBySegment.ts | 6 +- .../api/getters/useStrategy/useStrategy.ts | 6 +- .../api/getters/useTagType/useTagType.ts | 2 +- .../src/hooks/api/getters/useTags/useTags.ts | 2 +- .../api/getters/useTelemetry/useTelemetry.ts | 6 +- .../api/getters/useUiConfig/useUiConfig.ts | 4 +- .../useUnleashContext/useUnleashContext.ts | 6 +- .../api/getters/useUserInfo/useUserInfo.ts | 4 +- .../getters/useUserInvite/useUserInvite.ts | 4 +- .../hooks/api/getters/useUsers/useUsers.ts | 6 +- .../src/hooks/useChangeRequestAddStrategy.ts | 16 +- .../hooks/useChangeRequestInReviewWarning.tsx | 8 +- frontend/src/hooks/useChangeRequestToggle.ts | 18 +- .../hooks/useChangeRequestsEnabled.test.tsx | 6 +- .../src/hooks/useChangeRequestsEnabled.ts | 12 +- frontend/src/hooks/useCollaborateData.tsx | 2 +- .../hooks/useConditionallyHiddenColumns.ts | 12 +- .../src/hooks/useDefaultProjectSettings.ts | 2 +- frontend/src/hooks/useDragItem.ts | 10 +- frontend/src/hooks/useEventSettings.ts | 2 +- frontend/src/hooks/useFormErrors.ts | 16 +- frontend/src/hooks/useGlobalLocalStorage.ts | 2 +- frontend/src/hooks/useGlobalState.ts | 4 +- frontend/src/hooks/useHasAccess.ts | 22 +- frontend/src/hooks/useHiddenEnvironments.ts | 2 +- ...ghestPermissionChangeRequestEnvironment.ts | 8 +- frontend/src/hooks/useIsAppleDevice.ts | 2 +- frontend/src/hooks/useKeyboardShortcut.ts | 10 +- frontend/src/hooks/useLoading.ts | 2 +- frontend/src/hooks/useLocationSettings.ts | 2 +- frontend/src/hooks/useOnBlur.test.tsx | 8 +- frontend/src/hooks/useOnBlur.ts | 2 +- frontend/src/hooks/useOnClickOutside.test.tsx | 6 +- frontend/src/hooks/useOnClickOutside.ts | 8 +- frontend/src/hooks/usePagination.ts | 6 +- .../src/hooks/usePersistentGlobalState.ts | 4 +- frontend/src/hooks/usePinnedFavorites.test.ts | 6 +- frontend/src/hooks/usePinnedFavorites.ts | 4 +- frontend/src/hooks/usePlausibleTracker.ts | 4 +- .../src/hooks/useQueryStringNumberState.ts | 4 +- frontend/src/hooks/useQueryStringState.ts | 4 +- frontend/src/hooks/useSearch.test.tsx | 24 +- frontend/src/hooks/useSearch.ts | 50 +- frontend/src/hooks/useToast.tsx | 4 +- frontend/src/hooks/useUsersPlan.ts | 8 +- frontend/src/hooks/useVirtualizedRange.ts | 10 +- frontend/src/hooks/useWeakMap.ts | 6 +- frontend/src/index.tsx | 2 +- frontend/src/openapi/fetcher.ts | 2 +- frontend/src/themes/dark-theme.ts | 4 +- frontend/src/themes/theme.ts | 4 +- frontend/src/themes/themeStyles.ts | 2 +- frontend/src/themes/themeTypes.ts | 5 + frontend/src/types/react-table-config.d.ts | 19 +- frontend/src/utils/apiUtils.ts | 2 +- frontend/src/utils/arraysHaveSameItems.ts | 2 +- frontend/src/utils/cleanConstraint.test.ts | 4 +- frontend/src/utils/cleanConstraint.ts | 4 +- .../src/utils/createFeatureStrategy.test.ts | 4 +- frontend/src/utils/createFeatureStrategy.ts | 6 +- frontend/src/utils/createLocalStorage.ts | 2 +- frontend/src/utils/deepOmit.ts | 6 +- frontend/src/utils/formatAccessText.ts | 2 +- frontend/src/utils/formatConstraintValue.ts | 2 +- frontend/src/utils/formatDate.ts | 8 +- frontend/src/utils/formatPath.ts | 2 +- frontend/src/utils/getFeatureMetrics.ts | 6 +- frontend/src/utils/instanceTrial.test.ts | 20 +- frontend/src/utils/instanceTrial.ts | 10 +- frontend/src/utils/oneOf.ts | 2 +- frontend/src/utils/operatorsForContext.ts | 2 +- frontend/src/utils/paginate.test.ts | 3 +- frontend/src/utils/paginate.ts | 2 +- frontend/src/utils/parseParameter.ts | 8 +- frontend/src/utils/permissions.ts | 38 +- frontend/src/utils/projectFilterGenerator.ts | 6 +- frontend/src/utils/routePathHelpers.ts | 5 +- .../src/utils/sortStrategyParameters.test.ts | 4 +- frontend/src/utils/sortStrategyParameters.ts | 8 +- frontend/src/utils/sortTypes.test.ts | 8 +- frontend/src/utils/sortTypes.ts | 14 +- frontend/src/utils/storage.ts | 4 +- frontend/src/utils/strategyNames.tsx | 4 +- frontend/src/utils/testRenderer.tsx | 2 +- frontend/src/utils/testServer.ts | 4 +- frontend/src/utils/validateParameterValue.ts | 2 +- frontend/src/utils/variants.ts | 2 +- frontend/vite.config.ts | 2 +- frontend/yarn.lock | 1844 +---------------- package.json | 36 +- src/migrations/.eslintrc | 14 - 920 files changed, 5755 insertions(+), 7835 deletions(-) delete mode 100644 .prettierignore create mode 100644 .vscode/settings.json delete mode 100644 frontend/.prettierignore delete mode 100644 frontend/.prettierrc delete mode 100644 src/migrations/.eslintrc diff --git a/.gitignore b/.gitignore index d5d7377f94..0d2f39d5e9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,6 @@ unleash-server.tar.gz # Visual Studio Code jsconfig.json typings -.vscode .nyc_output # We use yarn.lock diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 50fa9364be..0000000000 --- a/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -CHANGELOG.md -website/docs diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..462a5c057c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.defaultFormatter": "biomejs.biome" +} diff --git a/biome.json b/biome.json index 2cf0a2ba6e..ec7484c86f 100644 --- a/biome.json +++ b/biome.json @@ -41,8 +41,8 @@ "website/translated_docs", "website", "setupJest.js", - "frontend", "dist", + "build", "src/migrations/*.js", "src/test/examples/*.json", "website/**/*.js", @@ -67,16 +67,13 @@ "website/translated_docs", "website", "setupJest.js", - "frontend", "dist", + "build", "src/migrations/*.js", "src/migrations/*.json", "src/test/examples/*.json", "website/**/*.js", - "coverage", - ".eslintrc", - ".eslintignore", - "package.json" + "coverage" ], "indentSize": 4 }, diff --git a/frontend/.prettierignore b/frontend/.prettierignore deleted file mode 100644 index 3a8fb9cf67..0000000000 --- a/frontend/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -.github/* -CHANGELOG.md diff --git a/frontend/.prettierrc b/frontend/.prettierrc deleted file mode 100644 index 552578130e..0000000000 --- a/frontend/.prettierrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "singleQuote": true, - "bracketSpacing": true, - "bracketSameLine": false, - "arrowParens": "avoid", - "printWidth": 80 -} diff --git a/frontend/cypress.config.ts b/frontend/cypress.config.ts index 88468d02b1..2ff0fa05ea 100644 --- a/frontend/cypress.config.ts +++ b/frontend/cypress.config.ts @@ -15,7 +15,7 @@ export default defineConfig({ vitePreprocessor({ configFile: path.resolve(__dirname, './vite.config.ts'), mode: 'development', - }) + }), ); on('task', { log(message) { diff --git a/frontend/cypress.d.ts b/frontend/cypress.d.ts index d12adb035f..82be5b6558 100644 --- a/frontend/cypress.d.ts +++ b/frontend/cypress.d.ts @@ -1,5 +1,5 @@ /// declare namespace Cypress { - interface Chainable {} + type Chainable = {}; } diff --git a/frontend/cypress/global.d.ts b/frontend/cypress/global.d.ts index aacc3afe18..92009e4931 100644 --- a/frontend/cypress/global.d.ts +++ b/frontend/cypress/global.d.ts @@ -26,25 +26,25 @@ declare namespace Cypress { createProject_UI( projectName: string, - defaultStickiness: string + defaultStickiness: string, ): Chainable; createFeature_UI( name: string, shouldWait?: boolean, - project?: string + project?: string, ): Chainable; // VARIANTS addVariantsToFeature_UI( featureToggleName: string, variants: Array, - projectName?: string + projectName?: string, ); deleteVariant_UI( featureToggleName: string, variant: string, - projectName?: string + projectName?: string, ): Chainable; // SEGMENTS @@ -54,16 +54,16 @@ declare namespace Cypress { // STRATEGY addUserIdStrategyToFeature_UI( featureName: string, - projectName?: string + projectName?: string, ): Chainable; addFlexibleRolloutStrategyToFeature_UI( - options: AddFlexibleRolloutStrategyOptions + options: AddFlexibleRolloutStrategyOptions, ): Chainable; updateFlexibleRolloutStrategy_UI(featureToggleName: string); deleteFeatureStrategy_UI( featureName: string, shouldWait?: boolean, - projectName?: string + projectName?: string, ): Chainable; // API @@ -72,22 +72,22 @@ declare namespace Cypress { addUserToProject_API( id: number, role: number, - projectName?: string + projectName?: string, ): Chainable; createProject_API( name: string, - options?: Partial + options?: Partial, ): Chainable; deleteProject_API(name: string): Chainable; createFeature_API( name: string, projectName?: string, - options?: Partial + options?: Partial, ): Chainable; deleteFeature_API(name: string): Chainable; createEnvironment_API( environment: IEnvironment, - options?: Partial + options?: Partial, ): Chainable; } } diff --git a/frontend/cypress/integration/demo/demo.spec.ts b/frontend/cypress/integration/demo/demo.spec.ts index 71f57a0938..f40fb4e2e3 100644 --- a/frontend/cypress/integration/demo/demo.spec.ts +++ b/frontend/cypress/integration/demo/demo.spec.ts @@ -16,7 +16,7 @@ describe('demo', () => { name: 'dev', type: 'development', }, - optionsIgnore409 + optionsIgnore409, ); cy.createProject_API('demo-app', optionsIgnore409); cy.createFeature_API('demoApp.step1', 'demo-app', optionsIgnore409); @@ -32,10 +32,10 @@ describe('demo', () => { cy.get("[data-testid='CLOSE_SPLASH']").click(); } - cy.intercept('GET', `${baseUrl}/api/admin/ui-config`, req => { + cy.intercept('GET', `${baseUrl}/api/admin/ui-config`, (req) => { req.headers['cache-control'] = 'no-cache, no-store, must-revalidate'; - req.on('response', res => { + req.on('response', (res) => { if (res.body) { res.body.flags = { ...res.body.flags, @@ -93,7 +93,7 @@ describe('demo', () => { 'log', `Testing topic #${topic + 1} "${ currentTopic.title - }", step #${step + 1}...` + }", step #${step + 1}...`, ); if (!currentStep.optional) { diff --git a/frontend/cypress/integration/feature/feature.spec.ts b/frontend/cypress/integration/feature/feature.spec.ts index 855fb7af4f..bfd6cec5e9 100644 --- a/frontend/cypress/integration/feature/feature.spec.ts +++ b/frontend/cypress/integration/feature/feature.spec.ts @@ -28,14 +28,14 @@ describe('feature', () => { it('gives an error if a toggle exists with the same name', () => { cy.createFeature_UI(featureToggleName, false); cy.get("[data-testid='INPUT_ERROR_TEXT']").contains( - 'A toggle with that name already exists' + 'A toggle with that name already exists', ); }); it('gives an error if a toggle name is url unsafe', () => { cy.createFeature_UI('featureToggleUnsafe####$#//', false); cy.get("[data-testid='INPUT_ERROR_TEXT']").contains( - `"name" must be URL friendly` + `"name" must be URL friendly`, ); }); @@ -44,7 +44,7 @@ describe('feature', () => { featureToggleName, }).then(() => { cy.updateFlexibleRolloutStrategy_UI(featureToggleName).then(() => - cy.deleteFeatureStrategy_UI(featureToggleName) + cy.deleteFeatureStrategy_UI(featureToggleName), ); }); }); @@ -71,7 +71,7 @@ describe('feature', () => { cy.intercept( 'PATCH', `/api/admin/projects/default/features/${featureToggleName}/environments/development/variants`, - req => { + (req) => { expect(req.body[0].op).to.equal('replace'); expect(req.body[0].path).to.equal('/1/weightType'); expect(req.body[0].value).to.equal('fix'); @@ -81,13 +81,13 @@ describe('feature', () => { expect(req.body[2].op).to.equal('replace'); expect(req.body[2].path).to.equal('/0/weight'); expect(req.body[2].value).to.equal(850); - } + }, ).as('variantUpdate'); cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click(); cy.get(`[data-testid=VARIANT_WEIGHT_${variant2}]`).should( 'have.text', - '15 %' + '15 %', ); }); diff --git a/frontend/cypress/integration/groups/groups.spec.ts b/frontend/cypress/integration/groups/groups.spec.ts index 2b4a2431dc..672f747280 100644 --- a/frontend/cypress/integration/groups/groups.spec.ts +++ b/frontend/cypress/integration/groups/groups.spec.ts @@ -15,13 +15,13 @@ describe('groups', () => { email: `unleash-e2e-user${i}-${randomId}@test.com`, sendEmail: false, rootRole: 3, - }).then(response => userIds.push(response.body.id)); + }).then((response) => userIds.push(response.body.id)); } }); after(() => { - userIds.forEach(id => - cy.request('DELETE', `${baseUrl}/api/admin/user-admin/${id}`) + userIds.forEach((id) => + cy.request('DELETE', `${baseUrl}/api/admin/user-admin/${id}`), ); }); @@ -55,7 +55,7 @@ describe('groups', () => { cy.get("[data-testid='UG_NAME_ID']").type(groupName); cy.get("[data-testid='INPUT_ERROR_TEXT'").contains( - 'A group with that name already exists.' + 'A group with that name already exists.', ); }); diff --git a/frontend/cypress/integration/import/import.spec.ts b/frontend/cypress/integration/import/import.spec.ts index f934c925bb..03eb40ff9d 100644 --- a/frontend/cypress/integration/import/import.spec.ts +++ b/frontend/cypress/integration/import/import.spec.ts @@ -15,13 +15,13 @@ describe('imports', () => { email: `unleash-e2e-user${i}-${randomFeatureName}@test.com`, sendEmail: false, rootRole: 3, - }).then(response => userIds.push(response.body.id)); + }).then((response) => userIds.push(response.body.id)); } }); after(() => { - userIds.forEach(id => - cy.request('DELETE', `${baseUrl}/api/admin/user-admin/${id}`) + userIds.forEach((id) => + cy.request('DELETE', `${baseUrl}/api/admin/user-admin/${id}`), ); }); @@ -118,13 +118,13 @@ describe('imports', () => { cy.wait(500); cy.get( - "[data-testid='feature-toggle-status'] input[type='checkbox']:checked" + "[data-testid='feature-toggle-status'] input[type='checkbox']:checked", ) .invoke('attr', 'aria-label') .should('eq', 'development'); cy.get( - '[data-testid="FEATURE_ENVIRONMENT_ACCORDION_development"]' + '[data-testid="FEATURE_ENVIRONMENT_ACCORDION_development"]', ).click(); cy.contains('50%'); }); diff --git a/frontend/cypress/integration/projects/access.spec.ts b/frontend/cypress/integration/projects/access.spec.ts index 68898e7ceb..d3d3f53b40 100644 --- a/frontend/cypress/integration/projects/access.spec.ts +++ b/frontend/cypress/integration/projects/access.spec.ts @@ -31,13 +31,13 @@ describe('project-access', () => { rootRole: 3, }) .as(name) - .then(response => { + .then((response) => { const id = response.body.id; userIds.push(id); cy.request('POST', `${baseUrl}/api/admin/groups`, { name: `${i}-${groupAndProjectName}`, users: [{ user: { id: id } }], - }).then(response => { + }).then((response) => { const id = response.body.id; groupIds.push(id); }); @@ -50,26 +50,26 @@ describe('project-access', () => { }); after(() => { - userIds.forEach(id => - cy.request('DELETE', `${baseUrl}/api/admin/user-admin/${id}`) + userIds.forEach((id) => + cy.request('DELETE', `${baseUrl}/api/admin/user-admin/${id}`), ); - groupIds.forEach(id => - cy.request('DELETE', `${baseUrl}/api/admin/groups/${id}`) + groupIds.forEach((id) => + cy.request('DELETE', `${baseUrl}/api/admin/groups/${id}`), ); cy.request( 'DELETE', - `${baseUrl}/api/admin/projects/${groupAndProjectName}` + `${baseUrl}/api/admin/projects/${groupAndProjectName}`, ); }); beforeEach(() => { cy.login_UI(); - cy.intercept('GET', `${baseUrl}/api/admin/ui-config`, req => { + cy.intercept('GET', `${baseUrl}/api/admin/ui-config`, (req) => { req.headers['cache-control'] = 'no-cache, no-store, must-revalidate'; - req.on('response', res => { + req.on('response', (res) => { if (res.body) { res.body.flags = { ...res.body.flags, @@ -90,7 +90,7 @@ describe('project-access', () => { cy.intercept( 'POST', - `/api/admin/projects/${groupAndProjectName}/access` + `/api/admin/projects/${groupAndProjectName}/access`, ).as('assignAccess'); cy.get(`[data-testid='${PA_USERS_GROUPS_ID}']`).click(); @@ -109,7 +109,7 @@ describe('project-access', () => { cy.intercept( 'POST', - `/api/admin/projects/${groupAndProjectName}/access` + `/api/admin/projects/${groupAndProjectName}/access`, ).as('assignAccess'); cy.get(`[data-testid='${PA_USERS_GROUPS_ID}']`).click(); @@ -128,7 +128,7 @@ describe('project-access', () => { cy.intercept( 'PUT', - `/api/admin/projects/${groupAndProjectName}/groups/${groupIds[0]}/roles` + `/api/admin/projects/${groupAndProjectName}/groups/${groupIds[0]}/roles`, ).as('editAccess'); cy.get(`[data-testid='CancelIcon']`).last().click(); @@ -148,7 +148,7 @@ describe('project-access', () => { cy.intercept( 'PUT', - `/api/admin/projects/${groupAndProjectName}/groups/${groupIds[0]}/roles` + `/api/admin/projects/${groupAndProjectName}/groups/${groupIds[0]}/roles`, ).as('editAccess'); cy.get(`[data-testid='${PA_ROLE_ID}']`).click(); @@ -167,7 +167,7 @@ describe('project-access', () => { cy.intercept( 'DELETE', - `/api/admin/projects/${groupAndProjectName}/groups/${groupIds[0]}/roles` + `/api/admin/projects/${groupAndProjectName}/groups/${groupIds[0]}/roles`, ).as('removeAccess'); cy.contains("Yes, I'm sure").click(); diff --git a/frontend/cypress/integration/segments/segments.spec.ts b/frontend/cypress/integration/segments/segments.spec.ts index 4d7f0733d1..343a8e904e 100644 --- a/frontend/cypress/integration/segments/segments.spec.ts +++ b/frontend/cypress/integration/segments/segments.spec.ts @@ -27,7 +27,7 @@ describe('segments', () => { cy.get("[data-testid='SEGMENT_NAME_ID']").type(segmentName); cy.get("[data-testid='SEGMENT_NEXT_BTN_ID']").should('be.disabled'); cy.get("[data-testid='INPUT_ERROR_TEXT']").contains( - 'Segment name already exists' + 'Segment name already exists', ); }); diff --git a/frontend/cypress/support/API.ts b/frontend/cypress/support/API.ts index 15ef005513..d4784a7462 100644 --- a/frontend/cypress/support/API.ts +++ b/frontend/cypress/support/API.ts @@ -2,12 +2,12 @@ import Chainable = Cypress.Chainable; const baseUrl = Cypress.config().baseUrl; -const password = Cypress.env(`AUTH_PASSWORD`) + '_A'; +const password = `${Cypress.env(`AUTH_PASSWORD`)}_A`; const PROJECT_MEMBER = 5; export const createFeature_API = ( featureName: string, projectName?: string, - options?: Partial + options?: Partial, ): Chainable => { const project = projectName || 'default'; return cy.request({ @@ -36,7 +36,7 @@ export const deleteFeature_API = (name: string): Chainable => { export const createProject_API = ( project: string, - options?: Partial + options?: Partial, ): Chainable => { return cy.request({ url: `${baseUrl}/api/admin/projects`, @@ -71,10 +71,10 @@ export const createUser_API = (userName: string, role: number) => { rootRole: role, }) .as(name) - .then(response => { + .then((response) => { const id = response.body.id; updateUserPassword_API(id).then(() => { - addUserToProject_API(id, PROJECT_MEMBER).then(value => { + addUserToProject_API(id, PROJECT_MEMBER).then((value) => { userIds.push(id); userCredentials.push({ email, password }); }); @@ -89,13 +89,13 @@ export const updateUserPassword_API = (id: number, pass?: string): Chainable => `${baseUrl}/api/admin/user-admin/${id}/change-password`, { password: pass || password, - } + }, ); export const addUserToProject_API = ( id: number, role: number, - projectName?: string + projectName?: string, ): Chainable => { const project = projectName || 'default'; return cy.request( @@ -104,7 +104,7 @@ export const addUserToProject_API = ( { groups: [], users: [{ id }], - } + }, ); }; @@ -115,7 +115,7 @@ interface IEnvironment { export const createEnvironment_API = ( environment: IEnvironment, - options?: Partial + options?: Partial, ): Chainable => { return cy.request({ url: `${baseUrl}/api/admin/environments`, diff --git a/frontend/cypress/support/UI.ts b/frontend/cypress/support/UI.ts index 006bad07c6..dc1fc18504 100644 --- a/frontend/cypress/support/UI.ts +++ b/frontend/cypress/support/UI.ts @@ -15,7 +15,7 @@ const disableActiveSplashScreens = () => { const disableFeatureStrategiesProdGuard = () => { localStorage.setItem( 'useFeatureStrategyProdGuardSettings:v2', - JSON.stringify({ hide: true }) + JSON.stringify({ hide: true }), ); }; @@ -26,7 +26,7 @@ export const runBefore = () => { export const login_UI = ( user = AUTH_USER, - password = AUTH_PASSWORD + password = AUTH_PASSWORD, ): Chainable => { return cy.session(user, () => { cy.visit('/'); @@ -51,14 +51,14 @@ export const login_UI = ( export const createFeature_UI = ( name: string, shouldWait?: boolean, - project?: string + project?: string, ): Chainable => { const projectName = project || 'default'; cy.get('[data-testid=NAVIGATE_TO_CREATE_FEATURE').click(); cy.intercept('POST', `/api/admin/projects/${projectName}/features`).as( - 'createFeature' + 'createFeature', ); cy.wait(300); @@ -72,7 +72,7 @@ export const createFeature_UI = ( export const createProject_UI = ( projectName: string, - defaultStickiness: string + defaultStickiness: string, ): Chainable => { cy.get('[data-testid=NAVIGATE_TO_CREATE_PROJECT').click(); @@ -111,7 +111,7 @@ export const deleteSegment_UI = (segmentName: string): Chainable => { }; export const addFlexibleRolloutStrategyToFeature_UI = ( - options: AddStrategyOptions + options: AddStrategyOptions, ): Chainable => { const { featureToggleName, project, environment, stickiness } = options; const projectName = project || 'default'; @@ -123,7 +123,7 @@ export const addFlexibleRolloutStrategyToFeature_UI = ( cy.intercept( 'POST', `/api/admin/projects/${projectName}/features/${featureToggleName}/environments/development/strategies`, - req => { + (req) => { expect(req.body.name).to.equal('flexibleRollout'); expect(req.body.parameters.groupId).to.equal(featureToggleName); expect(req.body.parameters.stickiness).to.equal(defaultStickiness); @@ -135,14 +135,14 @@ export const addFlexibleRolloutStrategyToFeature_UI = ( expect(req.body.constraints.length).to.equal(0); } - req.continue(res => { + req.continue((res) => { strategyId = res.body.id; }); - } + }, ).as('addStrategyToFeature'); cy.visit( - `/projects/${projectName}/features/${featureToggleName}/strategies/create?environmentId=${env}&strategyName=flexibleRollout` + `/projects/${projectName}/features/${featureToggleName}/strategies/create?environmentId=${env}&strategyName=flexibleRollout`, ); cy.wait(500); // Takes a bit to load the screen - this will wait until it finds it or fail @@ -157,11 +157,11 @@ export const addFlexibleRolloutStrategyToFeature_UI = ( export const updateFlexibleRolloutStrategy_UI = ( featureToggleName: string, - projectName?: string + projectName?: string, ) => { const project = projectName || 'default'; cy.visit( - `/projects/${project}/features/${featureToggleName}/strategies/edit?environmentId=development&strategyId=${strategyId}` + `/projects/${project}/features/${featureToggleName}/strategies/edit?environmentId=development&strategyId=${strategyId}`, ); cy.wait(500); @@ -182,7 +182,7 @@ export const updateFlexibleRolloutStrategy_UI = ( cy.intercept( 'PUT', `/api/admin/projects/${project}/features/${featureToggleName}/environments/*/strategies/${strategyId}`, - req => { + (req) => { expect(req.body.parameters.groupId).to.equal('new-group-id'); expect(req.body.parameters.stickiness).to.equal('sessionId'); expect(req.body.parameters.rollout).to.equal('50'); @@ -193,10 +193,10 @@ export const updateFlexibleRolloutStrategy_UI = ( expect(req.body.constraints.length).to.equal(0); } - req.continue(res => { + req.continue((res) => { expect(res.statusCode).to.equal(200); }); - } + }, ).as('updateStrategy'); cy.get(`[data-testid=STRATEGY_FORM_SUBMIT_ID]`).first().click(); @@ -206,18 +206,18 @@ export const updateFlexibleRolloutStrategy_UI = ( export const deleteFeatureStrategy_UI = ( featureToggleName: string, shouldWait?: boolean, - projectName?: string + projectName?: string, ): Chainable => { const project = projectName || 'default'; cy.intercept( 'DELETE', `/api/admin/projects/${project}/features/${featureToggleName}/environments/*/strategies/${strategyId}`, - req => { - req.continue(res => { + (req) => { + req.continue((res) => { expect(res.statusCode).to.equal(200); }); - } + }, ).as('deleteUserStrategy'); cy.visit(`/projects/${project}/features/${featureToggleName}`); cy.get('[data-testid=FEATURE_ENVIRONMENT_ACCORDION_development]').click(); @@ -230,11 +230,11 @@ export const deleteFeatureStrategy_UI = ( export const addUserIdStrategyToFeature_UI = ( featureToggleName: string, - projectName: string + projectName: string, ): Chainable => { const project = projectName || 'default'; cy.visit( - `/projects/${project}/features/${featureToggleName}/strategies/create?environmentId=development&strategyName=userWithId` + `/projects/${project}/features/${featureToggleName}/strategies/create?environmentId=development&strategyName=userWithId`, ); if (ENTERPRISE) { @@ -255,7 +255,7 @@ export const addUserIdStrategyToFeature_UI = ( cy.intercept( 'POST', `/api/admin/projects/default/features/${featureToggleName}/environments/*/strategies`, - req => { + (req) => { expect(req.body.name).to.equal('userWithId'); expect(req.body.parameters.userIds.length).to.equal(11); @@ -266,10 +266,10 @@ export const addUserIdStrategyToFeature_UI = ( expect(req.body.constraints.length).to.equal(0); } - req.continue(res => { + req.continue((res) => { strategyId = res.body.id; }); - } + }, ).as('addStrategyToFeature'); cy.get(`[data-testid=STRATEGY_FORM_SUBMIT_ID]`).first().click(); @@ -279,7 +279,7 @@ export const addUserIdStrategyToFeature_UI = ( export const addVariantsToFeature_UI = ( featureToggleName: string, variants: Array, - projectName: string + projectName: string, ) => { const project = projectName || 'default'; cy.visit(`/projects/${project}/features/${featureToggleName}/variants`); @@ -287,16 +287,16 @@ export const addVariantsToFeature_UI = ( cy.intercept( 'PATCH', `/api/admin/projects/${project}/features/${featureToggleName}/environments/development/variants`, - req => { + (req) => { variants.forEach((variant, index) => { expect(req.body[index].op).to.equal('add'); expect(req.body[index].path).to.equal(`/${index}`); expect(req.body[index].value.name).to.equal(variant); expect(req.body[index].value.weight).to.equal( - 1000 / variants.length + 1000 / variants.length, ); }); - } + }, ).as('variantCreation'); cy.get('[data-testid=ADD_VARIANT_BUTTON]').first().click(); @@ -314,7 +314,7 @@ export const addVariantsToFeature_UI = ( export const deleteVariant_UI = ( featureToggleName: string, variant: string, - projectName?: string + projectName?: string, ): Chainable => { const project = projectName || 'default'; cy.visit(`/projects/${project}/features/${featureToggleName}/variants`); @@ -325,13 +325,13 @@ export const deleteVariant_UI = ( cy.intercept( 'PATCH', `/api/admin/projects/${project}/features/${featureToggleName}/environments/development/variants`, - req => { + (req) => { expect(req.body[0].op).to.equal('remove'); expect(req.body[0].path).to.equal('/1'); expect(req.body[1].op).to.equal('replace'); expect(req.body[1].path).to.equal('/0/weight'); expect(req.body[1].value).to.equal(1000); - } + }, ).as('delete'); cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click(); diff --git a/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts index a726f50926..5f3e37f5b2 100644 --- a/frontend/cypress/support/commands.ts +++ b/frontend/cypress/support/commands.ts @@ -47,14 +47,14 @@ Cypress.Commands.add('deleteVariant_UI', deleteVariant_UI); Cypress.Commands.add('addVariantsToFeature_UI', addVariantsToFeature_UI); Cypress.Commands.add( 'addUserIdStrategyToFeature_UI', - addUserIdStrategyToFeature_UI + addUserIdStrategyToFeature_UI, ); Cypress.Commands.add( 'addFlexibleRolloutStrategyToFeature_UI', - addFlexibleRolloutStrategyToFeature_UI + addFlexibleRolloutStrategyToFeature_UI, ); Cypress.Commands.add( 'updateFlexibleRolloutStrategy_UI', - updateFlexibleRolloutStrategy_UI + updateFlexibleRolloutStrategy_UI, ); Cypress.Commands.add('createEnvironment_API', createEnvironment_API); diff --git a/frontend/cypress/support/e2e.ts b/frontend/cypress/support/e2e.ts index f80f74f8e1..598ab5f0d7 100644 --- a/frontend/cypress/support/e2e.ts +++ b/frontend/cypress/support/e2e.ts @@ -14,7 +14,7 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands' +import './commands'; // Alternatively you can use CommonJS syntax: -// require('./commands') \ No newline at end of file +// require('./commands') diff --git a/frontend/index.js b/frontend/index.js index 1eff7e6952..806b9296e7 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -5,5 +5,5 @@ const { version } = module.exports; module.exports = { publicFolder: path.join(__dirname, 'build'), - version + version, }; diff --git a/frontend/package.json b/frontend/package.json index 8c33c0fa77..05c060243f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,10 +2,7 @@ "name": "unleash-frontend-local", "version": "0.0.0", "private": true, - "files": [ - "index.js", - "build" - ], + "files": ["index.js", "build"], "engines": { "node": ">=18" }, @@ -21,10 +18,10 @@ "test": "tsc && NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" vitest run", "test:snapshot": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" yarn test -u", "test:watch": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" vitest watch", - "lint": "eslint --fix ./src", - "lint:check": "eslint ./src", - "fmt": "prettier src --write --loglevel warn", - "fmt:check": "prettier src --check", + "lint": "biome lint src --apply", + "lint:check": "biome lint src", + "fmt": "biome format src --write", + "fmt:check": "biome format src", "ts:check": "tsc", "e2e": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" yarn run cypress open --config baseUrl='http://localhost:3000' --env AUTH_USER=admin,AUTH_PASSWORD=unleash4all", "e2e:heroku": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" yarn run cypress open --config baseUrl='https://unleash.herokuapp.com' --env AUTH_USER=admin,AUTH_PASSWORD=unleash4all", @@ -33,6 +30,7 @@ "gen:api:sandbox": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" UNLEASH_OPENAPI_URL=https://sandbox.getunleash.io/demo2/docs/openapi.json yarn run gen:api" }, "devDependencies": { + "@biomejs/biome": "^1.2.2", "@codemirror/lang-json": "6.0.1", "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", @@ -75,8 +73,6 @@ "debounce": "1.2.1", "deep-diff": "1.0.2", "dequal": "2.0.3", - "eslint": "8.50.0", - "eslint-config-react-app": "7.0.1", "fast-json-patch": "3.1.1", "http-proxy-middleware": "2.0.6", "immer": "9.0.21", @@ -88,7 +84,6 @@ "msw": "0.49.3", "pkginfo": "0.4.1", "plausible-tracker": "0.3.8", - "prettier": "2.8.1", "prop-types": "15.8.1", "react": "17.0.2", "react-chartjs-2": "4.3.1", @@ -136,34 +131,12 @@ } }, "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], + "production": [">0.2%", "not dead", "not op_mini all"], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ], - "parserOptions": { - "warnOnUnsupportedTypeScriptVersion": false - }, - "rules": { - "no-restricted-globals": "off", - "no-useless-computed-key": "off", - "import/no-anonymous-default-export": "off", - "react-hooks/exhaustive-deps": "off" - }, - "ignorePatterns": [ - "cypress" - ] - }, "dependencies": {} } diff --git a/frontend/src/component/App.tsx b/frontend/src/component/App.tsx index 65a50202c2..ab799a9467 100644 --- a/frontend/src/component/App.tsx +++ b/frontend/src/component/App.tsx @@ -1,7 +1,7 @@ import { Suspense, useEffect } from 'react'; import { Route, Routes } from 'react-router-dom'; import { ErrorBoundary } from 'react-error-boundary'; -import { Error } from 'component/layout/Error/Error'; +import { Error as LayoutError } from 'component/layout/Error/Error'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { FeedbackNPS } from 'component/feedback/FeedbackNPS/FeedbackNPS'; import { LayoutPicker } from 'component/layout/LayoutPicker/LayoutPicker'; @@ -37,7 +37,7 @@ export const App = () => { const { isOss, uiConfig } = useUiConfig(); const availableRoutes = isOss() - ? routes.filter(route => !route.enterprise) + ? routes.filter((route) => !route.enterprise) : routes; useEffect(() => { @@ -47,9 +47,9 @@ export const App = () => { }, [authDetails, user]); return ( - + - + }> { <> } /> - {availableRoutes.map(route => ( - - ( + - - } - /> - ))} + > + + + } + /> + ), + )} } /> } /> - + diff --git a/frontend/src/component/admin/Admin.tsx b/frontend/src/component/admin/Admin.tsx index 50be47aa0b..2a7cdc8eec 100644 --- a/frontend/src/component/admin/Admin.tsx +++ b/frontend/src/component/admin/Admin.tsx @@ -25,26 +25,26 @@ export const Admin = () => { } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> } /> - } /> - } /> - } /> + } /> + } /> + } /> ); diff --git a/frontend/src/component/admin/AdminIndex.tsx b/frontend/src/component/admin/AdminIndex.tsx index 8ed728b61d..46d49b5818 100644 --- a/frontend/src/component/admin/AdminIndex.tsx +++ b/frontend/src/component/admin/AdminIndex.tsx @@ -10,35 +10,42 @@ import { useAdminRoutes } from './useAdminRoutes'; export const AdminIndex: VFC = () => { const adminRoutes = useAdminRoutes(); - const routeGroups = adminRoutes.reduce((acc, route) => { - const group = route.group || 'other'; + const routeGroups = adminRoutes.reduce( + (acc, route) => { + const group = route.group || 'other'; - const index = acc.findIndex(item => item.name === group); - if (index === -1) { - acc.push({ - name: group, - description: adminGroups[group] || 'Other', - items: [route], - }); + const index = acc.findIndex((item) => item.name === group); + if (index === -1) { + acc.push({ + name: group, + description: adminGroups[group] || 'Other', + items: [route], + }); + + return acc; + } + + acc[index].items.push(route); return acc; - } - - acc[index].items.push(route); - - return acc; - }, [] as Array<{ name: string; description: string; items: INavigationMenuItem[] }>); + }, + [] as Array<{ + name: string; + description: string; + items: INavigationMenuItem[]; + }>, + ); return ( - }> - {routeGroups.map(group => ( + }> + {routeGroups.map((group) => ( ({ marginBottom: theme.spacing(2) })} + sx={(theme) => ({ marginBottom: theme.spacing(2) })} > - {group.description} + {group.description}
    - {group.items.map(route => ( + {group.items.map((route) => (
  • {route.title} diff --git a/frontend/src/component/admin/AdminRedirect.tsx b/frontend/src/component/admin/AdminRedirect.tsx index 9ceaa4bdde..71b406d7a5 100644 --- a/frontend/src/component/admin/AdminRedirect.tsx +++ b/frontend/src/component/admin/AdminRedirect.tsx @@ -1,3 +1,3 @@ import { Navigate } from 'react-router-dom'; -export const AdminRedirect = () => ; +export const AdminRedirect = () => ; diff --git a/frontend/src/component/admin/apiToken/ApiTokenDocs/ApiTokenDocs.tsx b/frontend/src/component/admin/apiToken/ApiTokenDocs/ApiTokenDocs.tsx index 8ba756a7c9..a6b94e2550 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenDocs/ApiTokenDocs.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenDocs/ApiTokenDocs.tsx @@ -5,13 +5,13 @@ export const ApiTokenDocs = () => { const { uiConfig } = useUiConfig(); return ( - +

    Read the{' '} SDK overview {' '} diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx index 567e4f71b0..21c2ccb7e7 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx @@ -26,9 +26,9 @@ const ApiTokenForm: React.FC = ({ + Please be aware of our{' '} - + fair use policy . diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/EnvironmentSelector/EnvironmentSelector.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/EnvironmentSelector/EnvironmentSelector.tsx index f77a6048e1..c0186e20ea 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/EnvironmentSelector/EnvironmentSelector.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/EnvironmentSelector/EnvironmentSelector.tsx @@ -21,10 +21,10 @@ export const EnvironmentSelector = ({ const selectableEnvs = type === TokenType.ADMIN ? [{ key: '*', label: 'ALL' }] - : environments.map(environment => ({ + : environments.map((environment) => ({ key: environment.name, label: `${environment.name.concat( - !environment.enabled ? ' - deprecated' : '' + !environment.enabled ? ' - deprecated' : '', )}`, title: environment.name, disabled: false, @@ -40,9 +40,9 @@ export const EnvironmentSelector = ({ options={selectableEnvs} value={environment} onChange={setEnvironment} - label="Environment" - id="api_key_environment" - name="environment" + label='Environment' + id='api_key_environment' + name='environment' IconComponent={KeyboardArrowDownOutlined} fullWidth /> diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/ProjectSelector.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/ProjectSelector.tsx index 18162609fd..4838325ba0 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/ProjectSelector.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/ProjectSelector.tsx @@ -23,7 +23,7 @@ export const ProjectSelector = ({ const projectId = useOptionalPathParam('projectId'); const { projects: availableProjects } = useProjects(); - const selectableProjects = availableProjects.map(project => ({ + const selectableProjects = availableProjects.map((project) => ({ value: project.id, label: project.name, })); diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectAllButton/SelectAllButton.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectAllButton/SelectAllButton.tsx index 7e7b4ee818..755a2457bf 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectAllButton/SelectAllButton.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectAllButton/SelectAllButton.tsx @@ -17,7 +17,7 @@ export const SelectAllButton: FC = ({ }) => { return ( - + {isAllSelected ? 'Deselect all' : 'Select all'} diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.test.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.test.tsx index f013194bb5..2210259a5f 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.test.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.test.tsx @@ -36,7 +36,7 @@ describe('SelectProjectInput', () => { render(); const checkbox = screen.getByLabelText( - /all current and future projects/i + /all current and future projects/i, ); expect(checkbox).toBeChecked(); @@ -52,7 +52,7 @@ describe('SelectProjectInput', () => { await user.click(screen.getByTestId('select-all-projects')); expect( - screen.getByLabelText(/all current and future projects/i) + screen.getByLabelText(/all current and future projects/i), ).not.toBeChecked(); expect(screen.getByLabelText('Projects')).toBeEnabled(); @@ -60,7 +60,7 @@ describe('SelectProjectInput', () => { await user.click(screen.getByTestId('select-all-projects')); expect( - screen.getByLabelText(/all current and future projects/i) + screen.getByLabelText(/all current and future projects/i), ).toBeChecked(); expect(screen.getByLabelText('Projects')).toBeDisabled(); @@ -68,11 +68,11 @@ describe('SelectProjectInput', () => { it('renders with autocomplete enabled if default value is not a wildcard', () => { render( - + , ); const checkbox = screen.getByLabelText( - /all current and future projects/i + /all current and future projects/i, ); expect(checkbox).not.toBeChecked(); @@ -117,7 +117,7 @@ describe('SelectProjectInput', () => { { label: 'Project1', value: 'project1' }, { label: 'Project2', value: 'project2' }, ]} - /> + />, ); await user.click(screen.getByLabelText('Projects')); @@ -140,7 +140,7 @@ describe('SelectProjectInput', () => { { label: 'Charlie', value: 'charlie' }, { label: 'Alpaca', value: 'alpaca' }, ]} - /> + />, ); const input = await screen.findByLabelText('Projects'); await user.type(input, 'alp'); diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.tsx index 62c10564fa..8c48b76248 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.tsx @@ -48,10 +48,10 @@ export const SelectProjectInput: VFC = ({ onFocus, }) => { const [projects, setProjects] = useState( - typeof defaultValue === 'string' ? [defaultValue] : defaultValue + typeof defaultValue === 'string' ? [defaultValue] : defaultValue, ); const [isWildcardSelected, selectWildcard] = useState( - typeof defaultValue === 'string' || defaultValue.includes(ALL_PROJECTS) + typeof defaultValue === 'string' || defaultValue.includes(ALL_PROJECTS), ); const isAllSelected = projects.length > 0 && @@ -60,7 +60,7 @@ export const SelectProjectInput: VFC = ({ const onAllProjectsChange = ( e: ChangeEvent, - checked: boolean + checked: boolean, ) => { if (checked) { selectWildcard(true); @@ -82,12 +82,12 @@ export const SelectProjectInput: VFC = ({ const renderOption = ( props: object, option: IAutocompleteBoxOption, - { selected }: AutocompleteRenderOptionState + { selected }: AutocompleteRenderOptionState, ) => (

  • } - checkedIcon={} + icon={} + checkedIcon={} checked={selected} /> {option.label} @@ -114,11 +114,11 @@ export const SelectProjectInput: VFC = ({ {...params} error={Boolean(error)} helperText={error} - variant="outlined" - label="Projects" - placeholder="Select one or more projects" + variant='outlined' + label='Projects' + placeholder='Select one or more projects' onFocus={onFocus} - data-testid="select-input" + data-testid='select-input' /> ); @@ -127,14 +127,14 @@ export const SelectProjectInput: VFC = ({ } - label="ALL current and future projects" + label='ALL current and future projects' /> = ({ value={ isWildcardSelected || disabled ? options - : options.filter(option => - projects.includes(option.value) + : options.filter((option) => + projects.includes(option.value), ) } onChange={(_, input) => { diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/TokenInfo/TokenInfo.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/TokenInfo/TokenInfo.tsx index 86fbd6546e..0625f7dcf5 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/TokenInfo/TokenInfo.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/TokenInfo/TokenInfo.tsx @@ -22,9 +22,9 @@ export const TokenInfo = ({ setUsername(e.target.value)} - label="Token name" + name='username' + onChange={(e) => setUsername(e.target.value)} + label='Token name' error={errors.username !== undefined} errorText={errors.username} onFocus={() => clearErrors('username')} diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/TokenTypeSelector/TokenTypeSelector.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/TokenTypeSelector/TokenTypeSelector.tsx index 27553d19aa..192b220831 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/TokenTypeSelector/TokenTypeSelector.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/TokenTypeSelector/TokenTypeSelector.tsx @@ -29,13 +29,13 @@ export const TokenTypeSelector = ({ return ( - + What do you want to connect? setType(value as TokenType)} > @@ -59,8 +59,8 @@ export const TokenTypeSelector = ({ {label} {title} @@ -68,7 +68,7 @@ export const TokenTypeSelector = ({ } /> - ) + ), )} diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/useApiTokenForm.ts b/frontend/src/component/admin/apiToken/ApiTokenForm/useApiTokenForm.ts index 71422f61a3..7295120c1d 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/useApiTokenForm.ts +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/useApiTokenForm.ts @@ -16,12 +16,12 @@ export type ApiTokenFormErrorType = 'username' | 'projects'; export const useApiTokenForm = (project?: string) => { const { environments } = useEnvironments(); const { uiConfig } = useUiConfig(); - const initialEnvironment = environments?.find(e => e.enabled)?.name; + const initialEnvironment = environments?.find((e) => e.enabled)?.name; const hasCreateTokenPermission = useHasRootAccess(CREATE_CLIENT_API_TOKEN); const hasCreateProjectTokenPermission = useHasRootAccess( CREATE_PROJECT_API_TOKEN, - project + project, ); const apiTokenTypes: SelectOption[] = [ @@ -38,7 +38,7 @@ export const useApiTokenForm = (project?: string) => { const hasCreateFrontendAccess = useHasRootAccess(CREATE_FRONTEND_API_TOKEN); const hasCreateFrontendTokenAccess = useHasRootAccess( CREATE_PROJECT_API_TOKEN, - project + project, ); if (!project) { apiTokenTypes.push({ @@ -58,7 +58,7 @@ export const useApiTokenForm = (project?: string) => { }); } - const firstAccessibleType = apiTokenTypes.find(t => t.enabled)?.key; + const firstAccessibleType = apiTokenTypes.find((t) => t.enabled)?.key; const [username, setUsername] = useState(''); const [type, setType] = useState(firstAccessibleType || TokenType.CLIENT); @@ -99,10 +99,10 @@ export const useApiTokenForm = (project?: string) => { const isValid = () => { const newErrors: Partial> = {}; if (!username) { - newErrors['username'] = 'Username is required'; + newErrors.username = 'Username is required'; } if (projects.length === 0) { - newErrors['projects'] = 'At least one project is required'; + newErrors.projects = 'At least one project is required'; } setErrors(newErrors); diff --git a/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx b/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx index 94cd56b66f..537da13f5a 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenPage/ApiTokenPage.tsx @@ -34,7 +34,7 @@ export const ApiTokenPage = () => { setGlobalFilter, setHiddenColumns, columns, - } = useApiTokenTable(tokens, props => { + } = useApiTokenTable(tokens, (props) => { const READ_PERMISSION = props.row.original.type === 'client' ? READ_CLIENT_API_TOKEN @@ -91,7 +91,7 @@ export const ApiTokenPage = () => { CREATE_CLIENT_API_TOKEN, ADMIN, ]} - path="/admin/api/create-token" + path='/admin/api/create-token' /> } diff --git a/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx b/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx index 333c7f6f0e..8974757b13 100644 --- a/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx +++ b/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx @@ -25,21 +25,21 @@ export const ConfirmToken = ({ open={open} setOpen={setOpen} onClick={closeConfirm} - primaryButtonText="Close" - title="New token created" + primaryButtonText='Close' + title='New token created' > - + Your new token has been created successfully. + By default, all {TokenType.FRONTEND} tokens may be used from any CORS origin. If you'd like to configure a strict set of origins, please use the{' '} - + CORS origins configuration page . diff --git a/frontend/src/component/admin/apiToken/ConfirmToken/UserToken/UserToken.tsx b/frontend/src/component/admin/apiToken/ConfirmToken/UserToken/UserToken.tsx index 4a048cf84d..edc4f66e90 100644 --- a/frontend/src/component/admin/apiToken/ConfirmToken/UserToken/UserToken.tsx +++ b/frontend/src/component/admin/apiToken/ConfirmToken/UserToken/UserToken.tsx @@ -25,7 +25,7 @@ export const UserToken = ({ token }: IUserTokenProps) => { return ( ({ + sx={(theme) => ({ backgroundColor: theme.palette.background.elevation2, padding: theme.spacing(4), borderRadius: `${theme.shape.borderRadius}px`, @@ -37,8 +37,8 @@ export const UserToken = ({ token }: IUserTokenProps) => { })} > {token} - - + + diff --git a/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx b/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx index 37b11cb927..236d6a0ca2 100644 --- a/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx +++ b/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx @@ -66,8 +66,8 @@ export const CreateApiToken = ({ modal = false }: ICreateApiTokenProps) => { const payload = getApiTokenPayload(); await createToken(payload) - .then(res => res.json()) - .then(api => { + .then((res) => res.json()) + .then((api) => { scrollToTop(); setToken(api.secret); setShowConfirm(true); @@ -84,9 +84,7 @@ export const CreateApiToken = ({ modal = false }: ICreateApiTokenProps) => { }; const formatApiCode = () => { - return `curl --location --request POST '${ - uiConfig.unleashUrl - }/${PATH}' \\ + return `curl --location --request POST '${uiConfig.unleashUrl}/${PATH}' \\ --header 'Authorization: INSERT_API_KEY' \\ --header 'Content-Type: application/json' \\ --data-raw '${JSON.stringify(getApiTokenPayload(), undefined, 2)}'`; @@ -102,17 +100,17 @@ export const CreateApiToken = ({ modal = false }: ICreateApiTokenProps) => { title={pageTitle} modal={modal} description="Unleash SDKs use API tokens to authenticate to the Unleash API. Client SDKs need a token with 'client privileges', which allows them to fetch feature toggle configurations and post usage metrics." - documentationLink="https://docs.getunleash.io/reference/api-tokens-and-client-keys" - documentationLinkLabel="API tokens documentation" + documentationLink='https://docs.getunleash.io/reference/api-tokens-and-client-keys' + documentationLinkLabel='API tokens documentation' formatApiCode={formatApiCode} > { it('should prioritize new "projects" array over deprecated "project"', async () => { render( + />, ); const links = await screen.findAllByRole('link'); @@ -21,7 +21,7 @@ describe('ProjectsList', () => { }); it('should render correctly with single "project"', async () => { - render(); + render(); const links = await screen.findAllByRole('link'); expect(links).toHaveLength(1); diff --git a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx index 16351698e5..40abec2270 100644 --- a/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx +++ b/frontend/src/component/admin/apiToken/ProjectsList/ProjectsList.tsx @@ -23,7 +23,7 @@ export const ProjectsList: VFC = ({ project, }) => { const { searchQuery } = useSearchHighlightContext(); - let fields: string[] = + const fields: string[] = projects && Array.isArray(projects) ? projects : project diff --git a/frontend/src/component/admin/auth/AuthSettings.tsx b/frontend/src/component/admin/auth/AuthSettings.tsx index 2f14b9e501..7cc9f247bc 100644 --- a/frontend/src/component/admin/auth/AuthSettings.tsx +++ b/frontend/src/component/admin/auth/AuthSettings.tsx @@ -34,7 +34,7 @@ export const AuthSettings = () => { component: , }, ].filter( - item => uiConfig.flags?.googleAuthEnabled || item.label !== 'Google' + (item) => uiConfig.flags?.googleAuthEnabled || item.label !== 'Google', ); const [activeTab, setActiveTab] = useState(0); @@ -52,8 +52,8 @@ export const AuthSettings = () => { onChange={(_, tabId) => { setActiveTab(tabId); }} - indicatorColor="primary" - textColor="primary" + indicatorColor='primary' + textColor='primary' > {tabs.map((tab, index) => ( { > } + show={} /> + You are running Unleash in demo mode. You have to use the Enterprise edition in order configure Single Sign-on. @@ -90,7 +90,7 @@ export const AuthSettings = () => { + You have decided to use custom authentication type. You have to use the Enterprise edition in order configure Single Sign-on from the user @@ -101,7 +101,7 @@ export const AuthSettings = () => { + Your Unleash instance is managed by the Unleash team. @@ -113,6 +113,7 @@ export const AuthSettings = () => {
    {tabs.map((tab, index) => ( key={index} value={activeTab} index={index} diff --git a/frontend/src/component/admin/auth/AutoCreateForm/AutoCreateForm.tsx b/frontend/src/component/admin/auth/AutoCreateForm/AutoCreateForm.tsx index bc89340ad6..a8c9f12cd7 100644 --- a/frontend/src/component/admin/auth/AutoCreateForm/AutoCreateForm.tsx +++ b/frontend/src/component/admin/auth/AutoCreateForm/AutoCreateForm.tsx @@ -51,12 +51,12 @@ export const AutoCreateForm = ({ control={ } - label="Auto-create users" + label='Auto-create users' /> @@ -70,22 +70,22 @@ export const AutoCreateForm = ({ - + Default Role @@ -101,16 +101,16 @@ export const AutoCreateForm = ({ diff --git a/frontend/src/component/admin/auth/GoogleAuth/GoogleAuth.tsx b/frontend/src/component/admin/auth/GoogleAuth/GoogleAuth.tsx index d871b6f2ef..931392ec88 100644 --- a/frontend/src/component/admin/auth/GoogleAuth/GoogleAuth.tsx +++ b/frontend/src/component/admin/auth/GoogleAuth/GoogleAuth.tsx @@ -69,17 +69,17 @@ export const GoogleAuth = () => { return ( <> - + This integration is deprecated and will be removed in next major version. Please use OpenID Connect to enable Google SSO. - + Read the{' '} documentation {' '} @@ -103,7 +103,7 @@ export const GoogleAuth = () => { } @@ -122,13 +122,13 @@ export const GoogleAuth = () => { @@ -144,13 +144,13 @@ export const GoogleAuth = () => { @@ -172,13 +172,13 @@ export const GoogleAuth = () => { @@ -193,7 +193,7 @@ export const GoogleAuth = () => { @@ -209,24 +209,24 @@ export const GoogleAuth = () => { @@ -304,13 +302,13 @@ export const IntegrationForm: VFC = ({ )} />
    @@ -377,9 +375,9 @@ export const IntegrationForm: VFC = ({ options={selectableProjects} selectedItems={formValues.projects || []} onChange={setProjects} - entityName="project" - description="Selecting project(s) will filter events, so that your integration only receives events related to those specific projects." - note="If no projects are selected, the integration will receive events from all projects." + entityName='project' + description='Selecting project(s) will filter events, so that your integration only receives events related to those specific projects.' + note='If no projects are selected, the integration will receive events from all projects.' />
    @@ -387,9 +385,9 @@ export const IntegrationForm: VFC = ({ options={selectableEnvironments} selectedItems={formValues.environments || []} onChange={setEnvironments} - entityName="environment" - description="Selecting environment(s) will filter events, so that your integration only receives events related to those specific environments. Global events that are not specific to an environment will still be received." - note="If no environments are selected, the integration will receive events from all environments." + entityName='environment' + description='Selecting environment(s) will filter events, so that your integration only receives events related to those specific environments. Global events that are not specific to an environment will still be received.' + note='If no environments are selected, the integration will receive events from all environments.' />
    diff --git a/frontend/src/component/integrations/IntegrationForm/IntegrationInstall/IntegrationInstall.tsx b/frontend/src/component/integrations/IntegrationForm/IntegrationInstall/IntegrationInstall.tsx index 3912a85b46..47039e84c0 100644 --- a/frontend/src/component/integrations/IntegrationForm/IntegrationInstall/IntegrationInstall.tsx +++ b/frontend/src/component/integrations/IntegrationForm/IntegrationInstall/IntegrationInstall.tsx @@ -28,11 +28,11 @@ export const IntegrationInstall = ({
    + )} /> @@ -54,7 +54,7 @@ test('should fetch initial form data from local storage', async () => { expect(screen.getByText('Unleash playground')).toBeInTheDocument(); expect(screen.getByText('["projectA","projectB"]')).toBeInTheDocument(); expect( - screen.getByText('["development","production"]') + screen.getByText('["development","production"]'), ).toBeInTheDocument(); expect(screen.getByText('{"userId":"1"}')).toBeInTheDocument(); }); @@ -88,7 +88,7 @@ test('should display error on submit', async () => { details: [{ message: 'some error about too many items' }], }, 'post', - 400 + 400, ); render(testEvaluateComponent); diff --git a/frontend/src/component/playground/Playground/AdvancedPlayground.tsx b/frontend/src/component/playground/Playground/AdvancedPlayground.tsx index e6649c68c6..6bb3557365 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlayground.tsx +++ b/frontend/src/component/playground/Playground/AdvancedPlayground.tsx @@ -37,7 +37,7 @@ export const AdvancedPlayground: VFC<{ } = { projects: [], environments: [] }; const { value, setValue } = createLocalStorage( 'AdvancedPlayground:v1', - defaultSettings + defaultSettings, ); const { environments: availableEnvironments } = useEnvironments(); @@ -46,7 +46,7 @@ export const AdvancedPlayground: VFC<{ const [configurationError, setConfigurationError] = useState(); const [environments, setEnvironments] = useState( - value.environments + value.environments, ); const [projects, setProjects] = useState(value.projects); const [context, setContext] = useState(value.context); @@ -81,7 +81,7 @@ export const AdvancedPlayground: VFC<{ await evaluatePlaygroundContext( environments || [], projects || '*', - context + context, ); } }; @@ -91,7 +91,7 @@ export const AdvancedPlayground: VFC<{ setToastData({ type: 'error', title: `Failed to parse URL parameters: ${formatUnknownError( - error + error, )}`, }); } @@ -108,7 +108,7 @@ export const AdvancedPlayground: VFC<{ }; const resolveProjectsFromUrl = (): string[] | null => { let projectsArray: string[] | null = null; - let projectsFromUrl = searchParams.get('projects'); + const projectsFromUrl = searchParams.get('projects'); if (projectsFromUrl) { projectsArray = projectsFromUrl.split(','); setProjects(projectsArray); @@ -128,7 +128,7 @@ export const AdvancedPlayground: VFC<{ environments: string[] | string, projects: string[] | string, context: string | undefined, - action?: () => void + action?: () => void, ) => { try { setConfigurationError(undefined); @@ -153,7 +153,7 @@ export const AdvancedPlayground: VFC<{ setToastData({ type: 'error', title: `Error parsing context: ${formatUnknownError( - error + error, )}`, }); } else { @@ -165,7 +165,7 @@ export const AdvancedPlayground: VFC<{ } }; - const onSubmit: FormEventHandler = async event => { + const onSubmit: FormEventHandler = async (event) => { event.preventDefault(); setHasFormBeenSubmitted(true); @@ -210,7 +210,7 @@ export const AdvancedPlayground: VFC<{ } /> } @@ -255,7 +255,7 @@ export const AdvancedPlayground: VFC<{ ({ + sx={(theme) => ({ width: resultsWidth, transition: 'width 0.4s ease', padding: theme.spacing(4, 4), @@ -264,7 +264,7 @@ export const AdvancedPlayground: VFC<{ + {configurationError} } @@ -289,8 +289,7 @@ export const AdvancedPlayground: VFC<{ /> } /> diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentCell.tsx b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentCell.tsx index 605f4eed86..cb08adfb95 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentCell.tsx +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentCell.tsx @@ -16,7 +16,7 @@ import { PlaygroundEnvironmentTable } from '../../PlaygroundEnvironmentTable/Pla const StyledContainer = styled( 'div', - {} + {}, )(({ theme }) => ({ flexGrow: 0, ...flexRow, @@ -47,8 +47,10 @@ export const AdvancedPlaygroundEnvironmentCell = ({ const open = Boolean(anchor); - const enabled = (value || []).filter(evaluation => evaluation.isEnabled); - const disabled = (value || []).filter(evaluation => !evaluation.isEnabled); + const enabled = (value || []).filter((evaluation) => evaluation.isEnabled); + const disabled = (value || []).filter( + (evaluation) => !evaluation.isEnabled, + ); return ( @@ -95,7 +97,7 @@ export const AdvancedPlaygroundEnvironmentCell = ({ horizontal: -320, }} > - + {value[0].environment} diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell.tsx b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell.tsx index d650abfc5a..32ffd4e006 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell.tsx +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell.tsx @@ -6,7 +6,7 @@ import { PlaygroundEnvironmentDiffTable } from '../../PlaygroundEnvironmentTable const StyledContainer = styled( 'div', - {} + {}, )(({ theme }) => ({ flexGrow: 0, ...flexRow, @@ -64,7 +64,7 @@ export const AdvancedPlaygroundEnvironmentDiffCell = ({ horizontal: -320, }} > - + Environments diff diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.test.tsx b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.test.tsx index 42e76372d3..90ca2b564d 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.test.tsx +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.test.tsx @@ -103,7 +103,7 @@ test('should render advanced playground table', async () => { }, }} /> - + , ); expect(screen.getByText('Infinite')).toBeInTheDocument(); diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx index 9aafa8d537..0772a120f5 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/AdvancedPlaygroundResultsTable.tsx @@ -35,7 +35,7 @@ import { countCombinations } from './combinationCounter'; const defaultSort: SortingRule = { id: 'name' }; const { value, setValue } = createLocalStorage( 'AdvancedPlaygroundResultsTable:v1', - defaultSort + defaultSort, ); interface IAdvancedPlaygroundResultsTableProps { @@ -62,7 +62,7 @@ export const AdvancedPlaygroundResultsTable = ({ const [searchParams, setSearchParams] = useSearchParams(); const ref = useLoading(loading); const [searchValue, setSearchValue] = useState( - searchParams.get('search') || '' + searchParams.get('search') || '', ); const theme = useTheme(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('md')); @@ -186,7 +186,7 @@ export const AdvancedPlaygroundResultsTable = ({ }, useGlobalFilter, useFlexLayout, - useSortBy + useSortBy, ); useConditionallyHiddenColumns( @@ -197,7 +197,7 @@ export const AdvancedPlaygroundResultsTable = ({ }, ], setHiddenColumns, - COLUMNS + COLUMNS, ); useEffect(() => { @@ -235,7 +235,7 @@ export const AdvancedPlaygroundResultsTable = ({ mb: 3, }} > - + {features !== undefined && !loading ? `Results (${ rows.length < data.length diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.test.ts b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.test.ts index 5214acad7f..86f653a982 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.test.ts +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.test.ts @@ -7,7 +7,7 @@ import { import cartesian from 'cartesian'; const generateFeature = ( - context: Record + context: Record, ): AdvancedPlaygroundEnvironmentFeatureSchema => ({ isEnabled: false, isEnabledInCurrentEnvironment: true, @@ -56,7 +56,7 @@ const generateFeature = ( const generateInput = ( featureCount: number, environments: string[], - contextValues: { [key: string]: string[] } + contextValues: { [key: string]: string[] }, ): AdvancedPlaygroundFeatureSchema[] => { const cartesianContext = cartesian(contextValues); @@ -64,10 +64,10 @@ const generateInput = ( name: `feature-${i}`, projectId: 'default', environments: Object.fromEntries( - environments.map(env => [ + environments.map((env) => [ env, cartesianContext.map(generateFeature), - ]) + ]), ), })); }; @@ -76,13 +76,13 @@ it('counts the correct number of combinations', () => { const assertCount = ( numberOfFeatures: number, envs: string[], - context: { [k: string]: string[] } + context: { [k: string]: string[] }, ) => { const totalCombinations = numberOfFeatures * envs.length * Object.values(context) - .map(contextValues => contextValues.length) + .map((contextValues) => contextValues.length) .reduce((total, n) => total + n); const input = generateInput(numberOfFeatures, envs, context); expect(countCombinations(input)).toEqual(totalCombinations); diff --git a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.ts b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.ts index 6608f7d20b..70b2412cba 100644 --- a/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.ts +++ b/frontend/src/component/playground/Playground/AdvancedPlaygroundResultsTable/combinationCounter.ts @@ -1,12 +1,13 @@ import { AdvancedPlaygroundFeatureSchema } from 'openapi'; export const countCombinations = ( - features: AdvancedPlaygroundFeatureSchema[] + features: AdvancedPlaygroundFeatureSchema[], ) => features.reduce( (total, feature) => total + - Object.values(feature.environments).flatMap(env => Object.keys(env)) - .length, - 0 + Object.values(feature.environments).flatMap((env) => + Object.keys(env), + ).length, + 0, ); diff --git a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.test.tsx b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.test.tsx index 48f1726eac..7e90c4de88 100644 --- a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.test.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.test.tsx @@ -54,7 +54,7 @@ test('should render environment diff table', async () => { ], }} /> - + , ); expect(screen.getByText('web')).toBeInTheDocument(); diff --git a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.tsx b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.tsx index bd53c46fb6..1b85b42200 100644 --- a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentDiffTable.tsx @@ -30,25 +30,25 @@ export const PlaygroundEnvironmentDiffTable = ({ () => firstEnvFeatures.map((item, index) => ({ ...Object.fromEntries( - environments.map(env => [env, features[env][index]]) + environments.map((env) => [env, features[env][index]]), ), })), - [JSON.stringify(features)] + [JSON.stringify(features)], ); type RowType = typeof data[0]; const contextFieldsHeaders = Object.keys(firstContext).map( - contextField => ({ + (contextField) => ({ Header: capitalizeFirst(contextField), accessor: ( - row: Record }> - ) => row[environments[0]]['context'][contextField], + row: Record }>, + ) => row[environments[0]].context[contextField], minWidth: 160, Cell: HighlightCell, - }) + }), ); - const environmentHeaders = environments.map(environment => ({ + const environmentHeaders = environments.map((environment) => ({ Header: environment, accessor: (row: RowType) => row[environment]?.isEnabled @@ -91,7 +91,7 @@ export const PlaygroundEnvironmentDiffTable = ({ }, useGlobalFilter, useFlexLayout, - useSortBy + useSortBy, ); const parentRef = useRef(null); diff --git a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx index 3b6c9a1ac7..22e0c992d3 100644 --- a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.test.tsx @@ -35,7 +35,7 @@ test('should render environment table', async () => { }, ]} /> - + , ); expect(screen.getByText('web')).toBeInTheDocument(); diff --git a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx index b508ad17a4..da75b9e02c 100644 --- a/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundEnvironmentTable/PlaygroundEnvironmentTable.tsx @@ -31,13 +31,13 @@ export const PlaygroundEnvironmentTable = ({ const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); const dynamicHeaders = Object.keys(features[0].context).map( - contextField => ({ + (contextField) => ({ Header: capitalizeFirst(contextField), accessor: (row: { context: Record }) => - row['context'][contextField], + row.context[contextField], minWidth: 160, Cell: HighlightCell, - }) + }), ); const COLUMNS = useMemo(() => { @@ -111,7 +111,7 @@ export const PlaygroundEnvironmentTable = ({ }, useGlobalFilter, useFlexLayout, - useSortBy + useSortBy, ); useConditionallyHiddenColumns( @@ -122,7 +122,7 @@ export const PlaygroundEnvironmentTable = ({ }, ], setHiddenColumns, - COLUMNS + COLUMNS, ); const parentRef = useRef(null); diff --git a/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx b/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx index dc42aba023..78f6a784ba 100644 --- a/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundForm/PlaygroundCodeFieldset/PlaygroundCodeFieldset.tsx @@ -64,7 +64,7 @@ export const PlaygroundCodeFieldset: VFC = ({ setFieldExist( contextValue[contextField] !== undefined || contextValue?.properties?.[contextField] !== - undefined + undefined, ); } catch (error: unknown) { return setError(formatUnknownError(error)); @@ -72,7 +72,7 @@ export const PlaygroundCodeFieldset: VFC = ({ return setError(undefined); }, 250), - [setError, contextField, setFieldExist] + [setError, contextField, setFieldExist], ); useEffect(() => { @@ -90,12 +90,12 @@ export const PlaygroundCodeFieldset: VFC = ({ [contextField]: contextValue, }), null, - 2 - ) + 2, + ), ); const foundContext = contextData.find( - context => context.name === contextField + (context) => context.name === contextField, ); if ( @@ -115,7 +115,7 @@ export const PlaygroundCodeFieldset: VFC = ({ const changeContextValue = ( e: FormEvent, - newValue: string | (string | string[])[] | null + newValue: string | (string | string[])[] | null, ) => { if (!isStringOrStringArray(newValue)) return; @@ -137,7 +137,7 @@ export const PlaygroundCodeFieldset: VFC = ({ // Split comma separated strings to array for fields with legal values const foundField = contextData.find( - contextData => contextData.name === contextField + (contextData) => contextData.name === contextField, ); const hasLegalValues = (foundField?.legalValues || []).length > 1; if (contextValue.includes(',') && hasLegalValues) { @@ -158,13 +158,13 @@ export const PlaygroundCodeFieldset: VFC = ({ return ( { + onChange={(e) => { const parsedDate = parseValidDate(e.target.value); const dateString = parsedDate?.toISOString(); dateString && setContextValue(dateString); @@ -177,29 +177,25 @@ export const PlaygroundCodeFieldset: VFC = ({ ); } const foundField = contextData.find( - contextData => contextData.name === contextField + (contextData) => contextData.name === contextField, ); - if ( - foundField && - foundField.legalValues && - foundField.legalValues.length > 0 - ) { + if (foundField?.legalValues && foundField.legalValues.length > 0) { const options = foundField.legalValues.map(({ value }) => value); return ( ( - + )} disableCloseOnSelect={false} /> @@ -208,13 +204,13 @@ export const PlaygroundCodeFieldset: VFC = ({ return ( setContextValue(event.target.value || '')} + onChange={(event) => setContextValue(event.target.value || '')} /> ); }; @@ -233,7 +229,7 @@ export const PlaygroundCodeFieldset: VFC = ({ @@ -243,20 +239,20 @@ export const PlaygroundCodeFieldset: VFC = ({ - + Context field { }, }} > - {possibleLocales.map(locale => { + {possibleLocales.map((locale) => { return ( securing Unleash on GitHub @@ -57,13 +57,13 @@ const SimpleAuth: VFC = ({ authDetails, redirect }) => { value={email} onChange={handleChange} inputProps={{ 'data-testid': 'email-input-field' }} - size="small" - variant="outlined" - label="Email" - name="email" - id="email" + size='small' + variant='outlined' + label='Email' + name='email' + id='email' required - type="email" + type='email' data-testid={LOGIN_EMAIL_ID} autoFocus /> @@ -71,9 +71,9 @@ const SimpleAuth: VFC = ({ authDetails, redirect }) => {
    @@ -48,7 +48,7 @@ const InvalidToken: VFC = () => { + Provided invite link is invalid or expired. Please request a new URL in order to create your account. @@ -56,17 +56,17 @@ const InvalidToken: VFC = () => { } elseShow={ <> - + Your token has either been used to reset your password, or it has expired. Please request a new reset password URL in order to reset your password.