From 0c9ad19ad5d13eb88f46dbd6e7e88c03ce858276 Mon Sep 17 00:00:00 2001 From: Codemod Bot Date: Fri, 9 Aug 2024 16:13:54 +0200 Subject: [PATCH] refactor: remove ConditionallyRender with codemod Co-authored-by: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> --- frontend/src/component/App.tsx | 95 +++-- frontend/src/component/admin/Admin.tsx | 6 +- .../apiToken/ApiTokenForm/ApiTokenForm.tsx | 22 +- .../SelectProjectInput/SelectProjectInput.tsx | 16 +- .../apiToken/ConfirmToken/ConfirmToken.tsx | 26 +- .../CreateApiToken/CreateApiToken.tsx | 20 +- .../src/component/admin/auth/AuthSettings.tsx | 138 +++---- .../admin/auth/OidcAuth/OidcAuth.tsx | 34 +- .../admin/auth/SamlAuth/SamlAuth.tsx | 34 +- .../admin/auth/ScimSettings/ScimSettings.tsx | 24 +- .../component/admin/auth/SsoGroupSettings.tsx | 58 ++- .../admin/banners/BannerModal/BannerForm.tsx | 246 ++++++------ .../banners/BannersTable/BannersTable.tsx | 78 ++-- .../src/component/admin/billing/Billing.tsx | 33 +- .../BillingInformation/BillingInformation.tsx | 16 +- .../BillingPlan/BillingPlan.tsx | 279 +++++++------- .../billing/BillingHistory/BillingHistory.tsx | 8 +- .../component/admin/groups/Group/Group.tsx | 278 +++++++------- .../admin/groups/GroupForm/GroupForm.tsx | 82 ++-- .../GroupFormUsersTable.tsx | 18 +- .../groups/GroupsList/GroupCard/GroupCard.tsx | 63 ++-- .../admin/groups/GroupsList/GroupsList.tsx | 104 +++--- .../InstancePrivacySection.tsx | 37 +- .../component/admin/invoice/InvoiceList.tsx | 159 ++++---- .../src/component/admin/license/License.tsx | 96 +++-- .../component/admin/menu/AdminTabsMenu.tsx | 20 +- .../network/NetworkTraffic/NetworkTraffic.tsx | 29 +- .../NetworkTrafficUsage.tsx | 128 +++---- .../NetworkTrafficUsagePlanSummary.tsx | 107 +++--- .../admin/roles/RoleForm/RoleForm.tsx | 26 +- .../src/component/admin/roles/RolesPage.tsx | 37 +- .../RoleDeleteDialogProjectRole.tsx | 60 ++- .../RoleDeleteDialogRootRole.tsx | 112 +++--- .../roles/RolesTable/RolesCell/RolesCell.tsx | 8 +- .../admin/roles/RolesTable/RolesTable.tsx | 44 +-- .../admin/serviceAccounts/ServiceAccounts.tsx | 17 +- .../ServiceAccountDeleteDialog.tsx | 39 +- .../ServiceAccountModal.tsx | 153 ++++---- .../ServiceAccountTokens.tsx | 116 +++--- .../ServiceAccountsTable.tsx | 80 ++-- .../admin/users/AccessMatrix/AccessMatrix.tsx | 13 +- .../users/AccessMatrix/PermissionsTable.tsx | 10 +- .../DeleteInactiveUsers.tsx | 24 +- .../DeleteUser/DeleteUser.tsx | 22 +- .../InactiveUsersList/InactiveUsersList.tsx | 35 +- .../admin/users/InviteLink/InviteLink.tsx | 22 +- .../InviteLinkBar/InviteLinkBarContent.tsx | 53 +-- .../admin/users/UserForm/UserForm.tsx | 39 +- .../src/component/admin/users/UsersAdmin.tsx | 16 +- .../users/UsersList/DeleteUser/DeleteUser.tsx | 22 +- .../UsersList/UserTypeCell/UserTypeCell.tsx | 17 +- .../UsersActionsCell/UsersActionsCell.tsx | 30 +- .../admin/users/UsersList/UsersList.tsx | 118 +++--- .../src/component/application/Application.tsx | 29 +- .../ApplicationIssues/ApplicationIssues.tsx | 72 ++-- .../ApplicationUsageCell.tsx | 25 +- .../PaginatedApplicationList.tsx | 27 +- .../application/ApplicationOverview.tsx | 73 ++-- .../ConnectedInstances/ConnectedInstances.tsx | 46 ++- .../ConnectedInstancesTable.tsx | 20 +- .../archive/ArchiveTable/ArchiveTable.tsx | 65 ++-- .../ArchivedFeatureReviveConfirm.tsx | 35 +- .../EdgeUpgradeBanner/EdgeUpgradeBanner.tsx | 8 +- .../OutdatedSdksBanner/OutdatedSdksBanner.tsx | 8 +- .../ChangeRequest/ChangeRequest.tsx | 28 +- .../Changes/Change/ChangeActions.tsx | 172 ++++----- .../Changes/Change/ConflictWarning.tsx | 37 +- .../Changes/Change/FeatureChange.tsx | 81 ++-- .../Changes/Change/StrategyChange.tsx | 104 +++--- .../Change/VariantPatch/VariantPatch.tsx | 26 +- .../NameWithChangeInfo/NameWithChangeInfo.tsx | 31 +- .../ChangeRequestConfirmDialog.tsx | 26 +- .../ChangeRequestOverview.tsx | 232 ++++++------ .../ChangeRequestApprovals.tsx | 7 +- .../ChangeRequestReviewers.tsx | 17 +- .../ChangeRequestTitle.tsx | 81 ++-- .../EnvironmentChangeRequest.tsx | 104 +++--- .../ChangeRequestsTabs/ChangeRequestsTabs.tsx | 40 +- .../ChangeRequestsTabs/FeaturesCell.tsx | 53 ++- .../component/changeRequest/UpdateCount.tsx | 36 +- .../src/component/commandBar/CommandBar.tsx | 137 +++---- .../commandBar/CommandBarFeedback.tsx | 79 ++-- .../commandBar/CommandSearchFeatures.tsx | 20 +- .../RecentlyVisited/CommandResultGroup.tsx | 11 +- .../common/AnimateOnMount/AnimateOnMount.tsx | 19 +- .../common/ApiTokenTable/ApiTokenTable.tsx | 85 +++-- .../common/AvatarGroup/AvatarGroup.tsx | 14 +- frontend/src/component/common/Badge/Badge.tsx | 39 +- .../common/BreadcrumbNav/BreadcrumbNav.tsx | 76 ++-- .../ConstraintAccordion.tsx | 33 +- .../ConstraintAccordionEditBody.tsx | 8 +- .../RestrictiveLegalValues.tsx | 48 +-- .../SingleLegalValue/SingleLegalValue.tsx | 96 ++--- .../ConstraintAccordionEditHeader.tsx | 29 +- .../CaseSensitiveButton.tsx | 37 +- .../InvertedOperatorButton.tsx | 37 +- .../ConstraintAccordionHeaderActions.tsx | 51 ++- .../ConstraintAccordionList.tsx | 80 ++-- .../MultipleValues/MultipleValues.tsx | 13 +- .../ConstraintAccordionViewHeaderInfo.tsx | 35 +- ...raintAccordionViewHeaderMultipleValues.tsx | 20 +- .../ConstraintViewHeaderOperator.tsx | 43 +-- .../StyledIconWrapper.tsx | 15 +- .../component/common/Dialogue/Dialogue.tsx | 70 ++-- .../ExperimentalFeedback.tsx | 64 ++-- .../FavoriteIconButton/FavoriteIconButton.tsx | 47 ++- .../FeatureArchiveDialog.tsx | 128 +++---- .../FeatureStaleDialog/FeatureStaleDialog.tsx | 7 +- .../common/FormTemplate/FormTemplate.tsx | 155 ++++---- .../common/InstanceStatus/InstanceStatus.tsx | 24 +- frontend/src/component/common/Limit/Limit.tsx | 54 ++- .../common/MainHeader/MainHeader.tsx | 16 +- .../MultipleRoleSelect/MultipleRoleSelect.tsx | 26 +- .../ConstraintAccordionEditBody.tsx | 8 +- .../FreeTextInput/FreeTextInput.tsx | 20 +- .../RestrictiveLegalValues.tsx | 86 ++--- .../SingleLegalValue/SingleLegalValue.tsx | 102 +++-- .../ConstraintAccordionEditHeader.tsx | 29 +- .../CaseSensitiveButton.tsx | 37 +- .../InvertedOperatorButton.tsx | 37 +- .../ConstraintAccordionHeaderActions.tsx | 82 ++-- .../MultipleValues/MultipleValues.tsx | 13 +- .../ConstraintAccordionViewHeaderInfo.tsx | 35 +- ...raintAccordionViewHeaderMultipleValues.tsx | 20 +- .../ConstraintViewHeaderOperator.tsx | 43 +-- .../StyledIconWrapper.tsx | 15 +- .../ConstraintValueSearch.tsx | 18 +- .../NewConstraintAccordion.tsx | 35 +- .../NewConstraintAccordionList.tsx | 7 +- .../common/Notifications/Notifications.tsx | 125 +++---- .../common/PageContent/PageContent.tsx | 24 +- .../common/PageHeader/PageHeader.tsx | 8 +- .../common/PremiumFeature/PremiumFeature.tsx | 104 +++--- .../PrettifyLargeNumber.tsx | 17 +- .../common/Proclamation/Proclamation.tsx | 32 +- .../ResponsiveButton/ResponsiveButton.tsx | 61 ++- .../RoleDescription/RoleDescription.tsx | 50 ++- .../common/RoleSelect/RoleSelect.tsx | 10 +- .../src/component/common/Search/Search.tsx | 83 ++--- .../SearchDescription/SearchDescription.tsx | 57 ++- .../SearchSuggestions/SearchHistory.tsx | 34 +- .../SearchInstructions/SearchInstructions.tsx | 51 ++- .../SearchSuggestions/SearchSuggestions.tsx | 61 ++- .../common/SegmentItem/SegmentItem.tsx | 77 ++-- .../StrategyItemContainer.tsx | 82 ++-- .../StrategySeparator/StrategySeparator.tsx | 13 +- .../StringTruncator/StringTruncator.tsx | 45 +-- .../FavoriteIconHeader/FavoriteIconHeader.tsx | 11 +- .../Table/PaginatedTable/PaginatedTable.tsx | 58 ++- .../Table/PaginationBar/PaginationBar.tsx | 43 +-- .../CellSortable/CellSortable.tsx | 69 ++-- .../CellSortable/SortArrow/SortArrow.tsx | 72 ++-- .../FavoriteIconCell/FavoriteIconCell.tsx | 31 +- .../FeatureOverviewCell.tsx | 117 +++--- .../cells/FeatureSeenCell/FeatureSeenCell.tsx | 55 ++- .../cells/FeatureSeenCell/LastSeenTooltip.tsx | 121 +++--- .../cells/HighlightCell/HighlightCell.tsx | 33 +- .../common/Table/cells/LinkCell/LinkCell.tsx | 31 +- .../component/common/ThemeMode/ThemeMode.tsx | 9 +- .../common/ToastRenderer/Toast/Toast.tsx | 10 +- .../common/UserAvatar/UserAvatar.tsx | 7 +- .../ContectFormChip/ContextFormChip.tsx | 10 +- .../context/ContextList/AddContextButton.tsx | 43 +-- .../ContextList/ContextList/ContextList.tsx | 43 ++- frontend/src/component/demo/Demo.tsx | 160 ++++---- .../DemoDialogFinish/DemoDialogFinish.tsx | 22 +- .../DemoStepTooltip/DemoStepTooltip.tsx | 114 +++--- .../component/demo/DemoTopics/DemoTopics.tsx | 11 +- .../CreateEnvironment/CreateEnvironment.tsx | 142 ++++--- .../EnvironmentActionCellPopover.tsx | 11 +- .../EnvironmentCloneModal.tsx | 44 +-- .../EnvironmentProjectSelect.tsx | 16 +- .../EnvironmentDeprecateToggleDialog.tsx | 37 +- .../EnvironmentNameCell.tsx | 53 ++- .../EnvironmentTable/EnvironmentTable.tsx | 44 +-- .../EnvironmentTableSingle.tsx | 28 +- .../component/events/EventCard/EventCard.tsx | 89 ++--- .../component/events/EventLog/EventLog.tsx | 72 ++-- .../feature/CopyFeature/CopyFeature.tsx | 34 +- .../feature/CreateFeature/CreateFeature.tsx | 38 +- .../Dependencies/AddDependencyDialogue.tsx | 86 ++--- .../feature/FeatureForm/FeatureForm.tsx | 23 +- .../FeatureNamingPatternInfo.tsx | 31 +- ...FeatureStrategyConstraintAccordionList.tsx | 126 +++---- .../FeatureStrategyCreate.tsx | 20 +- .../CopyButton/CopyButton.tsx | 14 +- .../FeatureStrategyEmpty.tsx | 23 +- .../FeatureStrategyEnabled.tsx | 34 +- .../FeatureStrategyForm.tsx | 229 +++++------- .../FeatureStrategyMenuCards.tsx | 38 +- .../FeatureStrategySegmentChip.tsx | 14 +- .../FeatureStrategySegmentList.tsx | 26 +- .../FeatureToggleList/BulkDisableDialog.tsx | 33 +- .../FeatureToggleList/BulkEnableDialog.tsx | 33 +- .../FeatureToggleList/ExportDialog.tsx | 27 +- .../FeatureStaleCell/FeatureStaleCell.tsx | 23 +- .../FeatureToggleListActions.tsx | 46 +-- .../FeatureToggleListTable.tsx | 188 ++++------ .../FeatureMetrics/FeatureMetrics.tsx | 97 +++-- .../FeatureLifecycleTooltip.tsx | 25 +- .../MarkCompletedDialogue.tsx | 53 ++- .../EnvironmentAccordionBody.tsx | 181 ++++----- .../StrategyDraggableItem.tsx | 21 +- .../CopyStrategyIconMenu.tsx | 14 +- .../DisableEnableStrategyDialog.tsx | 25 +- .../ConstraintItem/ConstraintItem.tsx | 48 ++- .../StrategyExecution/StrategyExecution.tsx | 74 ++-- .../StrategyItem/StrategyItem.tsx | 21 +- .../FeatureOverviewEnvironment.tsx | 182 ++++----- .../FeatureOverviewMetaData/DependencyRow.tsx | 190 ++++------ .../FeatureOverviewMetaData.tsx | 209 +++++------ .../FeatureOverviewSegment.tsx | 6 +- ...atureOverviewSidePanelEnvironmentHider.tsx | 11 +- ...reOverviewSidePanelEnvironmentSwitches.tsx | 16 +- .../FeatureOverviewSidePanelTags.tsx | 33 +- .../ManageTagsDialog/ManageBulkTagsDialog.tsx | 43 +-- .../ManageTagsDialog/TagsInput.tsx | 31 +- .../FeatureSettings/FeatureSettings.tsx | 23 +- .../FeatureSettingsProjectConfirm.tsx | 199 +++++----- .../EnvironmentVariantsCard.tsx | 85 ++--- .../EnvironmentVariantsTable.tsx | 28 +- .../EnvironmentVariantsCopyFrom.tsx | 89 ++--- .../EnvironmentVariantsModal.tsx | 110 +++--- .../VariantForm/VariantForm.tsx | 168 ++++----- .../VariantOverrides/VariantOverrides.tsx | 74 ++-- .../FeatureEnvironmentVariants.tsx | 103 +++--- .../PushVariantsButton/PushVariantsButton.tsx | 114 +++--- .../feature/FeatureView/FeatureView.tsx | 97 ++--- .../StrategyTypes/NewStrategyVariants.tsx | 8 +- .../SplitPreviewSlider/SplitPreviewSlider.tsx | 18 +- .../StrategyInputList/StrategyInputList.tsx | 105 +++--- .../feedback/FeedbackNPS/FeedbackNPS.tsx | 78 ++-- .../feedbackNew/FeedbackComponent.tsx | 349 ++++++++---------- .../component/feedbackNew/FeedbackList.tsx | 37 +- .../FilterItemChip/FilterItemChip.tsx | 68 ++-- .../src/component/filter/Filters/Filters.tsx | 23 +- .../src/component/insights/InsightsCharts.tsx | 322 ++++++++-------- .../insights/LegacyInsightsCharts.tsx | 233 ++++++------ .../insights/components/Gauge/Gauge.tsx | 22 +- .../InsightsHeader/InsightsHeader.tsx | 25 +- .../LineChart/LineChartComponent.tsx | 35 +- .../insights/components/Widget/Widget.tsx | 14 +- .../components/WidgetTitle/WidgetTitle.tsx | 14 +- .../MetricsChartTooltip.tsx | 61 ++- .../HealthChartTooltip/HealthChartTooltip.tsx | 10 +- .../componentsStat/FlagStats/FlagStats.tsx | 45 +-- .../componentsStat/UserStats/UserStats.tsx | 90 ++--- .../IntegrationEventsModal.tsx | 27 +- .../IntegrationForm/IntegrationForm.tsx | 52 ++- .../AvailableIntegrations.tsx | 20 +- .../ConfiguredIntegrations.tsx | 38 +- .../IntegrationCard/IntegrationCard.tsx | 47 +-- .../IntegrationCardMenu.tsx | 35 +- .../IntegrationList/IntegrationList.tsx | 18 +- frontend/src/component/layout/Error/Error.tsx | 21 +- .../layout/LayoutPicker/LayoutPicker.tsx | 9 +- .../MainLayout/DraftBanner/DraftBanner.tsx | 65 ++-- .../layout/MainLayout/MainLayout.tsx | 27 +- .../NavigationSidebar/NavigationList.tsx | 24 +- .../LoginHistoryTable/LoginHistoryTable.tsx | 112 +++--- .../menu/Footer/ApiDetails/ApiDetails.tsx | 26 +- .../menu/Header/DrawerMenu/DrawerMenu.tsx | 83 ++--- frontend/src/component/menu/Header/Header.tsx | 42 +-- .../Header/InviteLink/InviteLinkContent.tsx | 18 +- .../Header/NavigationLink/NavigationLink.tsx | 14 +- .../Header/NavigationMenu/NavigationMenu.tsx | 14 +- .../src/component/menu/Header/OldHeader.tsx | 51 ++- .../Playground/AdvancedPlayground.tsx | 68 ++-- .../AdvancedPlaygroundEnvironmentCell.tsx | 35 +- .../AdvancedPlaygroundResultsTable.tsx | 72 ++-- .../PlaygroundEditor/PlaygroundEditor.tsx | 29 +- .../PlaygroundConnectionFieldset.tsx | 82 ++-- .../PlaygroundGuidanceSection.tsx | 14 +- .../FeatureDetails/FeatureDetails.tsx | 59 ++- .../PlaygroundResultFeatureStrategyList.tsx | 67 ++-- .../StrategyItem/FeatureStrategyItem.tsx | 29 +- .../ConstraintExecution.tsx | 24 +- .../ConstraintExecutionWithoutResults.tsx | 6 +- .../CustomParameterItem.tsx | 78 ++-- .../CustomStrategyParams.tsx | 6 +- .../DisabledStrategyExecution.tsx | 16 +- .../PlaygroundParameterItem.tsx | 90 ++--- .../SegmentExecution/SegmentExecution.tsx | 49 ++- .../SegmentExecutionWithoutResult.tsx | 20 +- .../StrategyExecution/StrategyExecution.tsx | 16 +- .../StrategyExecutionParameters.tsx | 27 +- .../playgroundResultStrategyLists.tsx | 92 ++--- .../PlaygroundResultChip.tsx | 73 ++-- .../VariantCell/VariantCell.tsx | 60 ++- .../VariantInformation/VariantInformation.tsx | 8 +- .../project/NewProjectCard/NewProjectCard.tsx | 24 +- .../ProjectOwners/ProjectOwners.tsx | 11 +- .../ConfigButtons/ChangeRequestTable.tsx | 48 +-- .../CreateProjectDialog.tsx | 155 ++++---- .../DeleteProject/DeleteProjectDialogue.tsx | 8 +- .../project/Project/Import/ImportModal.tsx | 110 +++--- .../Import/configure/ConfigurationStage.tsx | 96 +++-- .../Project/Import/import/ImportStage.tsx | 80 ++-- .../Import/validate/ValidationStage.tsx | 128 +++---- .../FeatureToggleCell/FeatureToggleCell.tsx | 6 +- .../ProjectFeatureToggles.tsx | 10 +- .../CreateFeatureDialog.tsx | 84 ++--- .../ProjectFeatureTogglesHeader.tsx | 204 +++++----- .../src/component/project/Project/Project.tsx | 56 ++- .../ProjectDoraMetrics/ProjectDoraMetrics.tsx | 28 +- .../ColumnsMenu/ColumnsMenu.tsx | 42 +-- .../createFeatureToggleCell.tsx | 6 +- .../useFeatureToggleSwitch.tsx | 12 +- .../MoreActions.tsx | 83 ++--- .../ProjectFeaturesBatchActions.tsx | 45 +-- .../project/Project/ProjectFlags.tsx | 8 +- .../Project/ProjectForm/ProjectForm.tsx | 171 ++++----- .../Project/ProjectHealth/ProjectHealth.tsx | 20 +- .../ReportTable/ReportCard/ReportCard.tsx | 103 ++---- .../ProjectHealth/ReportTable/ReportTable.tsx | 45 +-- .../Project/ProjectInfo/MetaWidget.tsx | 43 +-- .../Project/ProjectInfo/ProjectInfo.tsx | 47 +-- .../LeadTimeForChanges/LeadTimeForChanges.tsx | 28 +- .../ProjectHealth/ProjectHealth.tsx | 17 +- .../ProjectHealth/ProjectHealthChart.tsx | 67 ++-- .../ProjectInsightsStats/StatusBox.tsx | 77 ++-- .../ChangeRequestProcessHelp.tsx | 14 +- .../ChangeRequestTable.tsx | 99 ++--- .../ProjectActionsEventsDetailsAction.tsx | 8 +- .../ProjectActionsEventsModal.tsx | 26 +- .../ProjectActionsForm/ProjectActionsForm.tsx | 55 ++- .../ProjectActionsFormItem.tsx | 8 +- .../ProjectActionsFormStep.tsx | 8 +- .../ProjectActionsActionItem.tsx | 76 ++-- .../ProjectActionsFilterItem.tsx | 33 +- .../ProjectActionsFormStepSource.tsx | 10 +- .../ProjectActionsModal.tsx | 8 +- .../ProjectActionsTable.tsx | 14 +- .../ProjectApiAccess/ProjectApiAccess.tsx | 40 +- .../ProjectDefaultStrategyForm.tsx | 24 +- .../Settings/ArchiveProject.tsx | 47 +-- .../Settings/DeleteProject.tsx | 54 ++- .../Settings/EditProject/EditProject.tsx | 26 +- .../Project/ProjectStats/StatusBox.tsx | 90 ++--- .../ProjectAccessAssign.tsx | 43 +-- .../ProjectAccessTable/ProjectAccessTable.tsx | 135 +++---- .../ProjectGroupView/ProjectGroupView.tsx | 91 +++-- .../ProjectApplications.tsx | 83 ++--- .../ProjectEnvironment/ProjectEnvironment.tsx | 49 ++- .../project/ProjectList/ProjectGroup.tsx | 115 ++---- .../project/ProjectList/ProjectList.tsx | 52 ++- .../RemoveSegmentButton.tsx | 20 +- .../segments/SegmentDelete/SegmentDelete.tsx | 35 +- .../src/component/segments/SegmentEmpty.tsx | 17 +- .../src/component/segments/SegmentForm.tsx | 55 ++- .../component/segments/SegmentFormStepOne.tsx | 75 ++-- .../component/segments/SegmentFormStepTwo.tsx | 22 +- .../segments/SegmentProjectAlert.tsx | 19 +- .../segments/SegmentTable/SegmentTable.tsx | 100 +++-- .../SignalEndpointsForm.tsx | 189 +++++----- .../SignalEndpointsTokens.tsx | 78 ++-- .../SignalEndpointsTokensDialog.tsx | 46 ++- .../SignalEndpointsModal.tsx | 8 +- .../SignalEndpointsSignalsModal.tsx | 27 +- .../SignalEndpointsTable.tsx | 54 ++- .../AddStrategyButton/AddStrategyButton.tsx | 45 +-- .../StrategiesList/StrategiesList.tsx | 63 ++-- .../StrategyDeleteButton.tsx | 39 +- .../StrategyEditButton/StrategyEditButton.tsx | 39 +- .../StrategyParameter/StrategyParameter.tsx | 32 +- .../StrategyDetails/StrategyDetails.tsx | 48 +-- .../strategies/StrategyView/StrategyView.tsx | 24 +- .../TogglesLinkList/TogglesLinkList.tsx | 36 +- .../AddTagTypeButton/AddTagTypeButton.tsx | 37 +- .../tags/TagTypeList/TagTypeList.tsx | 42 +-- .../user/Authentication/Authentication.tsx | 16 +- .../ForgottenPassword/ForgottenPassword.tsx | 54 ++- frontend/src/component/user/HostedAuth.tsx | 110 +++--- frontend/src/component/user/Login/Login.tsx | 44 +-- .../src/component/user/NewUser/NewUser.tsx | 158 ++++---- .../NewUser/NewUserWrapper/NewUserWrapper.tsx | 32 +- frontend/src/component/user/PasswordAuth.tsx | 130 +++---- .../user/Profile/PasswordTab/PasswordTab.tsx | 133 ++++--- .../PersonalAPITokenForm.tsx | 99 +++-- .../PersonalAPITokensTab.tsx | 122 +++--- .../src/component/user/Profile/Profile.tsx | 16 +- .../user/Profile/ProfileTab/ProfileTab.tsx | 50 ++- .../user/ResetPassword/ResetPassword.tsx | 27 +- .../src/component/user/StandaloneBanner.tsx | 12 +- .../UserProfileContent/UserProfileContent.tsx | 71 ++-- .../user/common/AuthOptions/AuthOptions.tsx | 35 +- .../user/common/InvalidToken/InvalidToken.tsx | 89 ++--- .../ResetPasswordForm/PasswordChecker.tsx | 14 +- .../ResetPasswordForm/PasswordMatcher.tsx | 7 +- .../ResetPasswordForm/ResetPasswordForm.tsx | 19 +- 390 files changed, 9342 insertions(+), 12485 deletions(-) diff --git a/frontend/src/component/App.tsx b/frontend/src/component/App.tsx index f71425e5f461..38110e704416 100644 --- a/frontend/src/component/App.tsx +++ b/frontend/src/component/App.tsx @@ -1,6 +1,5 @@ import { Suspense, useEffect } from 'react'; import { Route, Routes } from 'react-router-dom'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { FeedbackNPS } from 'component/feedback/FeedbackNPS/FeedbackNPS'; import { LayoutPicker } from 'component/layout/LayoutPicker/LayoutPicker'; import Loader from 'component/common/Loader/Loader'; @@ -51,61 +50,53 @@ export const App = () => { return ( }> - } - elseShow={ - - <> - } - /> - - - - - - - - {availableRoutes.map((route) => ( - - - - } - /> - ))} + {!hasFetchedAuth ? ( + + ) : ( + + <> + {uiConfig?.maintenanceMode ? ( + + ) : null} + + + + + + + + {availableRoutes.map((route) => ( } + key={route.path} + path={route.path} + element={ + + + + } /> - } - /> - + ))} + } + /> + } /> + - + - - - - - } - /> + + + + + )} ); diff --git a/frontend/src/component/admin/Admin.tsx b/frontend/src/component/admin/Admin.tsx index c24281afa9ab..0a553824d0f4 100644 --- a/frontend/src/component/admin/Admin.tsx +++ b/frontend/src/component/admin/Admin.tsx @@ -21,17 +21,13 @@ import { AdminTabsMenu } from './menu/AdminTabsMenu'; import { Banners } from './banners/Banners'; import { License } from './license/License'; import { useUiFlag } from 'hooks/useUiFlag'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; export const Admin = () => { const sidebarNavigationEnabled = useUiFlag('navigationSidebar'); return ( <> - } - /> + {!sidebarNavigationEnabled ? : null} } /> } /> diff --git a/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx b/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx index e362c7c60354..babf4a082a23 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx @@ -2,7 +2,6 @@ import { Alert, Link } from '@mui/material'; import type React from 'react'; import type { ReactNode } from 'react'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { CancelButton, StyledBox, StyledForm } from './ApiTokenForm.styles'; interface IApiTokenFormProps { @@ -25,18 +24,15 @@ const ApiTokenForm: React.FC = ({ return ( - - Please be aware of our{' '} - - fair use policy - - . - - } - /> + {isUnleashCloud ? ( + + Please be aware of our{' '} + + fair use policy + + . + + ) : null} {children} {actions} 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 cdabf912243a..c656e9bea7b9 100644 --- a/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.tsx +++ b/frontend/src/component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectProjectInput.tsx @@ -19,7 +19,6 @@ import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; import type { IAutocompleteBoxOption } from 'component/common/AutocompleteBox/AutocompleteBox'; import { SelectAllButton } from './SelectAllButton/SelectAllButton'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const ALL_PROJECTS = '*'; @@ -96,15 +95,12 @@ export const SelectProjectInput: VFC = ({ const renderGroup = ({ key, children }: AutocompleteRenderGroupParams) => ( - 2} - show={ - - } - /> + {options.length > 2 ? ( + + ) : null} {children} ); diff --git a/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx b/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx index 8974757b13b1..e23ea2f5b0df 100644 --- a/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx +++ b/frontend/src/component/admin/apiToken/ConfirmToken/ConfirmToken.tsx @@ -2,7 +2,6 @@ import { Alert, Typography } from '@mui/material'; import { Link } from 'react-router-dom'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { UserToken } from './UserToken/UserToken'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { TokenType } from 'interfaces/token'; interface IConfirmUserLink { @@ -32,20 +31,17 @@ export const ConfirmToken = ({ 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 - - . - - } - /> + {type === TokenType.FRONTEND ? ( + + 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 + + . + + ) : null} ); }; diff --git a/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx b/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx index a820a61008d3..d9d70554c7d3 100644 --- a/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx +++ b/frontend/src/component/admin/apiToken/CreateApiToken/CreateApiToken.tsx @@ -1,7 +1,6 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useUiFlag } from 'hooks/useUiFlag'; import FormTemplate from 'component/common/FormTemplate/FormTemplate'; import ApiTokenForm from '../ApiTokenForm/ApiTokenForm'; @@ -176,17 +175,14 @@ export const CreateApiToken = ({ modal = false }: ICreateApiTokenProps) => { environment={environment} setEnvironment={setEnvironment} /> - - } - /> + {resourceLimitsEnabled ? ( + + ) : null} { { - setActiveTab(tabId); - }} - indicatorColor='primary' - textColor='primary' - > - {tabs.map((tab, index) => ( - - ))} - - } - /> - } - > - } - /> - - You are running Unleash in demo mode. You have - to use the Enterprise edition in order configure - Single Sign-on. - - } - /> - - You have decided to use custom authentication - type. You have to use the Enterprise edition in - order configure Single Sign-on from the user - interface. - - } - /> - - Your Unleash instance is managed by the Unleash - team. - - } - /> - + authenticationType === 'enterprise' ? ( + { + setActiveTab(tabId); + }} + indicatorColor='primary' + textColor='primary' + > {tabs.map((tab, index) => ( - - {tab.component} - + ))} - - } - /> + + ) : null + } + > + {authenticationType === 'open-source' ? ( + + ) : null} + {authenticationType === 'demo' ? ( + + You are running Unleash in demo mode. You have to + use the Enterprise edition in order configure Single + Sign-on. + + ) : null} + {authenticationType === 'custom' ? ( + + You have decided to use custom authentication type. + You have to use the Enterprise edition in order + configure Single Sign-on from the user interface. + + ) : null} + {authenticationType === 'hosted' ? ( + + Your Unleash instance is managed by the Unleash + team. + + ) : null} + {authenticationType === 'enterprise' ? ( +
+ {tabs.map((tab, index) => ( + + {tab.component} + + ))} +
+ ) : null}
diff --git a/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx b/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx index 53f602332bcb..1dfc6b3b7087 100644 --- a/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx +++ b/frontend/src/component/admin/auth/OidcAuth/OidcAuth.tsx @@ -21,7 +21,6 @@ import { formatUnknownError } from 'utils/formatUnknownError'; import { removeEmptyStringFields } from 'utils/removeEmptyStringFields'; import { SsoGroupSettings } from '../SsoGroupSettings'; import type { IRole } from 'interfaces/role'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const initialState = { enabled: false, @@ -109,24 +108,21 @@ export const OidcAuth = () => { <> - - OIDC is currently configured via environment - variables. Please refer to the{' '} - - documentation - {' '} - for detailed instructions on how to set up OIDC - using these variables. - - } - /> + {oidcConfiguredThroughEnv ? ( + + OIDC is currently configured via environment + variables. Please refer to the{' '} + + documentation + {' '} + for detailed instructions on how to set up OIDC + using these variables. + + ) : null} Please read the{' '} { <> - - SAML is currently configured via environment - variables. Please refer to the{' '} - - documentation - {' '} - for detailed instructions on how to set up SAML - using these variables. - - } - /> + {samlConfiguredThroughEnv ? ( + + SAML is currently configured via environment + variables. Please refer to the{' '} + + documentation + {' '} + for detailed instructions on how to set up SAML + using these variables. + + ) : null} Please read the{' '} { - - Generate new token - - } - /> + {settings.hasToken ? ( + + ) : null} - - - Request 'groups' Scope -

- When enabled Unleash will also request the - 'groups' scope as part of the login request. -

-
- - - } - label={ - data.addGroupsScope ? 'Enabled' : 'Disabled' - } - /> - + {ssoType === 'OIDC' ? ( + + + Request 'groups' Scope +

+ When enabled Unleash will also request the 'groups' + scope as part of the login request. +

+
+ + + } + label={data.addGroupsScope ? 'Enabled' : 'Disabled'} + /> - } - /> +
+ ) : null} ); }; diff --git a/frontend/src/component/admin/banners/BannerModal/BannerForm.tsx b/frontend/src/component/admin/banners/BannerModal/BannerForm.tsx index 395d26a1cd38..ad1d4d54ef1e 100644 --- a/frontend/src/component/admin/banners/BannerModal/BannerForm.tsx +++ b/frontend/src/component/admin/banners/BannerModal/BannerForm.tsx @@ -1,6 +1,5 @@ import { Button, Checkbox, FormControlLabel, styled } from '@mui/material'; import { Banner } from 'component/banners/Banner/Banner'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { FormSwitch } from 'component/common/FormSwitch/FormSwitch'; import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect'; import { HelpIcon } from 'component/common/HelpIcon/HelpIcon'; @@ -208,49 +207,45 @@ export const BannerForm = ({ )} /> - - - Which custom icon? - -

- Choose an icon from{' '} - - Material Symbols - - . -

-

- For example, if you want to - display the "Rocket Launch" - icon, you can enter - "rocket_launch" in the field - below. -

- - } - /> - - ) => - setIcon(e.target.value) + {iconOption === 'Custom' ? ( + + + Which custom icon? + +

+ Choose an icon from{' '} + + Material Symbols + + . +

+

+ For example, if you want to display + the "Rocket Launch" icon, you can + enter "rocket_launch" in the field + below. +

+ } - autoComplete='off' /> -
- } - /> + + ) => + setIcon(e.target.value) + } + autoComplete='off' + /> + + ) : null} What is your banner message? @@ -313,112 +308,103 @@ export const BannerForm = ({ }))} /> - + + What URL should be opened? + + ) => + setLink(e.target.value) + } + onBlur={() => { + if (!linkText) setLinkText(link); + }} + autoComplete='off' + /> + + ) : null} + {linkOption !== 'None' ? ( + + + What is the action text? + + ) => + setLinkText(e.target.value) + } + autoComplete='off' + /> + + ) : null} + {linkOption === 'Dialog' ? ( + <> - What URL should be opened? + What is the dialog title? ) => - setLink(e.target.value) + setDialogTitle(e.target.value) } - onBlur={() => { - if (!linkText) setLinkText(link); - }} autoComplete='off' /> - } - /> - - What is the action text? + What is the dialog content? + +

+ + Markdown + {' '} + is supported. +

+ + } + />
) => - setLinkText(e.target.value) + setDialog(e.target.value) } autoComplete='off' /> - } - /> - - - - What is the dialog title? - - , - ) => setDialogTitle(e.target.value)} - autoComplete='off' - /> - - - - What is the dialog content? - -

- - Markdown - {' '} - is supported. -

- - } - /> -
- , - ) => setDialog(e.target.value)} - autoComplete='off' - /> -
- } - onClick={() => setPreviewDialogOpen(true)} - > - Preview dialog - - - {dialog!} - - - } - /> + } + onClick={() => setPreviewDialogOpen(true)} + > + Preview dialog + + + {dialog!} + + + ) : null} Sticky banner diff --git a/frontend/src/component/admin/banners/BannersTable/BannersTable.tsx b/frontend/src/component/admin/banners/BannersTable/BannersTable.tsx index c782e985196b..1d17cb8c0f24 100644 --- a/frontend/src/component/admin/banners/BannersTable/BannersTable.tsx +++ b/frontend/src/component/admin/banners/BannersTable/BannersTable.tsx @@ -1,6 +1,5 @@ import { useMemo, useState } from 'react'; import { TablePlaceholder, VirtualizedTable } from 'component/common/Table'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; import { PageContent } from 'component/common/PageContent/PageContent'; @@ -175,18 +174,15 @@ export const BannersTable = () => { title={`Banners (${rows.length})`} actions={ <> - - - - - } - /> + {!isSmallScreen ? ( + <> + + + + ) : null} - } - /> + return invoices.length > 0 ? ( + } + > + Billing portal + } - > -
- - - - Amount - Status - Due date - PDF - Link - - - - {invoices.map((item: IInvoice) => ( - - - {item.amountFormatted} - - - {item.status} - - - {item.dueDate && - formatDateYMD( - item.dueDate, - locationSettings.locale, - )} - - - PDF - - - - Payment link - - - - ))} - -
-
-
- } - elseShow={ - {isLoaded && 'No invoices to show.'} + /> } - /> + > +
+ + + + Amount + Status + Due date + PDF + Link + + + + {invoices.map((item: IInvoice) => ( + + + {item.amountFormatted} + + + {item.status} + + + {item.dueDate && + formatDateYMD( + item.dueDate, + locationSettings.locale, + )} + + + PDF + + + + Payment link + + + + ))} + +
+
+ + ) : ( + {isLoaded && 'No invoices to show.'} ); }; export default InvoiceList; diff --git a/frontend/src/component/admin/license/License.tsx b/frontend/src/component/admin/license/License.tsx index 40d4e2e2a3ab..30210982887e 100644 --- a/frontend/src/component/admin/license/License.tsx +++ b/frontend/src/component/admin/license/License.tsx @@ -12,7 +12,6 @@ import { useState } from 'react'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; import useLicenseKeyApi from 'hooks/api/actions/useLicenseAPI/useLicenseApi'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledBox = styled(Box)(({ theme }) => ({ display: 'grid', @@ -71,58 +70,49 @@ export const License = () => { return ( }> - - - - Customer - - - {license.customer} - - - - - Instance Name - - - {license.instanceName} - - - - Plan - - {license.plan} - - - - Seats - - {license.seats} - - - - - Expire at - - - {formatDateYMD( - license.expireAt, - locationSettings.locale, - )} - - - - } - elseShow={ -

- You do not have a registered Unleash Enterprise - License. -

- } - /> + {license.token ? ( +
+ + Customer + + {license.customer} + + + + + Instance Name + + + {license.instanceName} + + + + Plan + + {license.plan} + + + + Seats + + {license.seats} + + + + Expire at + + {formatDateYMD( + license.expireAt, + locationSettings.locale, + )} + + +
+ ) : ( +

+ You do not have a registered Unleash Enterprise License. +

+ )}
{ label={ {tab.title} - - - - } - /> + {tab.menu.mode?.includes('enterprise') && + !tab.menu.mode?.includes('pro') && + isPro() ? ( + + + + ) : null} } /> diff --git a/frontend/src/component/admin/network/NetworkTraffic/NetworkTraffic.tsx b/frontend/src/component/admin/network/NetworkTraffic/NetworkTraffic.tsx index bff36affe743..dbe0258ebd5a 100644 --- a/frontend/src/component/admin/network/NetworkTraffic/NetworkTraffic.tsx +++ b/frontend/src/component/admin/network/NetworkTraffic/NetworkTraffic.tsx @@ -24,7 +24,6 @@ import 'chartjs-adapter-date-fns'; import { Alert, useTheme } from '@mui/material'; import { Box } from '@mui/system'; import { CyclicIterator } from 'utils/cyclicIterator'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { usePageTitle } from 'hooks/usePageTitle'; import { unknownify } from 'utils/unknownify'; import type { Theme } from '@mui/material/styles/createTheme'; @@ -203,22 +202,18 @@ export const NetworkTraffic: VFC = () => { return { datasets: toChartData(theme, metrics) }; }, [theme, metrics, locationSettings]); - return ( - No data available.} - elseShow={ - -
- -
-
- } - /> + return data.datasets.length === 0 ? ( + No data available. + ) : ( + +
+ +
+
); }; diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx index 48ca0081559b..ab08477a1563 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx @@ -6,7 +6,6 @@ import Select from 'component/common/select'; import Box from '@mui/system/Box'; import { Link as RouterLink } from 'react-router-dom'; import { Alert, Link } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import { Chart as ChartJS, @@ -277,74 +276,67 @@ export const NetworkTrafficUsage: VFC = () => { } }, [data]); - return ( - Not enabled.} - elseShow={ - <> - 0 && overageCost > 0} - show={ - - Heads up! You are currently consuming - more requests than your plan includes and will - be billed according to our terms. Please see{' '} - - this page - {' '} - for more information. In order to reduce your - traffic consumption, you may configure an{' '} - - Unleash Edge instance - {' '} - in your own datacenter. - - } + return isOss() || !flagEnabled ? ( + Not enabled. + ) : ( + <> + {includedTraffic > 0 && overageCost > 0 ? ( + + Heads up! You are currently consuming more requests + than your plan includes and will be billed according to our + terms. Please see{' '} + + this page + {' '} + for more information. In order to reduce your traffic + consumption, you may configure an{' '} + + Unleash Edge instance + {' '} + in your own datacenter. + + ) : null} + + + + + + + setPeriod(e.target.value)} - style={{ - minWidth: '100%', - marginBottom: theme.spacing(2), - }} - formControlStyles={{ width: '100%' }} - /> - - - - - - - - } - /> + + + ); }; diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsagePlanSummary.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsagePlanSummary.tsx index 820f16b6a480..880f5eb7494c 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsagePlanSummary.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsagePlanSummary.tsx @@ -2,7 +2,6 @@ import styled from '@mui/material/styles/styled'; import Box from '@mui/system/Box'; import Grid from '@mui/material/Grid'; import Link from '@mui/material/Link'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Badge } from 'component/common/Badge/Badge'; import { useUiFlag } from 'hooks/useUiFlag'; @@ -94,74 +93,62 @@ export const NetworkTrafficUsagePlanSummary = ({ - 0} - show={ - - - Included in your plan monthly - - {includedTraffic.toLocaleString()}{' '} - requests - - - - } - /> + {includedTraffic > 0 ? ( + + + Included in your plan monthly + + {includedTraffic.toLocaleString()}{' '} + requests + + + + ) : null} - 0 && overages > 0 - } - show={ - - - - - Accrued traffic charges - - + {estimateFlagEnabled && includedTraffic > 0 && overages > 0 ? ( + + + + + Accrued traffic charges + + + + Requests overages this month ( + + pricing + + ) + + {overages.toLocaleString()} requests + + + + Accrued traffic charges + + + {overageCost} USD + + + + {estimatedMonthlyCost > 0 ? ( - Requests overages this month ( - - pricing - - ) - - {overages.toLocaleString()} requests - - - - Accrued traffic charges + Estimated traffic charges based on + current usage - {overageCost} USD + {estimatedMonthlyCost} USD - 0} - show={ - - Estimated traffic charges based - on current usage - - - {estimatedMonthlyCost}{' '} - USD - - - - } - /> - - - - - } - /> + ) : null} + + + + + ) : null} ); }; diff --git a/frontend/src/component/admin/roles/RoleForm/RoleForm.tsx b/frontend/src/component/admin/roles/RoleForm/RoleForm.tsx index e04e19c9802f..b154b0d88c20 100644 --- a/frontend/src/component/admin/roles/RoleForm/RoleForm.tsx +++ b/frontend/src/component/admin/roles/RoleForm/RoleForm.tsx @@ -4,7 +4,6 @@ import type { ICheckedPermissions } from 'interfaces/permissions'; import type { IRoleFormErrors } from './useRoleForm'; import type { PredefinedRoleType } from 'interfaces/role'; import { ROOT_ROLE_TYPE } from '@server/util/constants'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { RolePermissionCategories } from './RolePermissionCategories/RolePermissionCategories'; const StyledInputDescription = styled('p')(({ theme }) => ({ @@ -107,20 +106,17 @@ export const RoleForm = ({ setCheckedPermissions={setCheckedPermissions} validatePermissions={validatePermissions} /> - ( - -
    - {Object.values(errors) - .filter(Boolean) - .map((error) => ( -
  • {error}
  • - ))} -
-
- )} - /> + {showErrors ? ( + +
    + {Object.values(errors) + .filter(Boolean) + .map((error) => ( +
  • {error}
  • + ))} +
+
+ ) : null} ); }; diff --git a/frontend/src/component/admin/roles/RolesPage.tsx b/frontend/src/component/admin/roles/RolesPage.tsx index 4299b0a48ae8..b947938e5add 100644 --- a/frontend/src/component/admin/roles/RolesPage.tsx +++ b/frontend/src/component/admin/roles/RolesPage.tsx @@ -1,5 +1,4 @@ import { useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ADMIN } from 'component/providers/AccessProvider/permissions'; import { RolesTable } from './RolesTable/RolesTable'; import { PageContent } from 'component/common/PageContent/PageContent'; @@ -89,18 +88,15 @@ export const RolesPage = () => { - - - - - } - /> + {!isSmallScreen ? ( + <> + + + + ) : null} { setSelectedRole(undefined); @@ -114,15 +110,12 @@ export const RolesPage = () => { - - } - /> + {isSmallScreen ? ( + + ) : null} } > diff --git a/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogProjectRole/RoleDeleteDialogProjectRole.tsx b/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogProjectRole/RoleDeleteDialogProjectRole.tsx index fa32b9981335..a28fea0abffe 100644 --- a/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogProjectRole/RoleDeleteDialogProjectRole.tsx +++ b/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogProjectRole/RoleDeleteDialogProjectRole.tsx @@ -1,5 +1,4 @@ import { Alert, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import type { IRole } from 'interfaces/role'; import { useProjectRoleAccessUsage } from 'hooks/api/getters/useProjectRoleAccessUsage/useProjectRoleAccessUsage'; @@ -43,40 +42,31 @@ export const RoleDeleteDialogProjectRole = ({ }} maxWidth='md' > - - - You are not allowed to delete a role that is - currently in use. Please change the role of the - following entities first: - - - - Role assigned in {projects?.length}{' '} - projects: - - - - - - } - /> - - } - elseShow={ -

- You are about to delete role:{' '} - {role?.name} -

- } - /> + {entitiesWithRole ? ( + <> + + You are not allowed to delete a role that is currently + in use. Please change the role of the following entities + first: + + {projects?.length ? ( + <> + + Role assigned in {projects?.length} projects: + + + + + + ) : null} + + ) : ( +

+ You are about to delete role: {role?.name} +

+ )} ); }; diff --git a/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogRootRole/RoleDeleteDialogRootRole.tsx b/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogRootRole/RoleDeleteDialogRootRole.tsx index 894a3bf824b6..0df0ba68a139 100644 --- a/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogRootRole/RoleDeleteDialogRootRole.tsx +++ b/frontend/src/component/admin/roles/RolesTable/RoleDeleteDialog/RoleDeleteDialogRootRole/RoleDeleteDialogRootRole.tsx @@ -1,5 +1,4 @@ import { Alert, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { useServiceAccounts } from 'hooks/api/getters/useServiceAccounts/useServiceAccounts'; import { useUsers } from 'hooks/api/getters/useUsers/useUsers'; @@ -56,72 +55,51 @@ export const RoleDeleteDialogRootRole = ({ setOpen(false); }} > - - - You are not allowed to delete a role that is - currently in use. Please change the role of the - following entities first: - - - - Users ({roleUsers.length}): - - - - - - } - /> - - - Service accounts ( - {roleServiceAccounts.length}): - - - - - - } - /> - - - Groups ({roleGroups?.length}): - - - - - - } - /> - - } - elseShow={ -

- You are about to delete role:{' '} - {role?.name} -

- } - /> + {entitiesWithRole ? ( + <> + + You are not allowed to delete a role that is currently + in use. Please change the role of the following entities + first: + + {roleUsers.length ? ( + <> + + Users ({roleUsers.length}): + + + + + + ) : null} + {roleServiceAccounts.length ? ( + <> + + Service accounts ({roleServiceAccounts.length}): + + + + + + ) : null} + {roleGroups?.length ? ( + <> + + Groups ({roleGroups?.length}): + + + + + + ) : null} + + ) : ( +

+ You are about to delete role: {role?.name} +

+ )} ); }; diff --git a/frontend/src/component/admin/roles/RolesTable/RolesCell/RolesCell.tsx b/frontend/src/component/admin/roles/RolesTable/RolesCell/RolesCell.tsx index 36d957033f45..854aebb9e6b7 100644 --- a/frontend/src/component/admin/roles/RolesTable/RolesCell/RolesCell.tsx +++ b/frontend/src/component/admin/roles/RolesTable/RolesCell/RolesCell.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Badge } from 'component/common/Badge/Badge'; import { styled } from '@mui/material'; import type { IRole } from 'interfaces/role'; @@ -18,10 +17,9 @@ export const RolesCell = ({ role }: IRolesCellProps) => ( value={role.name} subtitle={role.description} afterTitle={ - Predefined} - /> + PREDEFINED_ROLE_TYPES.includes(role.type) ? ( + Predefined + ) : null } /> ); diff --git a/frontend/src/component/admin/roles/RolesTable/RolesTable.tsx b/frontend/src/component/admin/roles/RolesTable/RolesTable.tsx index aeb4ba46c32a..d05c6d7e879a 100644 --- a/frontend/src/component/admin/roles/RolesTable/RolesTable.tsx +++ b/frontend/src/component/admin/roles/RolesTable/RolesTable.tsx @@ -1,6 +1,5 @@ import { useMemo, useState } from 'react'; import { TablePlaceholder, VirtualizedTable } from 'component/common/Table'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { IRole, PredefinedRoleType } from 'interfaces/role'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; @@ -170,27 +169,28 @@ export const RolesTable = ({ prepareRow={prepareRow} /> - 0} - show={ - - No {type} roles found matching “ - {searchValue} - ” - - } - elseShow={ - - No {type} roles available. Get started by adding - one. - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No {type} roles found matching “ + {searchValue} + ” + + } + elseShow={ + + No {type} roles available. Get started by adding + one. + + } + /> + ) : ( + + No {type} roles available. Get started by adding one. + + )} { const { isEnterprise } = useUiConfig(); return (
- - - - } - elseShow={} - /> + {isEnterprise() ? ( + + + + ) : ( + + )}
); }; diff --git a/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountDeleteDialog/ServiceAccountDeleteDialog.tsx b/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountDeleteDialog/ServiceAccountDeleteDialog.tsx index a237813376a9..7c61025f50c0 100644 --- a/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountDeleteDialog/ServiceAccountDeleteDialog.tsx +++ b/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountDeleteDialog/ServiceAccountDeleteDialog.tsx @@ -1,5 +1,4 @@ import { Alert, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import type { IServiceAccount } from 'interfaces/service-account'; import { ServiceAccountTokens } from '../ServiceAccountModal/ServiceAccountTokens/ServiceAccountTokens'; @@ -43,26 +42,24 @@ export const ServiceAccountDeleteDialog = ({ setOpen(false); }} > - - - Deleting this service account may break any existing - implementations currently using it. - - {deleteMessage} - Service account tokens: - - - - - } - elseShow={

{deleteMessage}

} - /> + {serviceAccount?.tokens.length ? ( + <> + + Deleting this service account may break any existing + implementations currently using it. + + {deleteMessage} + Service account tokens: + + + + + ) : ( +

{deleteMessage}

+ )} ); }; diff --git a/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountModal.tsx b/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountModal.tsx index 5ead0bd51f80..29339595a0a3 100644 --- a/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountModal.tsx +++ b/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountModal.tsx @@ -14,7 +14,6 @@ import useToast from 'hooks/useToast'; import { type FormEvent, useEffect, useState } from 'react'; import { formatUnknownError } from 'utils/formatUnknownError'; import Input from 'component/common/Input/Input'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { IUser } from 'interfaces/user'; import { type IServiceAccountPayload, @@ -311,94 +310,76 @@ export const ServiceAccountModal = ({ setValue={setRootRole} required /> - - - Token - + {!editing ? ( + + + Token + + + In order to connect your newly created + service account, you will also need a token.{' '} + + Read more about API tokens + + . + + + + setTokenGeneration( + e.target + .value as TokenGeneration, + ) + } + name='token-generation' + > + } + label='I want to generate a token later' + /> + } + label='Generate a token now' + /> + + + - In order to connect your newly created - service account, you will also need a - token.{' '} - - Read more about API tokens - - . + A new personal access token (PAT) will + be generated for the service account, so + you can get started right away. - - - setTokenGeneration( - e.target - .value as TokenGeneration, - ) - } - name='token-generation' - > - } - label='I want to generate a token later' - /> - } - label='Generate a token now' - /> - - - - - A new personal access token (PAT) - will be generated for the service - account, so you can get started - right away. - - - } + {tokenGeneration === TokenGeneration.NOW ? ( + - - - } - elseShow={ - <> - - Service account tokens - - - - } - /> + ) : null} + + + ) : ( + <> + + Service account tokens + + + + )} diff --git a/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountTokens/ServiceAccountTokens.tsx b/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountTokens/ServiceAccountTokens.tsx index 44532adf57ac..c3599402774e 100644 --- a/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountTokens/ServiceAccountTokens.tsx +++ b/frontend/src/component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountModal/ServiceAccountTokens/ServiceAccountTokens.tsx @@ -34,7 +34,6 @@ import { ServiceAccountCreateTokenDialog } from './ServiceAccountCreateTokenDial import { ServiceAccountTokenDialog } from 'component/admin/serviceAccounts/ServiceAccountsTable/ServiceAccountTokenDialog/ServiceAccountTokenDialog'; import { TimeAgoCell } from 'component/common/Table/cells/TimeAgoCell/TimeAgoCell'; import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { type ICreateServiceAccountTokenPayload, @@ -257,26 +256,23 @@ export const ServiceAccountTokens = ({ return ( <> - - - - - } - /> + {!readOnly ? ( + + + + + ) : null} - 0} - show={ - - No tokens found matching “ - {searchValue} - ” - - } - elseShow={ - - - You have no tokens for this service account - yet. - - - Create a service account token for access to - the Unleash API. - - - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No tokens found matching “ + {searchValue} + ” + + } + elseShow={ + + + You have no tokens for this service account yet. + + + Create a service account token for access to the + Unleash API. + + + + } + /> + ) : ( + + + You have no tokens for this service account yet. + + + Create a service account token for access to the Unleash + API. + + + + )} { title={`Service Accounts (${rows.length})`} actions={ <> - - - - - } - /> + {!isSmallScreen ? ( + <> + + + + ) : null} - } - /> + {isUpdating ? ( + + ) : null} - + {project} + + ))} + + + - - - - - } - /> + + + + ); }; diff --git a/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx b/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx index f2535dff556d..54d75a36db82 100644 --- a/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx +++ b/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx @@ -6,7 +6,6 @@ import { Box, ToggleButton, ToggleButtonGroup } from '@mui/material'; import { useApplicationOverview } from 'hooks/api/getters/useApplicationOverview/useApplicationOverview'; import { useConnectedInstances } from 'hooks/api/getters/useConnectedInstances/useConnectedInstances'; import type { ApplicationEnvironmentInstancesSchemaInstancesItem } from '../../../openapi'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StringParam, useQueryParam, withDefault } from 'use-query-params'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; @@ -93,30 +92,27 @@ export const ConnectedInstances: FC = () => { environments that have received traffic for this application will be shown here. - { - if (value !== null) { - trackEnvironmentChange(); - setCurrentEnvironment(value); - } - }} - > - {environments.map((env) => { - return ( - - {env} - - ); - })} - - } - /> + {currentEnvironment ? ( + { + if (value !== null) { + trackEnvironmentChange(); + setCurrentEnvironment(value); + } + }} + > + {environments.map((env) => { + return ( + + {env} + + ); + })} + + ) : null} - -

- There's no data for any connected instances to - display. Have you configured your clients correctly? -

- - } - /> + {rows.length === 0 && !loading ? ( + +

+ There's no data for any connected instances to display. + Have you configured your clients correctly? +

+
+ ) : null} ); }; diff --git a/frontend/src/component/archive/ArchiveTable/ArchiveTable.tsx b/frontend/src/component/archive/ArchiveTable/ArchiveTable.tsx index 3c9993191d8b..a9c489d55919 100644 --- a/frontend/src/component/archive/ArchiveTable/ArchiveTable.tsx +++ b/frontend/src/component/archive/ArchiveTable/ArchiveTable.tsx @@ -14,7 +14,6 @@ import { sortTypes } from 'utils/sortTypes'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell'; import { DateCell } from 'component/common/Table/cells/DateCell/DateCell'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Search } from 'component/common/Search/Search'; import { FeatureTypeCell } from 'component/common/Table/cells/FeatureTypeCell/FeatureTypeCell'; import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; @@ -301,25 +300,26 @@ export const ArchiveTable = ({ prepareRow={prepareRow} /> - ( - 0} - show={ - - No feature flags found matching “ - {searchValue}” - - } - elseShow={ - - None of the feature flags were archived yet. - - } - /> - )} - /> + {rows.length === 0 ? ( + 0} + show={ + + No feature flags found matching “ + {searchValue}” + + } + elseShow={ + + None of the feature flags were archived yet. + + } + /> + ) : ( + + None of the feature flags were archived yet. + + )} - - toggleAllRowsSelected(false)} - /> - - } - /> + {projectId ? ( + + toggleAllRowsSelected(false)} + /> + + ) : null} ); }; diff --git a/frontend/src/component/archive/ArchiveTable/ArchivedFeatureActionCell/ArchivedFeatureReviveConfirm/ArchivedFeatureReviveConfirm.tsx b/frontend/src/component/archive/ArchiveTable/ArchivedFeatureActionCell/ArchivedFeatureReviveConfirm/ArchivedFeatureReviveConfirm.tsx index 52ea43757b9b..2f58d6e0cffb 100644 --- a/frontend/src/component/archive/ArchiveTable/ArchivedFeatureActionCell/ArchivedFeatureReviveConfirm/ArchivedFeatureReviveConfirm.tsx +++ b/frontend/src/component/archive/ArchiveTable/ArchivedFeatureActionCell/ArchivedFeatureReviveConfirm/ArchivedFeatureReviveConfirm.tsx @@ -4,7 +4,6 @@ import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { formatUnknownError } from 'utils/formatUnknownError'; import useToast from 'hooks/useToast'; import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface IArchivedFeatureReviveConfirmProps { revivedFeatures: string[]; @@ -72,28 +71,22 @@ export const ArchivedFeatureReviveConfirm = ({ Revived feature flags will be automatically disabled in all environments - - 1} - show={ - <> - - You are about to revive feature flags: - -
    - {revivedFeatures.map((name) => ( -
  • {name}
  • - ))} -
- - } - elseShow={ + {revivedFeatures.length > 1 ? ( + <> - You are about to revive feature flag:{' '} - {revivedFeatures[0]} + You are about to revive feature flags: - } - /> +
    + {revivedFeatures.map((name) => ( +
  • {name}
  • + ))} +
+ + ) : ( + + You are about to revive feature flag: {revivedFeatures[0]} + + )} ); }; diff --git a/frontend/src/component/banners/EdgeUpgradeBanner/EdgeUpgradeBanner.tsx b/frontend/src/component/banners/EdgeUpgradeBanner/EdgeUpgradeBanner.tsx index cf132250c14e..0e6696cfc459 100644 --- a/frontend/src/component/banners/EdgeUpgradeBanner/EdgeUpgradeBanner.tsx +++ b/frontend/src/component/banners/EdgeUpgradeBanner/EdgeUpgradeBanner.tsx @@ -1,5 +1,4 @@ import { useUiFlag } from 'hooks/useUiFlag'; -import { ConditionallyRender } from '../../common/ConditionallyRender/ConditionallyRender'; import { Banner } from '../Banner/Banner'; import type { IBanner } from '../../../interfaces/banner'; @@ -13,10 +12,9 @@ export const EdgeUpgradeBanner = () => { }; return ( <> - } - /> + {displayUpgradeEdgeBanner ? ( + + ) : null} ); }; diff --git a/frontend/src/component/banners/OutdatedSdksBanner/OutdatedSdksBanner.tsx b/frontend/src/component/banners/OutdatedSdksBanner/OutdatedSdksBanner.tsx index 4e2ff51ada65..389cdf32d22a 100644 --- a/frontend/src/component/banners/OutdatedSdksBanner/OutdatedSdksBanner.tsx +++ b/frontend/src/component/banners/OutdatedSdksBanner/OutdatedSdksBanner.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Banner } from '../Banner/Banner'; import type { IBanner } from 'interfaces/banner'; import { useOutdatedSdks } from 'hooks/api/getters/useOutdatedSdks/useOutdatedSdks'; @@ -75,10 +74,9 @@ export const OutdatedSdksBanner = ({ project }: IOutdatedSdksBannerProps) => { }; return ( <> - 0} - show={} - /> + {sdks.length > 0 ? ( + + ) : null} ); }; diff --git a/frontend/src/component/changeRequest/ChangeRequest/ChangeRequest.tsx b/frontend/src/component/changeRequest/ChangeRequest/ChangeRequest.tsx index 766273422db9..115daca154c1 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/ChangeRequest.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/ChangeRequest.tsx @@ -4,7 +4,6 @@ import type { ChangeRequestType } from '../changeRequest.types'; import { FeatureToggleChanges } from './Changes/FeatureToggleChanges'; import { FeatureChange } from './Changes/Change/FeatureChange'; import { ChangeActions } from './Changes/Change/ChangeActions'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { SegmentChange } from './Changes/Change/SegmentChange'; interface IChangeRequestProps { @@ -20,15 +19,11 @@ export const ChangeRequest: VFC = ({ }) => { return ( - 0} - show={ - - You request changes for these segments: - - } - /> - + {changeRequest.segments.length > 0 ? ( + + You request changes for these segments: + + ) : null} {changeRequest.segments?.map((segmentChange) => ( = ({ } /> ))} - 0} - show={ - - You request changes for these feature flags: - - } - /> + {changeRequest.features.length > 0 ? ( + + You request changes for these feature flags: + + ) : null} {changeRequest.features?.map((feature) => ( - - - - - - - - - - - - - - Edit change - - - { - setEditOpen(false); - onRefetch?.(); - }} - onClose={() => { - setEditOpen(false); - }} - /> - - } - /> - - { - onDiscard(); - }} - > - - - - - - Discard change - - - + return showEdit || showDiscard ? ( + <> + + + + + + + + {showEdit ? ( + + + + + + + Edit change + + + { + setEditOpen(false); + onRefetch?.(); + }} + onClose={() => { + setEditOpen(false); + }} /> - - - - } - /> - ); + + ) : null} + + {showDiscard ? ( + { + onDiscard(); + }} + > + + + + + + Discard change + + + + ) : null} + + + + ) : null; }; diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/ConflictWarning.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/ConflictWarning.tsx index 734064b91fd7..7e52afba6191 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/ConflictWarning.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/ConflictWarning.tsx @@ -1,25 +1,20 @@ import { Alert } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; export const ConflictWarning: React.FC<{ conflict: string | null | undefined; -}> = ({ conflict }) => ( - - Conflict! {conflict}. - - } - /> -); +}> = ({ conflict }) => + conflict ? ( + + Conflict! {conflict}. + + ) : null; diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/FeatureChange.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/FeatureChange.tsx index 256430088b32..f141fe8609ab 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/FeatureChange.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/FeatureChange.tsx @@ -5,7 +5,6 @@ import type { IChangeRequestFeature, } from '../../../changeRequest.types'; import { objectId } from 'utils/objectId'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Alert, Box, styled } from '@mui/material'; import { ToggleStatusChange } from './ToggleStatusChange'; import { StrategyChange } from './StrategyChange'; @@ -96,51 +95,41 @@ export const FeatureChange: FC<{ )} $isLast={index + 1 === lastIndex} > - - Conflict! This change can’t be applied.{' '} - {change.conflict}. - - } - /> - - - Potential conflict! This change would - create conflicts with the following scheduled change - request(s):{' '} - - {( - change.scheduleConflicts ?? { - changeRequests: [], - } - ).changeRequests.map(({ id, title }) => { - const text = title - ? `#${id} (${title})` - : `#${id}`; - return ( -
  • - - {text} - -
  • - ); - })} - . -
    - - } - /> - + {Boolean(change.conflict) && !feature.conflict ? ( + + Conflict! This change can’t be applied.{' '} + {change.conflict}. + + ) : null} + {change.scheduleConflicts ? ( + + Potential conflict! This change would + create conflicts with the following scheduled change + request(s):{' '} + + {( + change.scheduleConflicts ?? { + changeRequests: [], + } + ).changeRequests.map(({ id, title }) => { + const text = title ? `#${id} (${title})` : `#${id}`; + return ( +
  • + + {text} + +
  • + ); + })} + . +
    +
    + ) : null} {(change.action === 'addDependency' || change.action === 'deleteDependency') && ( diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx index 927d2b1cd114..ffb134891e17 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx @@ -16,7 +16,6 @@ import type { } from 'component/changeRequest/changeRequest.types'; import { useCurrentStrategy } from './hooks/useCurrentStrategy'; import { Badge } from 'component/common/Badge/Badge'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { flexRow } from 'themes/themeStyles'; import { EnvironmentVariantsTable } from 'component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable'; import { ChangeOverwriteWarning } from './ChangeOverwriteWarning/ChangeOverwriteWarning'; @@ -185,21 +184,18 @@ export const StrategyChange: VFC<{
    {actions}
    - - - Updating feature variants to: - - - - ) - } - /> + {hasVariantDiff + ? change.payload.variants && ( + + + Updating feature variants to: + + + + ) + : null} )} {change.action === 'deleteStrategy' && ( @@ -224,18 +220,11 @@ export const StrategyChange: VFC<{
    {actions}
    - - { - - } - - } - /> + {currentStrategy ? ( + + {} + + ) : null} )} {change.action === 'updateStrategy' && ( @@ -266,41 +255,32 @@ export const StrategyChange: VFC<{
    {actions}
    - theme.spacing(2), - marginBottom: (theme) => theme.spacing(2), - ...flexRow, - gap: (theme) => theme.spacing(1), - }} - > - This strategy will be{' '} - - - } - /> + {change.payload?.disabled !== currentStrategy?.disabled ? ( + theme.spacing(2), + marginBottom: (theme) => theme.spacing(2), + ...flexRow, + gap: (theme) => theme.spacing(1), + }} + > + This strategy will be{' '} + + + ) : null} - - - Updating feature variants to: - - - - } - /> + {hasVariantDiff ? ( + + + Updating feature variants to: + + + + ) : null} )} diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx index 5050f3961214..603571626604 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/VariantPatch/VariantPatch.tsx @@ -4,7 +4,6 @@ import type { IChangeRequestPatchVariant, } from 'component/changeRequest/changeRequest.types'; import { Badge } from 'component/common/Badge/Badge'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { TooltipLink } from 'component/common/TooltipLink/TooltipLink'; import { EnvironmentVariantsTable } from 'component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; @@ -85,20 +84,17 @@ export const VariantPatch = ({ {actions} - 1} - show={ - <> - -

    Stickiness:

    - - {change.payload.variants[0]?.stickiness || - 'default'} - -
    - - } - /> + {change.payload.variants.length > 1 ? ( + <> + +

    Stickiness:

    + + {change.payload.variants[0]?.stickiness || + 'default'} + +
    + + ) : null} ); }; diff --git a/frontend/src/component/changeRequest/ChangeRequest/NameWithChangeInfo/NameWithChangeInfo.tsx b/frontend/src/component/changeRequest/ChangeRequest/NameWithChangeInfo/NameWithChangeInfo.tsx index 963418031de3..95fb0f9aa1f7 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/NameWithChangeInfo/NameWithChangeInfo.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/NameWithChangeInfo/NameWithChangeInfo.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react'; import { Typography, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { textTruncated } from 'themes/themeStyles'; const Truncated = styled('div')(() => ({ @@ -16,24 +15,18 @@ export const NameWithChangeInfo: FC<{ return ( <> - - - {previousName} - - - } - /> - - {newName} - - } - /> + {titleHasChanged ? ( + + + {previousName} + + + ) : null} + {newName ? ( + + {newName} + + ) : null} ); }; diff --git a/frontend/src/component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog.tsx b/frontend/src/component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog.tsx index c0f945038aa9..29979701aa65 100644 --- a/frontend/src/component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog.tsx @@ -3,7 +3,6 @@ import { Alert, Typography } from '@mui/material'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useChangeRequestInReviewWarning } from 'hooks/useChangeRequestInReviewWarning'; interface IChangeRequestDialogueProps { @@ -48,22 +47,15 @@ export const ChangeRequestDialogue: FC = ({ title='Request changes' fullWidth > - - - Change requests feature is enabled for {environment}. - Your changes need to be approved before they will be - live. All the changes you do now will be added into a - draft that you can submit for review. - - } - /> - + {hasChangeRequestInReviewForEnvironment ? alert : null} + {showBanner ? ( + + Change requests feature is enabled for {environment}. Your + changes need to be approved before they will be live. All + the changes you do now will be added into a draft that you + can submit for review. + + ) : null} Your suggestion: diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx index 1329c8054381..46705daaedfe 100644 --- a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestOverview.tsx @@ -12,7 +12,6 @@ import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useCh import { ChangeRequestReviewStatus } from './ChangeRequestReviewStatus/ChangeRequestReviewStatus'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import Paper from '@mui/material/Paper'; import { ReviewButton } from './ReviewButton/ReviewButton'; import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser'; @@ -340,19 +339,16 @@ export const ChangeRequestOverview: FC = () => { Comment - ({ - marginTop: theme.spacing(1.5), - })} - severity='info' - > - You can not approve your own change request - - } - /> + {isSelfReview ? ( + ({ + marginTop: theme.spacing(1.5), + })} + severity='info' + > + You can not approve your own change request + + ) : null} @@ -360,122 +356,104 @@ export const ChangeRequestOverview: FC = () => { } /> - - setShowRejectDialog(true) - } - onApprove={onApprove} - disabled={ - !allowChangeRequestActions || - disabled - } - > - Review changes ({countOfChanges}) - - } - /> + {changeRequest.state === 'In review' && + !hasApprovedAlready ? ( + setShowRejectDialog(true)} + onApprove={onApprove} + disabled={ + !allowChangeRequestActions || disabled + } + > + Review changes ({countOfChanges}) + + ) : null} - - setShowScheduleChangeDialog(true) - } - > - Apply or schedule changes - - } - /> - - setShowApplyScheduledDialog(true) - } - disabled={ - !allowChangeRequestActions || - disabled - } - onSchedule={() => - setShowScheduleChangeDialog(true) - } - variant={'update'} - > - Apply or schedule changes - - } - /> + {changeRequest.state === 'Approved' ? ( + + setShowScheduleChangeDialog(true) + } + > + Apply or schedule changes + + ) : null} + {changeRequest.state === 'Scheduled' ? ( + + setShowApplyScheduledDialog(true) + } + disabled={ + !allowChangeRequestActions || disabled + } + onSchedule={() => + setShowScheduleChangeDialog(true) + } + variant={'update'} + > + Apply or schedule changes + + ) : null} - { - navigate( - `/playground?changeRequest=${changeRequest.id}&projects=${projectId}&environments=${changeRequest.environment}`, - ); - }} - > - Preview changes - - } - /> + {changeRequestPlaygroundEnabled && + (changeRequest.state === 'In review' || + changeRequest.state === 'Approved' || + changeRequest.state === 'Scheduled') ? ( + { + navigate( + `/playground?changeRequest=${changeRequest.id}&projects=${projectId}&environments=${changeRequest.environment}`, + ); + }} + > + Preview changes + + ) : null} - - setShowRejectScheduledDialog( - true, - ) - } - disabled={disabled} - > - Reject changes - - } - elseShow={ - - Cancel changes - - } - /> - } - /> + {changeRequest.state !== 'Applied' && + changeRequest.state !== 'Rejected' && + changeRequest.state !== 'Cancelled' && + (changeRequest.createdBy.id === user?.id || + isAdmin) ? ( + + setShowRejectScheduledDialog( + true, + ) + } + disabled={disabled} + > + Reject changes + + } + elseShow={ + + Cancel changes + + } + /> + ) : ( + + Cancel changes + + )} diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestReviewers/ChangeRequestApprovals.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestReviewers/ChangeRequestApprovals.tsx index 11ad8a17435c..58cd46077624 100644 --- a/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestReviewers/ChangeRequestApprovals.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestOverview/ChangeRequestReviewers/ChangeRequestApprovals.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react'; import { Typography } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ChangeRequestApprover } from './ChangeRequestReviewer'; import type { IChangeRequestApproval } from '../../changeRequest.types'; @@ -13,11 +12,7 @@ export const ChangeRequestApprovals: FC = ({ }) => ( <> - 0} - show={'Approved by'} - elseShow={'No approvals yet'} - /> + {approvals?.length > 0 ? 'Approved by' : 'No approvals yet'} {approvals.map((approver) => ( } > - - } - elseShow={ - - } - /> + {changeRequest.state === 'Rejected' ? ( + + ) : ( + + )} ); diff --git a/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/ChangeRequestTitle.tsx b/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/ChangeRequestTitle.tsx index e740baca08ef..690ab48fa44c 100644 --- a/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/ChangeRequestTitle.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/ChangeRequestTitle.tsx @@ -4,7 +4,6 @@ import { Box, Button, IconButton, styled, Typography } from '@mui/material'; import Input from 'component/common/Input/Input'; import type { ChangeRequestType } from '../../changeRequest.types'; import Edit from '@mui/icons-material/Edit'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; import { formatUnknownError } from 'utils/formatUnknownError'; import useToast from 'hooks/useToast'; @@ -57,50 +56,42 @@ export const ChangeRequestTitle: FC<{ }; return ( - setTitle(e.target.value)} - disabled={isDisabled} - /> - } - /> - - - - } - /> - - - {' '} - - } - /> + {isDisabled ? ( + children + ) : ( + setTitle(e.target.value)} + disabled={isDisabled} + /> + )} + {isDisabled ? ( + + + + ) : null} + {!isDisabled ? ( + <> + + {' '} + + ) : null} ); }; diff --git a/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx b/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx index 70f82da2ec8a..738e02c986dc 100644 --- a/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestSidebar/EnvironmentChangeRequest/EnvironmentChangeRequest.tsx @@ -11,7 +11,6 @@ import { import type { ChangeRequestType } from '../../changeRequest.types'; import { useNavigate } from 'react-router-dom'; import { ChangeRequestStatusBadge } from '../../ChangeRequestStatusBadge/ChangeRequestStatusBadge'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { changesCount } from '../../changesCount'; import { Separator, @@ -147,73 +146,58 @@ export const EnvironmentChangeRequest: FC<{ {children} - - } - /> + {environmentChangeRequest?.state === 'Draft' ? ( + + ) : null} - - onReview(sendToReview)} - count={changesCount( - environmentChangeRequest, - )} - disabled={disabled} - /> + {environmentChangeRequest?.state === 'Draft' ? ( + <> + onReview(sendToReview)} + count={changesCount(environmentChangeRequest)} + disabled={disabled} + /> + + + ) : null} + {environmentChangeRequest.state === 'In review' || + environmentChangeRequest.state === 'Approved' ? ( + <> + + + + Draft successfully sent to review + - - } - /> - - - - - Draft successfully sent to review - - - - - } - /> + + + ) : null}
    diff --git a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx index fcb3af241522..8322345d4c9d 100644 --- a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx +++ b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx @@ -14,7 +14,6 @@ import { Box, styled, Tab, Tabs, useMediaQuery } from '@mui/material'; import { Link, useSearchParams } from 'react-router-dom'; import { sortTypes } from 'utils/sortTypes'; import { useEffect, useMemo, useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Search } from 'component/common/Search/Search'; import { featuresPlaceholder } from 'component/feature/FeatureToggleList/FeatureToggleListTable'; import theme from 'themes/theme'; @@ -339,25 +338,26 @@ export const ChangeRequestsTabs = ({ - ( - 0} - show={ - - No changes found matching “ - {searchValue}” - - } - elseShow={ - - None of the changes were submitted yet. - - } - /> - )} - /> + {rows.length === 0 ? ( + 0} + show={ + + No changes found matching “ + {searchValue}” + + } + elseShow={ + + None of the changes were submitted yet. + + } + /> + ) : ( + + None of the changes were submitted yet. + + )} ); }; diff --git a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/FeaturesCell.tsx b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/FeaturesCell.tsx index 5ae6448e5f4f..c9f52f9ec34d 100644 --- a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/FeaturesCell.tsx +++ b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/FeaturesCell.tsx @@ -1,7 +1,6 @@ import { Box, styled } from '@mui/material'; import { Link } from 'react-router-dom'; import type { VFC } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { TooltipLink } from 'component/common/TooltipLink/TooltipLink'; import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { Highlighter } from 'component/common/Highlighter/Highlighter'; @@ -48,9 +47,8 @@ export const FeaturesCell: VFC = ({ value, project }) => { const featureNames = value?.map((feature: any) => feature.name); return ( - ( + {featureNames?.length < 3 ? ( + featureNames?.map((featureName: string) => ( = ({ value, project }) => { {featureName} - ))} - elseShow={ - - {featureNames?.map((featureName: string) => ( - - - {featureName} - - - ))} - - } - > - {featureNames?.length} toggles - - } - /> + )) + ) : ( + + {featureNames?.map((featureName: string) => ( + + + {featureName} + + + ))} + + } + > + {featureNames?.length} toggles + + )} ); }; diff --git a/frontend/src/component/changeRequest/UpdateCount.tsx b/frontend/src/component/changeRequest/UpdateCount.tsx index e6a45d118a33..c044266ff97a 100644 --- a/frontend/src/component/changeRequest/UpdateCount.tsx +++ b/frontend/src/component/changeRequest/UpdateCount.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react'; import { Box, Typography } from '@mui/material'; -import { ConditionallyRender } from '../common/ConditionallyRender/ConditionallyRender'; export const UpdateCount: FC<{ featuresCount: number; @@ -16,24 +15,21 @@ export const UpdateCount: FC<{ {featuresCount}{' '} {featuresCount === 1 ? 'feature flag' : 'feature flags'} - 0} - show={ - <> - - {' and '} - - - {segmentsCount}{' '} - {segmentsCount === 1 ? 'segment' : 'segments'} - - - } - /> + {segmentsCount > 0 ? ( + <> + + {' and '} + + + {segmentsCount}{' '} + {segmentsCount === 1 ? 'segment' : 'segments'} + + + ) : null} ); diff --git a/frontend/src/component/commandBar/CommandBar.tsx b/frontend/src/component/commandBar/CommandBar.tsx index 25cb4889eaa6..e351aa37a1b8 100644 --- a/frontend/src/component/commandBar/CommandBar.tsx +++ b/frontend/src/component/commandBar/CommandBar.tsx @@ -9,7 +9,6 @@ import { } from '@mui/material'; import Close from '@mui/icons-material/Close'; import SearchIcon from '@mui/icons-material/Search'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useKeyboardShortcut } from 'hooks/useKeyboardShortcut'; import { SEARCH_INPUT } from 'utils/testIds'; import { useOnClickOutside } from 'hooks/useOnClickOutside'; @@ -327,89 +326,75 @@ export const CommandBar = () => { /> theme.spacing(4) }}> - - { - e.stopPropagation(); - onSearchChange(''); - searchInputRef.current?.focus(); - }} - sx={{ - padding: (theme) => theme.spacing(1), - }} - > - - - - } - /> + {value ? ( + + { + e.stopPropagation(); + onSearchChange(''); + searchInputRef.current?.focus(); + }} + sx={{ + padding: (theme) => theme.spacing(1), + }} + > + + + + ) : null} - - + {searchString !== undefined && ( + + )} + {!searchLoading ? ( + <> + + + {hasNoResults ? ( + + ) : null} + + ) : null} + + ) : ( + showSuggestions && ( - {searchString !== undefined && ( - - )} - - - - - } - /> - - } + + - } - elseShow={ - showSuggestions && ( - - - - - ) - } - /> + ) + )} ); }; diff --git a/frontend/src/component/commandBar/CommandBarFeedback.tsx b/frontend/src/component/commandBar/CommandBarFeedback.tsx index 060ffe6d5c08..70988c99725b 100644 --- a/frontend/src/component/commandBar/CommandBarFeedback.tsx +++ b/frontend/src/component/commandBar/CommandBarFeedback.tsx @@ -1,7 +1,6 @@ import { Button, styled, TextField } from '@mui/material'; import type React from 'react'; import { useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useUserFeedbackApi } from 'hooks/api/actions/useUserFeedbackApi/useUserFeedbackApi'; import useToast from 'hooks/useToast'; import useUserType from '../feedbackNew/useUserType'; @@ -50,47 +49,43 @@ export const CommandBarFeedback = ({ onSubmit }: ICommandBarFeedbackProps) => { }; return ( - - Describe the capability - - - Send to Unleash - - - } - elseShow={ - <> - - We couldn’t find anything matching your search - criteria. If you think this is a missing capability, - feel free to make a suggestion. - - { - e.stopPropagation(); - setSuggesting(true); - }} - > - Suggest capability - - - } - /> + {suggesting ? ( + <> + Describe the capability + + + Send to Unleash + + + ) : ( + <> + + We couldn’t find anything matching your search criteria. + If you think this is a missing capability, feel free to + make a suggestion. + + { + e.stopPropagation(); + setSuggesting(true); + }} + > + Suggest capability + + + )} ); }; diff --git a/frontend/src/component/commandBar/CommandSearchFeatures.tsx b/frontend/src/component/commandBar/CommandSearchFeatures.tsx index cb009fa75585..6b042cebe97f 100644 --- a/frontend/src/component/commandBar/CommandSearchFeatures.tsx +++ b/frontend/src/component/commandBar/CommandSearchFeatures.tsx @@ -4,7 +4,6 @@ import { } from './RecentlyVisited/CommandResultGroup'; import { useFeatureSearch } from 'hooks/api/getters/useFeatureSearch/useFeatureSearch'; import { useEffect } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface ICommandBar { searchString: string; @@ -43,17 +42,12 @@ export const CommandSearchFeatures = ({ setSearchLoading(loading); }, [loading]); - return ( - - } + return !loading ? ( + - ); + ) : null; }; diff --git a/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx b/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx index cc0d39e589f5..3d405430e676 100644 --- a/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx +++ b/frontend/src/component/commandBar/RecentlyVisited/CommandResultGroup.tsx @@ -9,7 +9,6 @@ import { } from '@mui/material'; import { Link } from 'react-router-dom'; import type { Theme } from '@mui/material/styles/createTheme'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { IconRenderer } from 'component/layout/MainLayout/NavigationSidebar/IconRenderer'; import InsightsIcon from '@mui/icons-material/Insights'; import PlaygroundIcon from '@mui/icons-material/AutoFixNormal'; @@ -259,11 +258,11 @@ export const CommandResultGroup = ({ sx={listItemButtonStyle} > - } - elseShow={{icon}} - /> + {groupName === 'Projects' ? ( + + ) : ( + {icon} + )} = ({ } }; - return ( - - {children} - - } - /> - ); + return show ? ( +
    + {children} +
    + ) : null; }; export default AnimateOnMount; diff --git a/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx b/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx index edb852a1e343..ea7149120bcd 100644 --- a/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx +++ b/frontend/src/component/common/ApiTokenTable/ApiTokenTable.tsx @@ -5,7 +5,6 @@ import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightC import { ApiTokenDocs } from 'component/admin/apiToken/ApiTokenDocs/ApiTokenDocs'; import theme from 'themes/theme'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns'; @@ -52,14 +51,11 @@ export const ApiTokenTable = ({ return ( <> - 0} - show={ - - - - } - /> + {rows.length > 0 ? ( + + + + ) : null} - 0} - show={ - - No tokens found matching “ - {globalFilter} - ” - - } - elseShow={ - - - {'No tokens available. Read '} - - API How-to guides - {' '} - {' to learn more.'} - - - } - /> - } - /> + {rows.length === 0 && !loading ? ( + 0} + show={ + + No tokens found matching “ + {globalFilter} + ” + + } + elseShow={ + + + {'No tokens available. Read '} + + API How-to guides + {' '} + {' to learn more.'} + + + } + /> + ) : ( + + + {'No tokens available. Read '} + + API How-to guides + {' '} + {' to learn more.'} + + + )} ); }; diff --git a/frontend/src/component/common/AvatarGroup/AvatarGroup.tsx b/frontend/src/component/common/AvatarGroup/AvatarGroup.tsx index ad7a85cc0e83..7943a81e1378 100644 --- a/frontend/src/component/common/AvatarGroup/AvatarGroup.tsx +++ b/frontend/src/component/common/AvatarGroup/AvatarGroup.tsx @@ -1,5 +1,4 @@ import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { IGroupUser } from 'interfaces/group'; import { useMemo } from 'react'; import { UserAvatar } from 'component/common/UserAvatar/UserAvatar'; // usage @@ -78,14 +77,11 @@ const AvatarGroupInner = ({ {shownUsers.map((user) => ( ))} - avatarLimit} - show={ - - +{users.length - shownUsers.length} - - } - /> + {users.length > avatarLimit ? ( + + +{users.length - shownUsers.length} + + ) : null} ); }; diff --git a/frontend/src/component/common/Badge/Badge.tsx b/frontend/src/component/common/Badge/Badge.tsx index 81652c652caf..0dffa167c6fb 100644 --- a/frontend/src/component/common/Badge/Badge.tsx +++ b/frontend/src/component/common/Badge/Badge.tsx @@ -8,7 +8,6 @@ import { type ReactElement, type ReactNode, } from 'react'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; type Color = | 'info' @@ -72,15 +71,12 @@ const StyledBadgeIcon = styled('span')< const BadgeIcon = (color: Color, icon: ReactElement) => ( - - cloneElement(icon!, { - sx: { fontSize: '16px' }, - }) - } - /> + {icon?.props.sx + ? icon + : () => + cloneElement(icon!, { + sx: { fontSize: '16px' }, + })} ); @@ -108,22 +104,13 @@ export const Badge: FC = forwardRef( {...props} ref={ref} > - - {children}} - /> - + {Boolean(icon) && !iconRight ? BadgeIcon(color, icon!) : null} + {children !== null && children !== undefined && children !== '' ? ( +
    {children}
    + ) : null} + {Boolean(icon) && Boolean(iconRight) + ? BadgeIcon(color, icon!) + : null} ), ); diff --git a/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx b/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx index 1eaf61e7a844..e2decb277c28 100644 --- a/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx +++ b/frontend/src/component/common/BreadcrumbNav/BreadcrumbNav.tsx @@ -1,6 +1,5 @@ import Breadcrumbs from '@mui/material/Breadcrumbs'; import { Link, useLocation } from 'react-router-dom'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import AccessContext from 'contexts/AccessContext'; import { useContext } from 'react'; import { styled } from '@mui/material'; @@ -60,49 +59,44 @@ const BreadcrumbNav = () => { return ( - 1} - show={ - - {paths.map((path, index) => { - const lastItem = index === paths.length - 1; - if (lastItem) { - return ( - - {path} - - ); - } + {(location.pathname.includes('admin') && isAdmin) || + !location.pathname.includes('admin') ? ( + 1} + show={ + + {paths.map((path, index) => { + const lastItem = index === paths.length - 1; + if (lastItem) { + return ( + + {path} + + ); + } - let link = '/'; + let link = '/'; - paths.forEach((path, i) => { - if (i !== index && i < index) { - link += `${path}/`; - } else if (i === index) { - link += path; - } - }); + paths.forEach((path, i) => { + if (i !== index && i < index) { + link += `${path}/`; + } else if (i === index) { + link += path; + } + }); - return ( - - - {path} - - - ); - })} - - } - /> - } - /> + return ( + + + {path} + + + ); + })} + + } + /> + ) : null} ); }; diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.tsx index bf7c4f50a081..5a5ff7c7eecb 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordion.tsx @@ -1,5 +1,4 @@ import type { IConstraint } from 'interfaces/strategy'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConstraintAccordionEdit } from './ConstraintAccordionEdit/ConstraintAccordionEdit'; import { ConstraintAccordionView } from './ConstraintAccordionView/ConstraintAccordionView'; @@ -25,25 +24,19 @@ export const ConstraintAccordion = ({ }: IConstraintAccordionProps) => { if (!constraint) return null; - return ( - - } - elseShow={ - - } + return editing && onSave ? ( + + ) : ( + ); }; diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx index 8366a415a8a6..3fb5ed74de2f 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx @@ -4,7 +4,6 @@ import { CANCEL } from '../ConstraintAccordionEdit'; import type React from 'react'; import { newOperators } from 'constants/operators'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { oneOf } from 'utils/oneOf'; import { OperatorUpgradeAlert } from 'component/common/OperatorUpgradeAlert/OperatorUpgradeAlert'; @@ -51,10 +50,9 @@ export const ConstraintAccordionEditBody: React.FC< return ( <> - } - /> + {oneOf(newOperators, localConstraint.operator) ? ( + + ) : null} {children} diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx index 521b06fc8a90..f375feab0c8d 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Alert, Checkbox } from '@mui/material'; import { useThemeStyles } from 'themes/themeStyles'; import { ConstraintValueSearch } from 'component/common/ConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch'; @@ -105,35 +104,24 @@ export const RestrictiveLegalValues = ({ return ( <> - 0)} - show={ - - This constraint is using legal values that have been - deleted as valid options. If you save changes on this - constraint and then save the strategy the following - values will be removed: -
      - {illegalValues?.map((value) => ( -
    • {value}
    • - ))} -
    -
    - } - /> - + {illegalValues && illegalValues.length > 0 ? ( + + This constraint is using legal values that have been deleted + as valid options. If you save changes on this constraint and + then save the strategy the following values will be removed: +
      + {illegalValues?.map((value) => ( +
    • {value}
    • + ))} +
    +
    + ) : null} Select values from a predefined set - 100} - show={ - - } - /> + {legalValues.length > 100 ? ( + + ) : null} {filteredValues.map((match) => ( ))} - - {error}

    } - /> + {error ?

    {error}

    : null} ); }; diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx index e120d4c0edb5..65474b68c8bd 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx @@ -3,7 +3,6 @@ import { useState } from 'react'; import { ConstraintFormHeader } from '../ConstraintFormHeader/ConstraintFormHeader'; import { FormControl, RadioGroup, Radio, Alert } from '@mui/material'; import { ConstraintValueSearch } from 'component/common/ConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useThemeStyles } from 'themes/themeStyles'; import type { ILegalValue } from 'interfaces/context'; import { @@ -49,65 +48,48 @@ export const SingleLegalValue = ({ return ( <> - 0)} - show={ - ({ marginTop: theme.spacing(1) })} - > - {' '} - This constraint is using legal values that have been - deleted as a valid option. Please select a new value - from the remaining predefined legal values. The - constraint will be updated with the new value when you - save the strategy. - - } - /> + {illegalValues && illegalValues.length > 0 ? ( + ({ marginTop: theme.spacing(1) })} + > + {' '} + This constraint is using legal values that have been deleted + as a valid option. Please select a new value from the + remaining predefined legal values. The constraint will be + updated with the new value when you save the strategy. + + ) : null} Add a single {type.toLowerCase()} value - 100)} - show={ - - } - /> - - { - setError(''); - setValue(e.target.value); - }} - > - {filteredValues.map((match) => ( - } - /> - ))} - - - } - elseShow={ -

    No valid legal values available for this operator.

    - } - /> - {error}

    } - /> + {legalValues.length > 100 ? ( + + ) : null} + {legalValues.length ? ( + + { + setError(''); + setValue(e.target.value); + }} + > + {filteredValues.map((match) => ( + } + /> + ))} + + + ) : ( +

    No valid legal values available for this operator.

    + )} + {error ?

    {error}

    : null} ); }; diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx index 458f0750e1f1..8802a9a8a35b 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx @@ -3,7 +3,6 @@ import type { IConstraint } from 'interfaces/strategy'; import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext'; import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect'; import { ConstraintIcon } from 'component/common/ConstraintAccordion/ConstraintIcon'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { dateOperators, DATE_AFTER, @@ -203,25 +202,19 @@ export const ConstraintAccordionEditHeader = ({ onChange={onOperatorChange} /> - - } - /> + {showCaseSensitiveButton ? ( + + ) : null} - - {resolveText(operator, contextName)} - - } - /> + {!compact ? ( + + {resolveText(operator, contextName)} + + ) : null} ); diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/CaseSensitiveButton/CaseSensitiveButton.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/CaseSensitiveButton/CaseSensitiveButton.tsx index 707454d34dbf..8c947476f47f 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/CaseSensitiveButton/CaseSensitiveButton.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/CaseSensitiveButton/CaseSensitiveButton.tsx @@ -5,7 +5,6 @@ import { StyledToggleButtonOff, StyledToggleButtonOn, } from '../StyledToggleButton'; -import { ConditionallyRender } from '../../../../ConditionallyRender/ConditionallyRender'; import type { IConstraint } from 'interfaces/strategy'; interface CaseSensitiveButtonProps { @@ -26,26 +25,22 @@ export const CaseSensitiveButton = ({ arrow > - - - - } - elseShow={ - - - - } - /> + {localConstraint.caseInsensitive ? ( + + + + ) : ( + + + + )} ); diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx index 42ea96e9ad5d..adc422cb1d71 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx @@ -6,7 +6,6 @@ import { StyledToggleButtonOff, StyledToggleButtonOn, } from '../StyledToggleButton'; -import { ConditionallyRender } from '../../../../ConditionallyRender/ConditionallyRender'; interface InvertedOperatorButtonProps { localConstraint: IConstraint; @@ -22,26 +21,22 @@ export const InvertedOperatorButton = ({ arrow > - - - - } - elseShow={ - - - - } - /> + {localConstraint.inverted ? ( + + + + ) : ( + + + + )} ); diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx index ac9df0e5d81b..2a2024bb9f38 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx @@ -2,7 +2,6 @@ import type React from 'react'; import { IconButton, styled, Tooltip } from '@mui/material'; import Delete from '@mui/icons-material/Delete'; import Edit from '@mui/icons-material/Edit'; -import { ConditionallyRender } from '../../ConditionallyRender/ConditionallyRender'; interface ConstraintAccordionHeaderActionsProps { onDelete?: () => void; @@ -41,34 +40,28 @@ export const ConstraintAccordionHeaderActions = ({ return ( - - - - - - } - /> - - - - - - } - /> + {Boolean(onEditClick) && !disableEdit ? ( + + + + + + ) : null} + {Boolean(onDeleteClick) && !disableDelete ? ( + + + + + + ) : null} ); }; diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx index 53243fd74597..1cefe9ed43eb 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx @@ -14,7 +14,6 @@ import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashCon import { type IUseWeakMap, useWeakMap } from 'hooks/useWeakMap'; import { objectId } from 'utils/objectId'; import { createEmptyConstraint } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; export interface IConstraintAccordionListProps { @@ -123,55 +122,45 @@ export const ConstraintAccordionList = forwardRef< return ( - 0 && showLabel - } - show={ - - Constraints - - } - /> + {constraints && constraints.length > 0 && showLabel ? ( + Constraints + ) : null} - - -

    Add any number of constraints

    - - - - - -
    - - - } - /> + + + + + + + + ) : null}
    ); }, @@ -235,10 +224,7 @@ export const ConstraintList = forwardRef< > {constraints.map((constraint, index) => ( - 0} - show={} - /> + {index > 0 ? : null} { return ( <> - 20} - show={ - - } - /> + {values.length > 20 ? ( + + ) : null} {values .filter((value) => value.includes(filter)) .map((value, index) => ( diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx index f7a4f0991259..77e9ced9b5a2 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx @@ -1,6 +1,5 @@ import { styled, Tooltip } from '@mui/material'; import { ConstraintViewHeaderOperator } from './ConstraintViewHeaderOperator'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConstraintAccordionViewHeaderSingleValue } from './ConstraintAccordionViewHeaderSingleValue'; import { ConstraintAccordionViewHeaderMultipleValues } from './ConstraintAccordionViewHeaderMultipleValues'; import type { IConstraint } from 'interfaces/strategy'; @@ -79,25 +78,21 @@ export const ConstraintAccordionViewHeaderInfo = ({ constraint={constraint} disabled={disabled} /> - - } - elseShow={ - - } - /> + {singleValue ? ( + + ) : ( + + )} ); diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx index 0aff879daa79..20eb135fd166 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { styled } from '@mui/material'; import { useEffect, useMemo, useState } from 'react'; import type { IConstraint } from 'interfaces/strategy'; @@ -83,18 +82,13 @@ export const ConstraintAccordionViewHeaderMultipleValues = ({ > {text} - - {!expanded - ? `View all (${constraint?.values?.length})` - : 'View less'} - - } - /> + {expandable ? ( + + {!expanded + ? `View all (${constraint?.values?.length})` + : 'View less'} + + ) : null} ); diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx index 2c6416f289d1..1a519e85c3b9 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx @@ -1,5 +1,4 @@ import type { IConstraint } from 'interfaces/strategy'; -import { ConditionallyRender } from '../../../ConditionallyRender/ConditionallyRender'; import { Tooltip, Box, styled } from '@mui/material'; import { stringOperators } from 'constants/operators'; import { ReactComponent as NegatedOnIcon } from 'assets/icons/not_operator_selected.svg'; @@ -35,18 +34,15 @@ export const ConstraintViewHeaderOperator = ({ const theme = useTheme(); return ( - - - - - - - - } - /> + {constraint.inverted ? ( + + + + + + + + ) : null} - - - - - - } - /> + {!constraint.caseInsensitive && + oneOf(stringOperators, constraint.operator) ? ( + + + + + + ) : null} ); }; diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx index ce0911e7482b..2b31de56ddf7 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx @@ -1,6 +1,5 @@ import { forwardRef, type ReactNode } from 'react'; import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; export const StyledIconWrapperBase = styled('div')<{ prefix?: boolean; @@ -28,10 +27,10 @@ const StyledPrefixIconWrapper = styled(StyledIconWrapperBase)(({ theme }) => ({ export const StyledIconWrapper = forwardRef< HTMLDivElement, { isPrefix?: boolean; children?: ReactNode } ->(({ isPrefix, ...props }, ref) => ( - } - elseShow={() => } - /> -)); +>(({ isPrefix, ...props }, ref) => + isPrefix ? ( + + ) : ( + + ), +); diff --git a/frontend/src/component/common/Dialogue/Dialogue.tsx b/frontend/src/component/common/Dialogue/Dialogue.tsx index c2cb20068318..70e6118a9fdc 100644 --- a/frontend/src/component/common/Dialogue/Dialogue.tsx +++ b/frontend/src/component/common/Dialogue/Dialogue.tsx @@ -9,7 +9,6 @@ import { styled, } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { DIALOGUE_CONFIRM_ID } from 'utils/testIds'; const StyledDialog = styled(Dialog)(({ theme, maxWidth }) => ({ @@ -103,48 +102,39 @@ export const Dialogue: React.FC = ({ > {title} - {children}} - /> + {children ? ( + {children} + ) : null} - - {primaryButtonText || "Yes, I'm sure"} - - } - /> - } - /> + {permissionButton ? ( + permissionButton! + ) : ( + + {primaryButtonText || "Yes, I'm sure"} + + } + /> + )} - - {secondaryButtonText || 'No, take me back'} - - } - /> + {onClose ? ( + + ) : null} - + {customButton ? customButton : null} diff --git a/frontend/src/component/common/ExperimentalFeedback/ExperimentalFeedback.tsx b/frontend/src/component/common/ExperimentalFeedback/ExperimentalFeedback.tsx index c78b3fa18bf0..e6a298a388e2 100644 --- a/frontend/src/component/common/ExperimentalFeedback/ExperimentalFeedback.tsx +++ b/frontend/src/component/common/ExperimentalFeedback/ExperimentalFeedback.tsx @@ -7,7 +7,6 @@ import { usePlausibleTracker, } from 'hooks/usePlausibleTracker'; import { createLocalStorage } from 'utils/createLocalStorage'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledOuterContainer = styled(Box)(({ theme }) => ({ backgroundColor: theme.palette.background.paper, @@ -116,45 +115,36 @@ export const ExperimentalFeedback: React.FC = ({ We are trying something experimental! {description} -
    - - + {' '} + Is this useful to you? - {' '} - Is this useful to you? - - onBtnClick('useful')} - > - Yes, I like the direction - - - + onBtnClick('useful')} + > + Yes, I like the direction + + - } - elseShow={ - ({ marginTop: theme.spacing(3) })} - > - Thank you for the feedback. Feel free to check out the - sketches and leave comments, or get in touch with our UX - team if you'd like to be involved in usertests and the - development of this feature. - - } - /> - + + ) : ( + ({ marginTop: theme.spacing(3) })}> + Thank you for the feedback. Feel free to check out the + sketches and leave comments, or get in touch with our UX + team if you'd like to be involved in usertests and the + development of this feature. + + )} diff --git a/frontend/src/component/common/FavoriteIconButton/FavoriteIconButton.tsx b/frontend/src/component/common/FavoriteIconButton/FavoriteIconButton.tsx index 961cadcd72ba..2aed25428ea9 100644 --- a/frontend/src/component/common/FavoriteIconButton/FavoriteIconButton.tsx +++ b/frontend/src/component/common/FavoriteIconButton/FavoriteIconButton.tsx @@ -1,6 +1,5 @@ import type { VFC } from 'react'; import { IconButton, type IconButtonProps } from '@mui/material'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; import StarIcon from '@mui/icons-material/Star'; import StarBorderIcon from '@mui/icons-material/StarBorder'; import { TooltipResolver } from '../TooltipResolver/TooltipResolver'; @@ -20,31 +19,27 @@ export const FavoriteIconButton: VFC = ({ title={isFavorite ? 'Remove from favorites' : 'Add to favorites'} > - - size === 'medium' - ? theme.spacing(2) - : theme.spacing(3), - }} - /> - } - elseShow={ - - size === 'medium' - ? theme.spacing(2) - : theme.spacing(3), - }} - /> - } - /> + {isFavorite ? ( + + size === 'medium' + ? theme.spacing(2) + : theme.spacing(3), + }} + /> + ) : ( + + size === 'medium' + ? theme.spacing(2) + : theme.spacing(3), + }} + /> + )}
    ); diff --git a/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx b/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx index 8430a71ce071..0bc04685b0e3 100644 --- a/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx +++ b/frontend/src/component/common/FeatureArchiveDialog/FeatureArchiveDialog.tsx @@ -3,7 +3,6 @@ import { Dialogue } from 'component/common/Dialogue/Dialogue'; import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi'; import { Alert, Typography } from '@mui/material'; import { Link } from 'react-router-dom'; @@ -375,88 +374,67 @@ export const FeatureArchiveDialog: VFC = ({ title={dialogTitle} disabledPrimaryButton={disableArchive} > - -

    - Are you sure you want to archive{' '} - {featureIds?.length} feature flags? -

    + {isBulkArchive ? ( + <> +

    + Are you sure you want to archive{' '} + {featureIds?.length} feature flags? +

    - 0, - )} - show={ - - } - /> - 0} - show={ - - } - /> - } + {featuresWithUsage && featuresWithUsage?.length > 0 ? ( + - - 0 ? ( + + ) : null} + {removeDependenciesWarning ? ( + + ) : null} - - {featureIds?.map((id) => ( -
  • {id}
  • - ))} - - } - /> - - } - elseShow={ - <> -

    - Are you sure you want to archive{' '} - {isBulkArchive - ? 'these feature flags' - : 'this feature flag'} - ? -

    - 0} - show={ - - } - /> - } - /> + - + {featureIds?.map((id) => ( +
  • {id}
  • + ))} + + ) : null} + + ) : ( + <> +

    + Are you sure you want to archive{' '} + {isBulkArchive + ? 'these feature flags' + : 'this feature flag'} + ? +

    + {offendingParents.length > 0 ? ( + - - } - /> + ) : null} + {removeDependenciesWarning ? ( + + ) : null} + + + + )} ); }; diff --git a/frontend/src/component/common/FeatureStaleDialog/FeatureStaleDialog.tsx b/frontend/src/component/common/FeatureStaleDialog/FeatureStaleDialog.tsx index 4eb2e750ad27..1b418cb0045f 100644 --- a/frontend/src/component/common/FeatureStaleDialog/FeatureStaleDialog.tsx +++ b/frontend/src/component/common/FeatureStaleDialog/FeatureStaleDialog.tsx @@ -1,6 +1,5 @@ import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; import { Typography } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import type React from 'react'; import useToast from 'hooks/useToast'; @@ -71,11 +70,7 @@ export const FeatureStaleDialog = ({ onClick={onSubmit} onClose={onClose} > - + {isStale ? flagToActiveContent : flagToStaleContent} ); }; diff --git a/frontend/src/component/common/FormTemplate/FormTemplate.tsx b/frontend/src/component/common/FormTemplate/FormTemplate.tsx index dcb9ec6ce39c..dec7f148abb2 100644 --- a/frontend/src/component/common/FormTemplate/FormTemplate.tsx +++ b/frontend/src/component/common/FormTemplate/FormTemplate.tsx @@ -8,7 +8,6 @@ import { Divider, styled, } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import FileCopy from '@mui/icons-material/FileCopy'; import Info from '@mui/icons-material/Info'; import Loader from '../Loader/Loader'; @@ -281,10 +280,7 @@ const FormTemplate: React.FC = ({ if (!apiDisabled) { return ( <> - } - /> + {!dividerDisabled ? : null} API Command{' '} @@ -303,68 +299,56 @@ const FormTemplate: React.FC = ({ return ( - - - - } - /> + {showGuidance && smallScreen ? ( + + + + ) : null} - } - elseShow={ - <> - {title}} - /> - {children} - - } - /> - - ( + {loading || false ? ( + + ) : ( <> - - {footer} + {title !== undefined ? ( + {title} + ) : null} + {children} )} - /> + + {footer !== undefined ? ( + <> + + {footer} + + ) : null} - - {renderApiInfo( - formatApiCode === undefined, - !(showDescription || showLink), - )} - - } - /> + {showGuidance && !smallScreen ? ( + + {renderApiInfo( + formatApiCode === undefined, + !(showDescription || showLink), + )} + + ) : null} ); }; @@ -451,38 +435,29 @@ const GuidanceContent: React.FC< return ( <> - - - {documentationIcon} - - } - /> - {description} - - } - /> - - - - - {documentationLinkLabel} - - - } - /> + {showDescription ? ( + + {documentationIcon ? ( + + {documentationIcon} + + ) : null} + {description} + + ) : null} + + {showLink && !!documentationLink ? ( + + + + {documentationLinkLabel} + + + ) : null} {children} diff --git a/frontend/src/component/common/InstanceStatus/InstanceStatus.tsx b/frontend/src/component/common/InstanceStatus/InstanceStatus.tsx index b056a6a79450..8240d1220057 100644 --- a/frontend/src/component/common/InstanceStatus/InstanceStatus.tsx +++ b/frontend/src/component/common/InstanceStatus/InstanceStatus.tsx @@ -7,7 +7,6 @@ import React, { useContext, } from 'react'; import { InstanceStatusBar } from 'component/common/InstanceStatus/InstanceStatusBar'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { Typography } from '@mui/material'; import { useNavigate } from 'react-router-dom'; @@ -128,20 +127,15 @@ export const InstanceStatus: FC<{ children?: React.ReactNode }> = ({ return ( <> - ( - <> - - - - )} - /> + {instanceStatus ? ( + <> + + + + ) : null} {children} ); diff --git a/frontend/src/component/common/Limit/Limit.tsx b/frontend/src/component/common/Limit/Limit.tsx index 714c0db2bbe2..7af6a00ec198 100644 --- a/frontend/src/component/common/Limit/Limit.tsx +++ b/frontend/src/component/common/Limit/Limit.tsx @@ -5,7 +5,6 @@ import WarningIcon from '@mui/icons-material/ErrorOutlined'; import ErrorIcon from '@mui/icons-material/Cancel'; import CloseIcon from '@mui/icons-material/Close'; import type { FC } from 'react'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; const StyledBox = styled(Box)(({ theme }) => ({ @@ -98,36 +97,29 @@ export const Limit: FC<{ return (
    - } - elseShow={} - /> - - - You are nearing the limit for {name} - - } - elseShow={ - - You have reached the limit for {name} - - } - /> - - - - - - - } - /> + {belowLimit ? ( + + ) : ( + + )} + + {belowLimit ? ( + + You are nearing the limit for {name} + + ) : ( + + You have reached the limit for {name} + + )} + + {typeof onClose === 'function' ? ( + + + + + + ) : null}
    diff --git a/frontend/src/component/common/MainHeader/MainHeader.tsx b/frontend/src/component/common/MainHeader/MainHeader.tsx index 57003541d75b..005682b75841 100644 --- a/frontend/src/component/common/MainHeader/MainHeader.tsx +++ b/frontend/src/component/common/MainHeader/MainHeader.tsx @@ -1,7 +1,6 @@ import { Paper, styled } from '@mui/material'; import { usePageTitle } from 'hooks/usePageTitle'; import type { ReactNode } from 'react'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; const StyledMainHeader = styled(Paper)(({ theme }) => ({ borderRadius: theme.shape.borderRadiusLarge, @@ -50,15 +49,12 @@ export const MainHeader = ({ {title} {actions} - - Description: - {description} - - } - /> + {description?.length ? ( + <> + Description: + {description} + + ) : null} ); }; diff --git a/frontend/src/component/common/MultipleRoleSelect/MultipleRoleSelect.tsx b/frontend/src/component/common/MultipleRoleSelect/MultipleRoleSelect.tsx index a5b2af949255..5e09d6a53b23 100644 --- a/frontend/src/component/common/MultipleRoleSelect/MultipleRoleSelect.tsx +++ b/frontend/src/component/common/MultipleRoleSelect/MultipleRoleSelect.tsx @@ -10,7 +10,6 @@ import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; import type { IRole } from 'interfaces/role'; import { RoleDescription } from '../RoleDescription/RoleDescription'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; const StyledRoleOption = styled('div')(({ theme }) => ({ display: 'flex', @@ -72,20 +71,17 @@ export const MultipleRoleSelect = ({ )} {...rest} /> - 0} - show={() => ( - <> - {value.map(({ id }) => ( - - ))} - - )} - /> + {value.length > 0 ? ( + <> + {value.map(({ id }) => ( + + ))} + + ) : null} ); }; diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx index 81c2fc4cb8bc..a202e1e9c4ab 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/ConstraintAccordionEditBody.tsx @@ -3,7 +3,6 @@ import type { IConstraint } from 'interfaces/strategy'; import type React from 'react'; import { newOperators } from 'constants/operators'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { oneOf } from 'utils/oneOf'; import { OperatorUpgradeAlert } from 'component/common/OperatorUpgradeAlert/OperatorUpgradeAlert'; @@ -50,10 +49,9 @@ export const ConstraintAccordionEditBody: React.FC< return ( <> - } - /> + {oneOf(newOperators, localConstraint.operator) ? ( + + ) : null} {children} diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/FreeTextInput/FreeTextInput.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/FreeTextInput/FreeTextInput.tsx index c74e4d8d6168..b0a3798b27e8 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/FreeTextInput/FreeTextInput.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/FreeTextInput/FreeTextInput.tsx @@ -8,7 +8,6 @@ import { ConstraintFormHeader } from '../ConstraintFormHeader/ConstraintFormHead import { parseParameterStrings } from 'utils/parseParameter'; import { useUiFlag } from 'hooks/useUiFlag'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Limit } from 'component/common/Limit/Limit'; interface IFreeTextInputProps { @@ -148,17 +147,14 @@ export const FreeTextInput = ({ /> - - } - /> + {resourceLimitsEnabled ? ( + + ) : null} ); diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx index 991b34052a93..23a500a382cb 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/RestrictiveLegalValues/RestrictiveLegalValues.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Alert, Button, Checkbox, Chip, Stack, styled } from '@mui/material'; import { ConstraintValueSearch } from 'component/common/ConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch'; import { ConstraintFormHeader } from '../ConstraintFormHeader/ConstraintFormHeader'; @@ -144,22 +143,18 @@ export const RestrictiveLegalValues = ({ return ( <> - 0)} - show={ - - This constraint is using legal values that have been - deleted as valid options. If you save changes on this - constraint and then save the strategy the following - values will be removed: -
      - {illegalValues?.map((value) => ( -
    • {value}
    • - ))} -
    -
    - } - /> + {illegalValues && illegalValues.length > 0 ? ( + + This constraint is using legal values that have been deleted + as valid options. If you save changes on this constraint and + then save the strategy the following values will be removed: +
      + {illegalValues?.map((value) => ( +
    • {value}
    • + ))} +
    +
    + ) : null} Select values from a predefined set @@ -168,36 +163,28 @@ export const RestrictiveLegalValues = ({ {isAllSelected ? 'Unselect all' : 'Select all'} - 100} - show={ - <> - - {values.map((value) => { - return ( - onChange(value)} - /> - ); - })} - - } - /> - - - } - /> + {legalValues.length > 100 ? ( + <> + {!disableShowContextFieldSelectionValues && + Boolean(values) ? ( + + {values.map((value) => { + return ( + onChange(value)} + /> + ); + })} + + ) : null} + + + ) : null} {filteredValues.map((match) => ( ))} - {error}} - /> + {error ? {error} : null} ); }; diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx index 861aff745cba..ab1acfa3bccc 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/SingleLegalValue/SingleLegalValue.tsx @@ -3,7 +3,6 @@ import { useState } from 'react'; import { ConstraintFormHeader } from '../ConstraintFormHeader/ConstraintFormHeader'; import { FormControl, RadioGroup, Radio, Alert, styled } from '@mui/material'; import { ConstraintValueSearch } from 'component/common/ConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useThemeStyles } from 'themes/themeStyles'; import type { ILegalValue } from 'interfaces/context'; import { @@ -60,68 +59,51 @@ export const SingleLegalValue = ({ return ( <> - 0)} - show={ - ({ marginTop: theme.spacing(1) })} - > - {' '} - This constraint is using legal values that have been - deleted as a valid option. Please select a new value - from the remaining predefined legal values. The - constraint will be updated with the new value when you - save the strategy. - - } - /> + {illegalValues && illegalValues.length > 0 ? ( + ({ marginTop: theme.spacing(1) })} + > + {' '} + This constraint is using legal values that have been deleted + as a valid option. Please select a new value from the + remaining predefined legal values. The constraint will be + updated with the new value when you save the strategy. + + ) : null} Add a single {type.toLowerCase()} value - 100)} - show={ - - } - /> - - - theme.spacing(0.5) }} - onChange={(e) => { - setError(''); - setValue(e.target.value); - }} - > - {filteredValues.map((match) => ( - } - /> - ))} - - - - } - elseShow={ -

    No valid legal values available for this operator.

    - } - /> - {error}

    } - /> + {legalValues.length > 100 ? ( + + ) : null} + {legalValues.length ? ( + + + theme.spacing(0.5) }} + onChange={(e) => { + setError(''); + setValue(e.target.value); + }} + > + {filteredValues.map((match) => ( + } + /> + ))} + + + + ) : ( +

    No valid legal values available for this operator.

    + )} + {error ?

    {error}

    : null} ); }; diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx index c15987f58374..1a7d93ef5e55 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditHeader/ConstraintAccordionEditHeader.tsx @@ -3,7 +3,6 @@ import type { IConstraint } from 'interfaces/strategy'; import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext'; import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect'; import { ConstraintIcon } from 'component/common/ConstraintAccordion/ConstraintIcon'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { dateOperators, DATE_AFTER, @@ -207,25 +206,19 @@ export const ConstraintAccordionEditHeader = ({ onChange={onOperatorChange} /> - - } - /> + {showCaseSensitiveButton ? ( + + ) : null} - - {resolveText(operator, contextName)} - - } - /> + {!compact ? ( + + {resolveText(operator, contextName)} + + ) : null} - - - - } - elseShow={ - - - - } - /> + {localConstraint.caseInsensitive ? ( + + + + ) : ( + + + + )} ); diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx index ec75f0bd369e..1676a0d99d21 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionEdit/StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton.tsx @@ -6,7 +6,6 @@ import { StyledToggleButtonOff, StyledToggleButtonOn, } from '../StyledToggleButton'; -import { ConditionallyRender } from '../../../../ConditionallyRender/ConditionallyRender'; interface InvertedOperatorButtonProps { localConstraint: Pick; @@ -22,26 +21,22 @@ export const InvertedOperatorButton = ({ arrow > - - - - } - elseShow={ - - - - } - /> + {localConstraint.inverted ? ( + + + + ) : ( + + + + )} ); diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx index 8443c3060052..06bbb23fedf0 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions.tsx @@ -3,7 +3,6 @@ import { IconButton, styled, Tooltip } from '@mui/material'; import Delete from '@mui/icons-material/Delete'; import Edit from '@mui/icons-material/Edit'; import Undo from '@mui/icons-material/Undo'; -import { ConditionallyRender } from '../../ConditionallyRender/ConditionallyRender'; import type { IConstraint } from 'interfaces/strategy'; interface ConstraintAccordionHeaderActionsProps { @@ -54,51 +53,42 @@ export const ConstraintAccordionHeaderActions = ({ return ( - - - - - - } - /> - 1} - show={ - - - - - - } - /> - - - - - - } - /> + {Boolean(onEditClick) && !disableEdit ? ( + + + + + + ) : null} + {Boolean(onUndoClick) && constraintChanges.length > 1 ? ( + + + + + + ) : null} + {Boolean(onDeleteClick) && !disableDelete ? ( + + + + + + ) : null} ); }; diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewBody/MultipleValues/MultipleValues.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewBody/MultipleValues/MultipleValues.tsx index dd13705ae662..12e16db9ff4d 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewBody/MultipleValues/MultipleValues.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewBody/MultipleValues/MultipleValues.tsx @@ -1,6 +1,5 @@ import { useState } from 'react'; import { Chip, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import StringTruncator from 'component/common/StringTruncator/StringTruncator'; import { ConstraintValueSearch } from '../../../ConstraintValueSearch/ConstraintValueSearch'; @@ -23,15 +22,9 @@ export const MultipleValues = ({ values }: IMultipleValuesProps) => { return ( <> - 20} - show={ - - } - /> + {values.length > 20 ? ( + + ) : null} {values .filter((value) => value.includes(filter)) .map((value, index) => ( diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx index f7a4f0991259..77e9ced9b5a2 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderInfo.tsx @@ -1,6 +1,5 @@ import { styled, Tooltip } from '@mui/material'; import { ConstraintViewHeaderOperator } from './ConstraintViewHeaderOperator'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConstraintAccordionViewHeaderSingleValue } from './ConstraintAccordionViewHeaderSingleValue'; import { ConstraintAccordionViewHeaderMultipleValues } from './ConstraintAccordionViewHeaderMultipleValues'; import type { IConstraint } from 'interfaces/strategy'; @@ -79,25 +78,21 @@ export const ConstraintAccordionViewHeaderInfo = ({ constraint={constraint} disabled={disabled} /> - - } - elseShow={ - - } - /> + {singleValue ? ( + + ) : ( + + )} ); diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx index 0aff879daa79..20eb135fd166 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintAccordionViewHeaderMultipleValues.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { styled } from '@mui/material'; import { useEffect, useMemo, useState } from 'react'; import type { IConstraint } from 'interfaces/strategy'; @@ -83,18 +82,13 @@ export const ConstraintAccordionViewHeaderMultipleValues = ({ > {text} - - {!expanded - ? `View all (${constraint?.values?.length})` - : 'View less'} - - } - /> + {expandable ? ( + + {!expanded + ? `View all (${constraint?.values?.length})` + : 'View less'} + + ) : null} ); diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx index 2c6416f289d1..1a519e85c3b9 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/ConstraintViewHeaderOperator.tsx @@ -1,5 +1,4 @@ import type { IConstraint } from 'interfaces/strategy'; -import { ConditionallyRender } from '../../../ConditionallyRender/ConditionallyRender'; import { Tooltip, Box, styled } from '@mui/material'; import { stringOperators } from 'constants/operators'; import { ReactComponent as NegatedOnIcon } from 'assets/icons/not_operator_selected.svg'; @@ -35,18 +34,15 @@ export const ConstraintViewHeaderOperator = ({ const theme = useTheme(); return ( - - - - - - - - } - /> + {constraint.inverted ? ( + + + + + + + + ) : null} - - - - - - } - /> + {!constraint.caseInsensitive && + oneOf(stringOperators, constraint.operator) ? ( + + + + + + ) : null} ); }; diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx index ce0911e7482b..2b31de56ddf7 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionViewHeader/StyledIconWrapper.tsx @@ -1,6 +1,5 @@ import { forwardRef, type ReactNode } from 'react'; import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; export const StyledIconWrapperBase = styled('div')<{ prefix?: boolean; @@ -28,10 +27,10 @@ const StyledPrefixIconWrapper = styled(StyledIconWrapperBase)(({ theme }) => ({ export const StyledIconWrapper = forwardRef< HTMLDivElement, { isPrefix?: boolean; children?: ReactNode } ->(({ isPrefix, ...props }, ref) => ( - } - elseShow={() => } - /> -)); +>(({ isPrefix, ...props }, ref) => + isPrefix ? ( + + ) : ( + + ), +); diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch.tsx index 47d688e4932c..7449a157befd 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch.tsx @@ -1,6 +1,5 @@ import { TextField, InputAdornment, Chip } from '@mui/material'; import Search from '@mui/icons-material/Search'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface IConstraintValueSearchProps { filter: string; @@ -35,16 +34,13 @@ export const ConstraintValueSearch = ({ }} /> - setFilter('')} - /> - } - /> + {filter ? ( + setFilter('')} + /> + ) : null} ); }; diff --git a/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordion.tsx b/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordion.tsx index da4f98a5fbd4..6216baac9348 100644 --- a/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordion.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordion.tsx @@ -1,5 +1,4 @@ import type { IConstraint } from 'interfaces/strategy'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConstraintAccordionEdit } from './ConstraintAccordionEdit/ConstraintAccordionEdit'; import { ConstraintAccordionView } from './ConstraintAccordionView/ConstraintAccordionView'; @@ -27,26 +26,20 @@ export const NewConstraintAccordion = ({ }: IConstraintAccordionProps) => { if (!constraint) return null; - return ( - - } - elseShow={ - - } + return editing && onSave ? ( + + ) : ( + ); }; diff --git a/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordionList/NewConstraintAccordionList.tsx b/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordionList/NewConstraintAccordionList.tsx index f3dec38b2556..81243f525f62 100644 --- a/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordionList/NewConstraintAccordionList.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/NewConstraintAccordionList/NewConstraintAccordionList.tsx @@ -10,7 +10,6 @@ import { constraintId, createEmptyConstraint, } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { NewConstraintAccordion } from 'component/common/NewConstraintAccordion/NewConstraintAccordion'; @@ -171,11 +170,7 @@ export const NewConstraintAccordionList = forwardRef< return ( - 0} - show={} - /> - + {index > 0 ? : null} { data-testid='NOTIFICATIONS_BUTTON' size='large' > - } - /> + {hasUnreadNotifications ? : null} - - setShowNotifications(false)} + {showNotifications ? ( + setShowNotifications(false)} + > + - - - - - Show only unread - - - setShowUnread(!showUnread) - } - checked={showUnread} - /> - - - - - - } - />{' '} - + + + + Show only unread + + setShowUnread(!showUnread)} + checked={showUnread} + /> + + + {hasUnreadNotifications ? ( + + + + ) : null}{' '} + {notificationComponents?.length === 0 ? ( + - - {notificationComponents} - - - -
    - - } - /> -
    -
    - } - /> + ) : null} + + {notificationComponents} + + {shouldShowFeedback ? ( + <> + +
    + + ) : null} + + + ) : null} ); }; diff --git a/frontend/src/component/common/PageContent/PageContent.tsx b/frontend/src/component/common/PageContent/PageContent.tsx index d408eb91054d..4b8f3769d810 100644 --- a/frontend/src/component/common/PageContent/PageContent.tsx +++ b/frontend/src/component/common/PageContent/PageContent.tsx @@ -5,7 +5,6 @@ import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { Paper, type PaperProps, styled } from '@mui/material'; import { useStyles } from './PageContent.styles'; import useLoading from 'hooks/useLoading'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; interface IPageContentProps extends PaperProps { header?: ReactNode; @@ -93,18 +92,17 @@ export const PageContent: FC = ({ {...paperProps} className={classnames(className)} > - - } - elseShow={header} - /> - - } - /> + {header ? ( + + {typeof header === 'string' ? ( + + ) : ( + header + )} + + ) : ( + header + )}
    {children}
    ); diff --git a/frontend/src/component/common/PageHeader/PageHeader.tsx b/frontend/src/component/common/PageHeader/PageHeader.tsx index ead77001106b..914fa8721a98 100644 --- a/frontend/src/component/common/PageHeader/PageHeader.tsx +++ b/frontend/src/component/common/PageHeader/PageHeader.tsx @@ -10,7 +10,6 @@ import { Typography, type TypographyProps, } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { usePageTitle } from 'hooks/usePageTitle'; @@ -102,10 +101,9 @@ const PageHeaderComponent: FC & { {subtitle && {subtitle}} - {actions}} - /> + {actions ? ( + {actions} + ) : null} {children} diff --git a/frontend/src/component/common/PremiumFeature/PremiumFeature.tsx b/frontend/src/component/common/PremiumFeature/PremiumFeature.tsx index 9062f694a69e..788aff271ba3 100644 --- a/frontend/src/component/common/PremiumFeature/PremiumFeature.tsx +++ b/frontend/src/component/common/PremiumFeature/PremiumFeature.tsx @@ -2,7 +2,6 @@ import { ReactComponent as ProPlanIcon } from 'assets/icons/pro-enterprise-featu import { ReactComponent as ProPlanIconLight } from 'assets/icons/pro-enterprise-feature-badge-light.svg'; import { Box, Button, Link, styled, Typography } from '@mui/material'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; import { ThemeMode } from '../ThemeMode/ThemeMode'; import { PageContent } from '../PageContent/PageContent'; import { PageHeader } from '../PageHeader/PageHeader'; @@ -193,61 +192,54 @@ export const PremiumFeature = ({ /> {`${plan} feature`} - - - - {featureMessage}. You need to upgrade your plan - if you want to use it. - - - - - Compare plans - - - - } - elseShow={ - <> - - - {featureMessage} - - - You need to upgrade your plan if you want to use - it. - - - - - - - - } - /> + {tooltip ? ( + <> + + + {featureMessage}. You need to upgrade your plan if + you want to use it. + + + + + Compare plans + + + + ) : ( + <> + + {featureMessage} + + You need to upgrade your plan if you want to use it. + + + + + + + + )} ); diff --git a/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx b/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx index 2051bab69bc5..4da48dfc9317 100644 --- a/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx +++ b/frontend/src/component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx @@ -2,7 +2,6 @@ import type { FC } from 'react'; import millify from 'millify'; import { Tooltip } from '@mui/material'; import { LARGE_NUMBER_PRETTIFIED } from 'utils/testIds'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; interface IPrettifyLargeNumberProps { /** @@ -40,15 +39,11 @@ export const PrettifyLargeNumber: FC = ({ {prettyValue} ); - return ( - - {valueSpan} - - } - elseShow={valueSpan} - /> + return showTooltip ? ( + + {valueSpan} + + ) : ( + valueSpan ); }; diff --git a/frontend/src/component/common/Proclamation/Proclamation.tsx b/frontend/src/component/common/Proclamation/Proclamation.tsx index 8ba2c8e3437d..57cd4eb4cfbf 100644 --- a/frontend/src/component/common/Proclamation/Proclamation.tsx +++ b/frontend/src/component/common/Proclamation/Proclamation.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react'; import { Alert, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Typography } from '@mui/material'; import type { IProclamationToast } from 'interfaces/uiConfig'; @@ -49,25 +48,18 @@ const Proclamation = ({ toast }: IProclamationProps) => { if (!toast) return null; - return ( - - - {toast.message} - - - View more - - - } - /> - ); + return show ? ( + + {toast.message} + + View more + + + ) : null; }; export default Proclamation; diff --git a/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx b/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx index a6fad58c4332..1991df31ea91 100644 --- a/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx +++ b/frontend/src/component/common/ResponsiveButton/ResponsiveButton.tsx @@ -1,6 +1,5 @@ import type React from 'react'; import { useMediaQuery } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import PermissionButton from 'component/common/PermissionButton/PermissionButton'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import type { ITooltipResolverProps } from '../TooltipResolver/TooltipResolver'; @@ -33,39 +32,33 @@ const ResponsiveButton: React.FC = ({ }) => { const smallScreen = useMediaQuery(`(max-width:${maxWidth})`); - return ( - - - - } - elseShow={ - - {children} - - } - /> + return smallScreen ? ( + + + + ) : ( + + {children} + ); }; diff --git a/frontend/src/component/common/RoleDescription/RoleDescription.tsx b/frontend/src/component/common/RoleDescription/RoleDescription.tsx index c896e03b5126..04d366f60ddd 100644 --- a/frontend/src/component/common/RoleDescription/RoleDescription.tsx +++ b/frontend/src/component/common/RoleDescription/RoleDescription.tsx @@ -1,6 +1,5 @@ import { type SxProps, type Theme, styled } from '@mui/material'; import SupervisedUserCircle from '@mui/icons-material/SupervisedUserCircle'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; import { useRole } from 'hooks/api/getters/useRole/useRole'; import { PREDEFINED_ROLE_TYPES, @@ -99,32 +98,29 @@ export const RoleDescription = ({ {description} - ( - <> - - Role permissions: - - - {categories.map(({ label, permissions }) => ( -
    - - {label} - - - {permissions.map((permission) => ( -
  • - {permission.displayName} -
  • - ))} -
    -
    - ))} -
    - - )} - /> + {!PREDEFINED_ROLE_TYPES.includes(role.type) ? ( + <> + + Role permissions: + + + {categories.map(({ label, permissions }) => ( +
    + + {label} + + + {permissions.map((permission) => ( +
  • + {permission.displayName} +
  • + ))} +
    +
    + ))} +
    + + ) : null} ); }; diff --git a/frontend/src/component/common/RoleSelect/RoleSelect.tsx b/frontend/src/component/common/RoleSelect/RoleSelect.tsx index a919292fdac0..6f46ef9f4cd0 100644 --- a/frontend/src/component/common/RoleSelect/RoleSelect.tsx +++ b/frontend/src/component/common/RoleSelect/RoleSelect.tsx @@ -6,7 +6,6 @@ import { } from '@mui/material'; import type { IRole } from 'interfaces/role'; import { RoleDescription } from '../RoleDescription/RoleDescription'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; const StyledRoleOption = styled('div')(({ theme }) => ({ display: 'flex', @@ -61,12 +60,9 @@ export const RoleSelect = ({ )} {...rest} /> - ( - - )} - /> + {Boolean(value) && !hideDescription ? ( + + ) : null} ); }; diff --git a/frontend/src/component/common/Search/Search.tsx b/frontend/src/component/common/Search/Search.tsx index 87ad34a5c3e5..3e981fce8db8 100644 --- a/frontend/src/component/common/Search/Search.tsx +++ b/frontend/src/component/common/Search/Search.tsx @@ -11,7 +11,6 @@ import { } from '@mui/material'; import Close from '@mui/icons-material/Close'; import SearchIcon from '@mui/icons-material/Search'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { SearchSuggestions } from './SearchSuggestions/SearchSuggestions'; import type { IGetSearchContextOutput } from 'hooks/useSearch'; import { useKeyboardShortcut } from 'hooks/useKeyboardShortcut'; @@ -214,54 +213,44 @@ export const Search = ({ disabled={disabled} /> theme.spacing(4) }}> - - { - e.stopPropagation(); // prevent outside click from the lazily added element - onSearchChange(''); - searchInputRef.current?.focus(); - }} - sx={{ - padding: (theme) => theme.spacing(1), - }} - > - - - - } - /> + {value ? ( + + { + e.stopPropagation(); // prevent outside click from the lazily added element + onSearchChange(''); + searchInputRef.current?.focus(); + }} + sx={{ + padding: (theme) => theme.spacing(1), + }} + > + + + + ) : null} - - { - onSearchChange(suggestion); - searchInputRef.current?.focus(); - }} - savedQuery={savedQuery} - getSearchContext={getSearchContext!} - /> - } - elseShow={ - historyEnabled && ( - - - - ) - } - /> + {Boolean(hasFilters && getSearchContext) && showSuggestions ? ( + { + onSearchChange(suggestion); + searchInputRef.current?.focus(); + }} + savedQuery={savedQuery} + getSearchContext={getSearchContext!} + /> + ) : ( + historyEnabled && ( + + + + ) + )} ); }; diff --git a/frontend/src/component/common/Search/SearchSuggestions/SearchDescription/SearchDescription.tsx b/frontend/src/component/common/Search/SearchSuggestions/SearchDescription/SearchDescription.tsx index fd964760083f..f70c839fccfa 100644 --- a/frontend/src/component/common/Search/SearchSuggestions/SearchDescription/SearchDescription.tsx +++ b/frontend/src/component/common/Search/SearchSuggestions/SearchDescription/SearchDescription.tsx @@ -1,5 +1,4 @@ import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { getSearchTextGenerator, type IGetSearchContextOutput, @@ -33,39 +32,31 @@ export const SearchDescription: VFC = ({ return ( <> - - Searching for: -

    - {searchText}{' '} - {searchableColumnsString - ? ` in ${searchableColumnsString}` - : ''} + {searchText ? ( + <> + Searching for: +

    + {searchText}{' '} + {searchableColumnsString + ? ` in ${searchableColumnsString}` + : ''} +

    + + ) : null} + {searchFilters.length > 0 ? ( + <> + Filtering by: + {searchFilters.map((filter) => ( +

    + {filter.values.join(',')}{' '} + in {filter.header}. Options:{' '} + {[...new Set(filter.options)] + .slice(0, 10) + .join(', ')}

    - - } - /> - 0} - show={ - <> - Filtering by: - {searchFilters.map((filter) => ( -

    - - {filter.values.join(',')} - {' '} - in {filter.header}. Options:{' '} - {[...new Set(filter.options)] - .slice(0, 10) - .join(', ')} -

    - ))} - - } - /> + ))} + + ) : null} ); }; diff --git a/frontend/src/component/common/Search/SearchSuggestions/SearchHistory.tsx b/frontend/src/component/common/Search/SearchSuggestions/SearchHistory.tsx index d5653fd441e1..02b9869a86cb 100644 --- a/frontend/src/component/common/Search/SearchSuggestions/SearchHistory.tsx +++ b/frontend/src/component/common/Search/SearchSuggestions/SearchHistory.tsx @@ -1,6 +1,5 @@ import History from '@mui/icons-material/History'; import { Box, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { VFC } from 'react'; import { StyledCode } from './SearchInstructions/SearchInstructions'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; @@ -33,23 +32,18 @@ export const SearchHistory: VFC = ({ }); }; - return ( - - - - - {savedQuery} - - - - } - /> - ); + return savedQuery ? ( + <> + + + + {savedQuery} + + + + ) : null; }; diff --git a/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx b/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx index 03082dbf8d1e..fdf546615296 100644 --- a/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx +++ b/frontend/src/component/common/Search/SearchSuggestions/SearchInstructions/SearchInstructions.tsx @@ -1,5 +1,4 @@ import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { VFC } from 'react'; import { onEnter } from '../onEnter'; @@ -57,41 +56,33 @@ export const SearchInstructions: VFC = ({ {filters.map((filter) => ( {filter.header}:{' '} - 0} - show={ + {filter.options.length > 0 ? ( + + onClick(firstFilterOption(filter)), + )} + onClick={() => onClick(firstFilterOption(filter))} + > + {firstFilterOption(filter)} + + ) : null} + {filter.options.length > 1 ? ( + <> + {' or '} - onClick(firstFilterOption(filter)), + onClick(secondFilterOption(filter)), )} - onClick={() => - onClick(firstFilterOption(filter)) - } + onClick={() => { + onClick(secondFilterOption(filter)); + }} > - {firstFilterOption(filter)} + {secondFilterOption(filter)} - } - /> - 1} - show={ - <> - {' or '} - - onClick(secondFilterOption(filter)), - )} - onClick={() => { - onClick(secondFilterOption(filter)); - }} - > - {secondFilterOption(filter)} - - - } - /> + + ) : null} ))} diff --git a/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx b/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx index 9ac99b590840..64a564a4120e 100644 --- a/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx +++ b/frontend/src/component/common/Search/SearchSuggestions/SearchSuggestions.tsx @@ -1,7 +1,6 @@ import FilterList from '@mui/icons-material/FilterList'; import History from '@mui/icons-material/History'; import { Box, Divider, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { getColumnValues, getFilterableColumns, @@ -118,50 +117,36 @@ export const SearchSuggestions: VFC = ({ return ( - - - - - } - /> + {savedQuery ? ( + <> + + + + ) : null} - - } - elseShow={ - - } - /> + {searchContext.searchValue ? ( + + ) : ( + + )} - 0} - show='Combine filters and search: ' - /> + {filters.length > 0 ? 'Combine filters and search: ' : null} ; @@ -90,50 +89,42 @@ export const SegmentItem: VFC = ({ {segment.name} - - setIsOpen((value) => !value)} - sx={{ - my: 0, - ml: 'auto', - fontSize: (theme) => - theme.typography.body2.fontSize, - }} - > - {isOpen ? 'Close preview' : 'Preview'} - - } - /> + {headerContent ? headerContent : null} + {!isExpanded ? ( + + ) : null} - 0} - show={ - - } - elseShow={ - - This segment has no constraints. - - } - /> - } - /> + {constraintList ? ( + constraintList + ) : ( + 0} + show={ + + } + elseShow={ + + This segment has no constraints. + + } + /> + )} ); diff --git a/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx b/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx index 8d271268c5fb..745165862eeb 100644 --- a/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx +++ b/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx @@ -8,7 +8,6 @@ import { getFeatureStrategyIcon, } from 'utils/strategyNames'; import StringTruncator from 'component/common/StringTruncator/StringTruncator'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { PlaygroundStrategySchema } from 'openapi'; import { Badge } from '../Badge/Badge'; import { Link } from 'react-router-dom'; @@ -114,10 +113,9 @@ export const StrategyItemContainer: FC = ({ return ( - {orderNumber}} - /> + {orderNumber !== undefined ? ( + {orderNumber} + ) : null} = ({ draggable={Boolean(onDragStart)} disabled={Boolean(strategy?.disabled)} > - ( - - - - )} - /> + {onDragStart ? ( + + + + ) : null} theme.palette.action.disabled, @@ -157,35 +152,22 @@ export const StrategyItemContainer: FC = ({ maxLength={15} text={formatStrategyName(String(strategy.name))} /> - - {formatStrategyName( - String(strategy.title), - )} - - } - /> + {strategy.title ? ( + + {formatStrategyName(String(strategy.title))} + + ) : null} - - {description} - - } - /> + {description ? ( + {description} + ) : null} - ( - <> - Disabled - - )} - /> + {strategy?.disabled ? ( + <> + Disabled + + ) : null} { width: '100%', }} > - {text}} - elseShow={() => ( - {text} - )} - /> + {text === 'AND' ? ( + {text} + ) : ( + {text} + )} ); }; diff --git a/frontend/src/component/common/StringTruncator/StringTruncator.tsx b/frontend/src/component/common/StringTruncator/StringTruncator.tsx index 74205701f83a..f1752e605823 100644 --- a/frontend/src/component/common/StringTruncator/StringTruncator.tsx +++ b/frontend/src/component/common/StringTruncator/StringTruncator.tsx @@ -1,5 +1,4 @@ import { Tooltip } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface IStringTruncatorProps { text: string; @@ -15,30 +14,26 @@ const StringTruncator = ({ className, ...rest }: IStringTruncatorProps) => { - return ( - maxLength} - show={ - - - {text} - - - } - elseShow={{text}} - /> + return (text?.length ?? 0) > maxLength ? ( + + + {text} + + + ) : ( + {text} ); }; diff --git a/frontend/src/component/common/Table/FavoriteIconHeader/FavoriteIconHeader.tsx b/frontend/src/component/common/Table/FavoriteIconHeader/FavoriteIconHeader.tsx index 0e897989cb44..2499f31923b5 100644 --- a/frontend/src/component/common/Table/FavoriteIconHeader/FavoriteIconHeader.tsx +++ b/frontend/src/component/common/Table/FavoriteIconHeader/FavoriteIconHeader.tsx @@ -2,7 +2,6 @@ import { useState, type VFC } from 'react'; import { IconButton } from '@mui/material'; import StarIcon from '@mui/icons-material/Star'; import StarBorderIcon from '@mui/icons-material/StarBorder'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { TooltipResolver } from '../../TooltipResolver/TooltipResolver'; interface IFavoriteIconHeaderProps { @@ -40,11 +39,11 @@ export const FavoriteIconHeader: VFC = ({ onClick={onToggle} size='small' > - } - elseShow={} - /> + {internalState ? ( + + ) : ( + + )} ); diff --git a/frontend/src/component/common/Table/PaginatedTable/PaginatedTable.tsx b/frontend/src/component/common/Table/PaginatedTable/PaginatedTable.tsx index 34556e7de8fe..fa29058b098e 100644 --- a/frontend/src/component/common/Table/PaginatedTable/PaginatedTable.tsx +++ b/frontend/src/component/common/Table/PaginatedTable/PaginatedTable.tsx @@ -8,7 +8,6 @@ import { import { TableCell } from '../TableCell/TableCell'; import { CellSortable } from '../SortableTableHeader/CellSortable/CellSortable'; import { StickyPaginationBar } from 'component/common/Table/StickyPaginationBar/StickyPaginationBar'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { styled } from '@mui/material'; const HeaderCell = (header: Header) => { @@ -100,37 +99,32 @@ export const PaginatedTable = ({ - 0 && - (totalItems || 0) > 25 - } - show={ - - tableInstance.setPagination({ - pageIndex: pagination.pageIndex + 1, - pageSize: pagination.pageSize, - }) - } - fetchPrevPage={() => - tableInstance.setPagination({ - pageIndex: pagination.pageIndex - 1, - pageSize: pagination.pageSize, - }) - } - setPageLimit={(pageSize) => - tableInstance.setPagination({ - pageIndex: 0, - pageSize, - }) - } - /> - } - /> + {tableInstance.getRowModel().rows.length > 0 && + (totalItems || 0) > 25 ? ( + + tableInstance.setPagination({ + pageIndex: pagination.pageIndex + 1, + pageSize: pagination.pageSize, + }) + } + fetchPrevPage={() => + tableInstance.setPagination({ + pageIndex: pagination.pageIndex - 1, + pageSize: pagination.pageSize, + }) + } + setPageLimit={(pageSize) => + tableInstance.setPagination({ + pageIndex: 0, + pageSize, + }) + } + /> + ) : null} ); }; diff --git a/frontend/src/component/common/Table/PaginationBar/PaginationBar.tsx b/frontend/src/component/common/Table/PaginationBar/PaginationBar.tsx index b358bcdcf8a1..b641693fc8fd 100644 --- a/frontend/src/component/common/Table/PaginationBar/PaginationBar.tsx +++ b/frontend/src/component/common/Table/PaginationBar/PaginationBar.tsx @@ -1,6 +1,5 @@ import type React from 'react'; import { Box, Typography, Button, styled } from '@mui/material'; -import { ConditionallyRender } from '../../ConditionallyRender/ConditionallyRender'; import { ReactComponent as ArrowRight } from 'assets/icons/arrowRight.svg'; import { ReactComponent as ArrowLeft } from 'assets/icons/arrowLeft.svg'; @@ -82,33 +81,27 @@ export const PaginationBar: React.FC = ({ : ' '} - - - - } - /> + {hasPreviousPage ? ( + + + + ) : null} Page {pageIndex + 1} of {pageCount} - - - - } - /> + {hasNextPage ? ( + + + + ) : null} Show rows diff --git a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx index 44a83cae7550..425305ad0531 100644 --- a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx +++ b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/CellSortable.tsx @@ -9,7 +9,6 @@ import { useState, } from 'react'; import { Tooltip } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext'; import { StyledButton, @@ -114,42 +113,40 @@ export const CellSortable: FC = ({ isFlexGrow={isFlexGrow} isSortable={isSortable} > - - + + - - - {children} - - - - - - {children} - - - - - - } - elseShow={
    {children}
    } - /> + + {children} + + + + + + {children} + + + +
    + + ) : ( +
    {children}
    + )} ); }; diff --git a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/SortArrow/SortArrow.tsx b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/SortArrow/SortArrow.tsx index cacd9cb67f2d..5469e284188c 100644 --- a/frontend/src/component/common/Table/SortableTableHeader/CellSortable/SortArrow/SortArrow.tsx +++ b/frontend/src/component/common/Table/SortableTableHeader/CellSortable/SortArrow/SortArrow.tsx @@ -1,9 +1,6 @@ import type { VFC } from 'react'; import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; import KeyboardArrowUp from '@mui/icons-material/KeyboardArrowUp'; -import UnfoldMoreOutlined from '@mui/icons-material/UnfoldMoreOutlined'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import classnames from 'classnames'; import type { Theme } from '@mui/material'; interface ISortArrowProps { @@ -23,40 +20,35 @@ export const SortArrow: VFC = ({ isSorted: sorted, isDesc: desc = false, className, -}) => ( - ({ - ...iconStyle(theme), - })} - className={className} - fontSize='inherit' - /> - } - elseShow={ - ({ - ...iconStyle(theme), - })} - className={className} - fontSize='inherit' - /> - } - /> - } - elseShow={ - ({ - ...iconStyle(theme), - })} - className={classnames(className, 'hover-only')} - fontSize='inherit' - /> - } - /> -); +}) => + sorted ? ( + ({ + ...iconStyle(theme), + })} + className={className} + fontSize='inherit' + /> + } + elseShow={ + ({ + ...iconStyle(theme), + })} + className={className} + fontSize='inherit' + /> + } + /> + ) : ( + ({ + ...iconStyle(theme), + })} + className={className} + fontSize='inherit' + /> + ); diff --git a/frontend/src/component/common/Table/cells/FavoriteIconCell/FavoriteIconCell.tsx b/frontend/src/component/common/Table/cells/FavoriteIconCell/FavoriteIconCell.tsx index 17344924ff95..38c21eab99eb 100644 --- a/frontend/src/component/common/Table/cells/FavoriteIconCell/FavoriteIconCell.tsx +++ b/frontend/src/component/common/Table/cells/FavoriteIconCell/FavoriteIconCell.tsx @@ -2,7 +2,6 @@ import type { VFC } from 'react'; import { Box, IconButton, styled } from '@mui/material'; import StarIcon from '@mui/icons-material/Star'; import StarBorderIcon from '@mui/icons-material/StarBorder'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledCell = styled(Box)(({ theme }) => ({ paddingLeft: theme.spacing(2), @@ -37,22 +36,18 @@ export const FavoriteIconCell: VFC = ({ onClick, }) => ( - - - - } - elseShow={ - - - - } - /> + {value ? ( + + + + ) : ( + + + + )} ); diff --git a/frontend/src/component/common/Table/cells/FeatureOverviewCell/FeatureOverviewCell.tsx b/frontend/src/component/common/Table/cells/FeatureOverviewCell/FeatureOverviewCell.tsx index a8ab7f17165d..2e402244f70b 100644 --- a/frontend/src/component/common/Table/cells/FeatureOverviewCell/FeatureOverviewCell.tsx +++ b/frontend/src/component/common/Table/cells/FeatureOverviewCell/FeatureOverviewCell.tsx @@ -9,7 +9,6 @@ import { StyledDescription, StyledTitle } from '../LinkCell/LinkCell.styles'; import { Link } from 'react-router-dom'; import { Badge } from '../../../Badge/Badge'; import { HtmlTooltip } from '../../../HtmlTooltip/HtmlTooltip'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; interface IFeatureNameCellProps { @@ -52,28 +51,20 @@ const CappedDescription: FC<{ text: string; searchQuery: string }> = ({ text, searchQuery, }) => { - return ( - 40)} - show={ - {text} - } - placement='bottom-start' - arrow - > - - {text} - - - } - elseShow={ - - {text} - - } - /> + return text && text.length > 40 ? ( + {text}} + placement='bottom-start' + arrow + > + + {text} + + + ) : ( + + {text} + ); }; @@ -81,12 +72,10 @@ const CappedTag: FC<{ tag: string; children: ReactElement }> = ({ tag, children, }) => { - return ( - 30} - show={{children}} - elseShow={children} - /> + return tag.length > 30 ? ( + {children} + ) : ( + children ); }; @@ -184,10 +173,9 @@ const Tags: FC<{ onClick(tag3)}>{tag3} )} - 0} - show={} - /> + {restTags.length > 0 ? ( + + ) : null} ); }; @@ -280,31 +268,28 @@ export const PrimaryFeatureInfo: FC<{ feature={feature} searchQuery={searchQuery} /> - + {dependencyType ? ( + + } + enterDelay={delay} + enterNextDelay={delay} + > + - - {dependencyType} - - - } - /> + {dependencyType} + + + ) : null} ); }; @@ -313,21 +298,11 @@ const SecondaryFeatureInfo: FC<{ description: string; searchQuery: string; }> = ({ description, searchQuery }) => { - return ( - ({ display: 'flex', gap: theme.spacing(1) })} - > - -
    - } - /> - ); + return description ? ( + ({ display: 'flex', gap: theme.spacing(1) })}> + + + ) : null; }; export const FeatureOverviewCell = diff --git a/frontend/src/component/common/Table/cells/FeatureSeenCell/FeatureSeenCell.tsx b/frontend/src/component/common/Table/cells/FeatureSeenCell/FeatureSeenCell.tsx index 68f866b788c4..99d697d7fde1 100644 --- a/frontend/src/component/common/Table/cells/FeatureSeenCell/FeatureSeenCell.tsx +++ b/frontend/src/component/common/Table/cells/FeatureSeenCell/FeatureSeenCell.tsx @@ -2,7 +2,6 @@ import type React from 'react'; import type { FC, VFC } from 'react'; import TimeAgo from 'react-timeago'; import { styled, Tooltip, useTheme } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; function shortenUnitName(unit?: string): string { switch (unit) { @@ -93,38 +92,28 @@ const Wrapper: FC<{ export const FeatureSeenCell: VFC = ({ value: lastSeenAt, }) => { - return ( - { - return ( - - {value} - {shortenUnitName(unit)} - - ); - }} - /> - } - elseShow={ - - – - - } + return lastSeenAt ? ( + { + return ( + + {value} + {shortenUnitName(unit)} + + ); + }} /> + ) : ( + + – + ); }; diff --git a/frontend/src/component/common/Table/cells/FeatureSeenCell/LastSeenTooltip.tsx b/frontend/src/component/common/Table/cells/FeatureSeenCell/LastSeenTooltip.tsx index 81e941a1654b..4e5f7006b10d 100644 --- a/frontend/src/component/common/Table/cells/FeatureSeenCell/LastSeenTooltip.tsx +++ b/frontend/src/component/common/Table/cells/FeatureSeenCell/LastSeenTooltip.tsx @@ -1,7 +1,6 @@ -import { styled, type SxProps, type Theme, Typography } from '@mui/material'; +import { styled, type SxProps, type Theme } from '@mui/material'; import TimeAgo from 'react-timeago'; import type { ILastSeenEnvironments } from 'interfaces/featureToggle'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useLastSeenColors } from 'component/feature/FeatureView/FeatureEnvironmentSeen/useLastSeenColors'; import { LastSeenProgress } from './LastSeenProgress/LastSeenProgress'; @@ -83,84 +82,48 @@ export const LastSeenTooltip = ({ Last usage reported - - {environments?.map(({ name, lastSeenAt, yes, no }) => ( - - - {name} - - - { - const [, textColor] = - getColor(unit); - return ( - - {`${value} ${unit}${ - value !== 1 - ? 's' - : '' - } ${suffix}`} - - ); - }} - /> - } - elseShow={ - - no usage - - } + {Boolean(environments) && Boolean(environmentsHaveLastSeen) ? ( + + {environments?.map(({ name, lastSeenAt, yes, no }) => ( + + + {name} + + + {lastSeenAt ? ( + { + const [, textColor] = + getColor(unit); + return ( + + {`${value} ${unit}${ + value !== 1 ? 's' : '' + } ${suffix}`} + + ); + }} /> - - - - ))} - - } - elseShow={ - { - return ( - - {`Reported ${value} ${unit}${ - value !== 1 ? 's' : '' - } ${suffix}`} - - ); - }} - /> - } - /> + ) : ( + + no usage + + )} + + + + ))} + + ) : ( + no usage + )} Usage is reported from connected applications through metrics diff --git a/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx b/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx index 3aa5c699d242..48bb019559df 100644 --- a/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx +++ b/frontend/src/component/common/Table/cells/HighlightCell/HighlightCell.tsx @@ -3,7 +3,6 @@ import type { FC } from 'react'; import { Highlighter } from 'component/common/Highlighter/Highlighter'; import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { Box, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; interface IHighlightCellProps { @@ -49,27 +48,18 @@ export const HighlightCell: FC = ({ }) => { const { searchQuery } = useSearchHighlightContext(); - const renderSubtitle = ( - 40 || subtitleTooltip), - )} - show={ - - - - {subtitle} - - - - } - elseShow={ + const renderSubtitle = + subtitle && (subtitle.length > 40 || subtitleTooltip) ? ( + {subtitle} - } - /> - ); + + ) : ( + + {subtitle} + + ); return ( @@ -83,10 +73,7 @@ export const HighlightCell: FC = ({ {value} {afterTitle} - + {subtitle ? renderSubtitle : null} ); }; diff --git a/frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx b/frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx index 7ec25a43900e..caf595a54199 100644 --- a/frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx +++ b/frontend/src/component/common/Table/cells/LinkCell/LinkCell.tsx @@ -1,6 +1,5 @@ import type React from 'react'; import { Link as RouterLink } from 'react-router-dom'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Highlighter } from 'component/common/Highlighter/Highlighter'; import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; @@ -29,25 +28,18 @@ export const LinkCell: React.FC = ({ }) => { const { searchQuery } = useSearchHighlightContext(); - const renderSubtitle = ( - 40)} - show={ - - - - {subtitle} - - - - } - elseShow={ + const renderSubtitle = + subtitle && subtitle.length > 40 ? ( + {subtitle} - } - /> - ); + + ) : ( + + {subtitle} + + ); const content = ( @@ -61,10 +53,7 @@ export const LinkCell: React.FC = ({ {title} {children} - + {subtitle ? renderSubtitle : null} ); diff --git a/frontend/src/component/common/ThemeMode/ThemeMode.tsx b/frontend/src/component/common/ThemeMode/ThemeMode.tsx index 67a6d3e582c5..80c20afef422 100644 --- a/frontend/src/component/common/ThemeMode/ThemeMode.tsx +++ b/frontend/src/component/common/ThemeMode/ThemeMode.tsx @@ -1,6 +1,5 @@ import UIContext from 'contexts/UIContext'; import { useContext } from 'react'; -import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; interface IThemeModeProps { darkmode: JSX.Element; @@ -10,11 +9,5 @@ interface IThemeModeProps { export const ThemeMode = ({ darkmode, lightmode }: IThemeModeProps) => { const { themeMode } = useContext(UIContext); - return ( - - ); + return themeMode === 'dark' ? darkmode : lightmode; }; diff --git a/frontend/src/component/common/ToastRenderer/Toast/Toast.tsx b/frontend/src/component/common/ToastRenderer/Toast/Toast.tsx index 52b06f172615..4887249c3b53 100644 --- a/frontend/src/component/common/ToastRenderer/Toast/Toast.tsx +++ b/frontend/src/component/common/ToastRenderer/Toast/Toast.tsx @@ -4,7 +4,6 @@ import { useContext } from 'react'; import { IconButton, Tooltip } from '@mui/material'; import CheckMarkBadge from 'component/common/CheckmarkBadge/CheckMarkBadge'; import UIContext from 'contexts/UIContext'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import Close from '@mui/icons-material/Close'; import type { IToast } from 'interfaces/toast'; import { TOAST_TEXT } from 'utils/testIds'; @@ -71,12 +70,9 @@ const Toast = ({ title, text, type, confetti }: IToast) => {

    {title}

    - {text}

    - } - /> + {text ? ( +

    {text}

    + ) : null}
    diff --git a/frontend/src/component/common/UserAvatar/UserAvatar.tsx b/frontend/src/component/common/UserAvatar/UserAvatar.tsx index 6c329c2ddd1a..fe23da1845ea 100644 --- a/frontend/src/component/common/UserAvatar/UserAvatar.tsx +++ b/frontend/src/component/common/UserAvatar/UserAvatar.tsx @@ -7,7 +7,6 @@ import { } from '@mui/material'; import type { IUser } from 'interfaces/user'; import type { FC } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { HtmlTooltip } from '../HtmlTooltip/HtmlTooltip'; const StyledAvatar = styled(Avatar)(({ theme }) => ({ width: theme.spacing(3.5), @@ -90,11 +89,7 @@ export const UserAvatar: FC = ({ alt={user?.name || user?.email || user?.username || 'Gravatar'} src={src || user?.imageUrl} > - + {fallback ? fallback : children} ); diff --git a/frontend/src/component/context/ContectFormChip/ContextFormChip.tsx b/frontend/src/component/context/ContectFormChip/ContextFormChip.tsx index 4bed3acbe784..5198f19bf327 100644 --- a/frontend/src/component/context/ContectFormChip/ContextFormChip.tsx +++ b/frontend/src/component/context/ContectFormChip/ContextFormChip.tsx @@ -1,5 +1,4 @@ import Cancel from '@mui/icons-material/Cancel'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { styled } from '@mui/material'; interface IContextFormChipProps { @@ -54,12 +53,9 @@ export const ContextFormChip = ({
    {label} - ( - {description} - )} - /> + {description ? ( + {description} + ) : null}
    diff --git a/frontend/src/component/context/ContextList/AddContextButton.tsx b/frontend/src/component/context/ContextList/AddContextButton.tsx index f8a548559f4d..65887491d890 100644 --- a/frontend/src/component/context/ContextList/AddContextButton.tsx +++ b/frontend/src/component/context/ContextList/AddContextButton.tsx @@ -2,7 +2,6 @@ import type { VFC } from 'react'; import { useNavigate } from 'react-router-dom'; import { useMediaQuery } from '@mui/material'; import Add from '@mui/icons-material/Add'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { CREATE_CONTEXT_FIELD } from 'component/providers/AccessProvider/permissions'; import PermissionButton from 'component/common/PermissionButton/PermissionButton'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; @@ -13,29 +12,23 @@ export const AddContextButton: VFC = () => { const smallScreen = useMediaQuery('(max-width:700px)'); const navigate = useNavigate(); - return ( - navigate('/context/create')} - size='large' - tooltipProps={{ title: 'Add context type' }} - > - - - } - elseShow={ - navigate('/context/create')} - permission={CREATE_CONTEXT_FIELD} - color='primary' - variant='contained' - > - New context field - - } - /> + return smallScreen ? ( + navigate('/context/create')} + size='large' + tooltipProps={{ title: 'Add context type' }} + > + + + ) : ( + navigate('/context/create')} + permission={CREATE_CONTEXT_FIELD} + color='primary' + variant='contained' + > + New context field + ); }; diff --git a/frontend/src/component/context/ContextList/ContextList/ContextList.tsx b/frontend/src/component/context/ContextList/ContextList/ContextList.tsx index e2e5a7cf5a98..014f8e1a1474 100644 --- a/frontend/src/component/context/ContextList/ContextList/ContextList.tsx +++ b/frontend/src/component/context/ContextList/ContextList/ContextList.tsx @@ -10,7 +10,6 @@ import { } from 'component/common/Table'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue as ConfirmDialogue } from 'component/common/Dialogue/Dialogue'; import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext'; import useContextsApi from 'hooks/api/actions/useContextsApi/useContextsApi'; @@ -212,27 +211,27 @@ const ContextList: VFC = () => { - 0} - show={ - - No contexts found matching “ - {globalFilter} - ” - - } - elseShow={ - - No contexts available. Get started by adding - one. - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No contexts found matching “ + {globalFilter} + ” + + } + elseShow={ + + No contexts available. Get started by adding one. + + } + /> + ) : ( + + No contexts available. Get started by adding one. + + )} { open={plansOpen} onClose={() => setPlansOpen(false)} /> - - { - setWelcomeOpen(false); - - setExpanded(false); - - trackEvent('demo-close', { - props: { - topic: 'welcome', - step: 'welcome', - }, - }); - }} - onStart={() => { - setWelcomeOpen(false); - - onStart(); - - trackEvent('demo-start'); - }} - /> - { - setFinishOpen(false); - setPlansOpen(true); - }} - onRestart={() => { - setFinishOpen(false); - onStart(); - - trackEvent('demo-restart'); - }} - /> - { - setTopic(topic); - setStep(0); - - setWelcomeOpen(false); - setPlansOpen(false); - - trackEvent('demo-start-topic', { - props: { - topic: TOPICS[topic].title, - }, - }); - }} - topics={TOPICS} - onWelcome={() => { - closeGuide(); - setPlansOpen(false); - - setWelcomeOpen(true); - - trackEvent('demo-view-demo-link'); - }} - /> - - - } - /> + {!isSmallScreen ? ( + <> + { + setWelcomeOpen(false); + + setExpanded(false); + + trackEvent('demo-close', { + props: { + topic: 'welcome', + step: 'welcome', + }, + }); + }} + onStart={() => { + setWelcomeOpen(false); + + onStart(); + + trackEvent('demo-start'); + }} + /> + { + setFinishOpen(false); + setPlansOpen(true); + }} + onRestart={() => { + setFinishOpen(false); + onStart(); + + trackEvent('demo-restart'); + }} + /> + { + setTopic(topic); + setStep(0); + + setWelcomeOpen(false); + setPlansOpen(false); + + trackEvent('demo-start-topic', { + props: { + topic: TOPICS[topic].title, + }, + }); + }} + topics={TOPICS} + onWelcome={() => { + closeGuide(); + setPlansOpen(false); + + setWelcomeOpen(true); + + trackEvent('demo-view-demo-link'); + }} + /> + + + ) : null} ); }; diff --git a/frontend/src/component/demo/DemoDialog/DemoDialogFinish/DemoDialogFinish.tsx b/frontend/src/component/demo/DemoDialog/DemoDialogFinish/DemoDialogFinish.tsx index 97d2a3fe9e90..83334c0f80bd 100644 --- a/frontend/src/component/demo/DemoDialog/DemoDialogFinish/DemoDialogFinish.tsx +++ b/frontend/src/component/demo/DemoDialog/DemoDialogFinish/DemoDialogFinish.tsx @@ -1,7 +1,6 @@ import { Button, Typography, styled } from '@mui/material'; import { DemoDialog } from '../DemoDialog'; import Confetti from 'react-confetti'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledActions = styled('div')(({ theme }) => ({ display: 'grid', @@ -26,18 +25,15 @@ export const DemoDialogFinish = ({ onRestart, }: IDemoDialogFinishProps) => ( <> - - } - /> + {open ? ( + + ) : null} You finished the demo diff --git a/frontend/src/component/demo/DemoSteps/DemoStepTooltip/DemoStepTooltip.tsx b/frontend/src/component/demo/DemoSteps/DemoStepTooltip/DemoStepTooltip.tsx index 114f135467b6..5f263a879926 100644 --- a/frontend/src/component/demo/DemoSteps/DemoStepTooltip/DemoStepTooltip.tsx +++ b/frontend/src/component/demo/DemoSteps/DemoStepTooltip/DemoStepTooltip.tsx @@ -6,7 +6,6 @@ import { alpha, styled, } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { ITutorialTopic, ITutorialTopicStep, @@ -112,45 +111,37 @@ export const DemoStepTooltip = ({ - - {topics[topic].title} - - } - /> + {step.title ? ( + step.title + ) : ( + + {topics[topic].title} + + )} {step.content}
    - 0 || stepIndex > 0} - show={ - - } - /> + {topic > 0 || stepIndex > 0 ? ( + + ) : null}
    - onNext(stepIndex)} - variant='contained' - sx={{ alignSelf: 'flex-end' }} - data-testid='DEMO_NEXT_BUTTON' - > - {nextLabel} - - } - /> + {step.nextButton ? ( + + ) : null}
    @@ -164,45 +155,34 @@ export const DemoStepTooltip = ({ - - {topics[topic].title} - - } - /> + {step.title ? ( + step.title + ) : ( + + {topics[topic].title} + + )} {step.content}
    - 0 || stepIndex > 0} - show={ - - } - /> + {topic > 0 || stepIndex > 0 ? ( + + ) : null}
    - onNext(stepIndex)} - variant='contained' - sx={{ alignSelf: 'flex-end' }} - data-testid='DEMO_NEXT_BUTTON' - > - {nextLabel} - - } - /> + {step.nextButton ? ( + + ) : null}
    diff --git a/frontend/src/component/demo/DemoTopics/DemoTopics.tsx b/frontend/src/component/demo/DemoTopics/DemoTopics.tsx index 7f50086b104d..d840c63dc33d 100644 --- a/frontend/src/component/demo/DemoTopics/DemoTopics.tsx +++ b/frontend/src/component/demo/DemoTopics/DemoTopics.tsx @@ -13,7 +13,6 @@ import CheckCircle from '@mui/icons-material/CheckCircle'; import CircleOutlined from '@mui/icons-material/CircleOutlined'; import ExpandMore from '@mui/icons-material/ExpandMore'; import type { ITutorialTopic } from '../demo-topics'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ReactComponent as StarsIcon } from 'assets/img/stars.svg'; const StyledAccordion = styled(Accordion)(({ theme }) => ({ @@ -209,11 +208,11 @@ export const DemoTopics = ({ selected={selected} completed={completed} > - } - elseShow={} - /> + {completed ? ( + + ) : ( + + )} {topic.title} diff --git a/frontend/src/component/environments/CreateEnvironment/CreateEnvironment.tsx b/frontend/src/component/environments/CreateEnvironment/CreateEnvironment.tsx index 99b93248cfcf..9db45c80b76c 100644 --- a/frontend/src/component/environments/CreateEnvironment/CreateEnvironment.tsx +++ b/frontend/src/component/environments/CreateEnvironment/CreateEnvironment.tsx @@ -10,7 +10,6 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useToast from 'hooks/useToast'; import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments'; import usePermissions from 'hooks/api/getters/usePermissions/usePermissions'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import { ADMIN } from 'component/providers/AccessProvider/permissions'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; @@ -72,83 +71,72 @@ const CreateEnvironment = () => { navigate(GO_BACK); }; - return ( - - - } - /> - } - > - + - - - } - elseShow={ - <> - } - > - -

    - Currently Unleash does not support more than{' '} - {environmentLimit} environments. If you need - more please reach out. -

    -
    -
    - -
    - - } - /> + ) : null + } + > + +
    + + ) : ( + <> + }> + +

    + Currently Unleash does not support more than{' '} + {environmentLimit} environments. If you need more please + reach out. +

    +
    +
    + +
    + ); }; diff --git a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentActionCellPopover/EnvironmentActionCellPopover.tsx b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentActionCellPopover/EnvironmentActionCellPopover.tsx index 77b645b1e21a..1560d9d5e041 100644 --- a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentActionCellPopover/EnvironmentActionCellPopover.tsx +++ b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentActionCellPopover/EnvironmentActionCellPopover.tsx @@ -23,7 +23,6 @@ import Edit from '@mui/icons-material/Edit'; import CopyIcon from '@mui/icons-material/AddToPhotos'; import VisibilityOffOutlined from '@mui/icons-material/VisibilityOffOutlined'; import VisibilityOutlined from '@mui/icons-material/VisibilityOutlined'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledMenuList = styled(MenuList)(({ theme }) => ({ padding: theme.spacing(1), @@ -143,11 +142,11 @@ export const EnvironmentActionCellPopover = ({ disabled={!hasAccess || environment.protected} > - } - elseShow={} - /> + {environment.enabled ? ( + + ) : ( + + )} diff --git a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentCloneModal.tsx b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentCloneModal.tsx index ffca6514a1b1..d1c7e8e52456 100644 --- a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentCloneModal.tsx +++ b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentCloneModal.tsx @@ -30,7 +30,6 @@ import useApiTokensApi, { type IApiTokenCreate, } from 'hooks/api/actions/useApiTokensApi/useApiTokensApi'; import type { IApiToken } from 'hooks/api/getters/useApiTokens/useApiTokens'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledForm = styled('form')(() => ({ display: 'flex', @@ -339,31 +338,24 @@ export const EnvironmentCloneModal = ({ environment, so you can get started right away. - - - Which projects do you want this - token to give access to? - - - clearError( - ErrorField.PROJECTS, - ) - } - /> - - } - /> + {apiTokenGeneration === + APITokenGeneration.NOW ? ( + <> + + Which projects do you want this + token to give access to? + + + clearError(ErrorField.PROJECTS) + } + /> + + ) : null} diff --git a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentProjectSelect/EnvironmentProjectSelect.tsx b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentProjectSelect/EnvironmentProjectSelect.tsx index d3280263850e..d78cf33d1037 100644 --- a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentProjectSelect/EnvironmentProjectSelect.tsx +++ b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentCloneModal/EnvironmentProjectSelect/EnvironmentProjectSelect.tsx @@ -10,7 +10,6 @@ import CheckBoxIcon from '@mui/icons-material/CheckBox'; import { caseInsensitiveSearch } from 'utils/search'; import useProjects from 'hooks/api/getters/useProjects/useProjects'; import { Fragment } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { SelectAllButton } from 'component/admin/apiToken/ApiTokenForm/ProjectSelector/SelectProjectInput/SelectAllButton/SelectAllButton'; const StyledOption = styled('div')(({ theme }) => ({ @@ -102,15 +101,12 @@ export const EnvironmentProjectSelect = ({ const renderGroup = ({ key, children }: AutocompleteRenderGroupParams) => ( - 2} - show={ - - } - /> + {projectOptions.length > 2 ? ( + + ) : null} {children} ); diff --git a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentDeprecateToggleDialog/EnvironmentDeprecateToggleDialog.tsx b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentDeprecateToggleDialog/EnvironmentDeprecateToggleDialog.tsx index a57c469949be..21deee8a0c95 100644 --- a/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentDeprecateToggleDialog/EnvironmentDeprecateToggleDialog.tsx +++ b/frontend/src/component/environments/EnvironmentTable/EnvironmentActionCell/EnvironmentDeprecateToggleDialog/EnvironmentDeprecateToggleDialog.tsx @@ -1,7 +1,6 @@ import { Alert } from '@mui/material'; import type React from 'react'; import type { IEnvironment } from 'interfaces/environments'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { EnvironmentTableSingle } from 'component/environments/EnvironmentTable/EnvironmentTableSingle'; @@ -32,27 +31,21 @@ export const EnvironmentDeprecateToggleDialog = ({ setOpen(false); }} > - - Deprecating an environment will mark it as deprecated. - Deprecated environments are set as not visible by - default for new projects. Project owners are still able - to override this setting in the project. This - environment will still be visible in any current - projects. - - } - elseShow={ - - Undeprecating an environment will no longer mark it as - deprecated. An undeprecated environment will be set as - visible by default for new projects. - - } - /> - + {enabled ? ( + + Deprecating an environment will mark it as deprecated. + Deprecated environments are set as not visible by default + for new projects. Project owners are still able to override + this setting in the project. This environment will still be + visible in any current projects. + + ) : ( + + Undeprecating an environment will no longer mark it as + deprecated. An undeprecated environment will be set as + visible by default for new projects. + + )} ); diff --git a/frontend/src/component/environments/EnvironmentTable/EnvironmentNameCell/EnvironmentNameCell.tsx b/frontend/src/component/environments/EnvironmentTable/EnvironmentNameCell/EnvironmentNameCell.tsx index f93712e0f45a..1398617fdf90 100644 --- a/frontend/src/component/environments/EnvironmentTable/EnvironmentNameCell/EnvironmentNameCell.tsx +++ b/frontend/src/component/environments/EnvironmentTable/EnvironmentNameCell/EnvironmentNameCell.tsx @@ -1,6 +1,5 @@ import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; import type { IEnvironment } from 'interfaces/environments'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Badge } from 'component/common/Badge/Badge'; import { Highlighter } from 'component/common/Highlighter/Highlighter'; import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; @@ -38,34 +37,30 @@ export const EnvironmentNameCell = ({ })} > {environment.name} - Predefined} - /> - - - Deprecated environment - - - This environment is not auto-enabled for new - projects. The project owner will need to - manually enable it in the project. - - - } - describeChild - arrow - > - Deprecated - - } - /> + {environment.protected ? ( + Predefined + ) : null} + {!environment.enabled ? ( + + + Deprecated environment + + + This environment is not auto-enabled for new + projects. The project owner will need to + manually enable it in the project. + + + } + describeChild + arrow + > + Deprecated + + ) : null} ); }; diff --git a/frontend/src/component/environments/EnvironmentTable/EnvironmentTable.tsx b/frontend/src/component/environments/EnvironmentTable/EnvironmentTable.tsx index e2cb880a9a93..a00a31630c81 100644 --- a/frontend/src/component/environments/EnvironmentTable/EnvironmentTable.tsx +++ b/frontend/src/component/environments/EnvironmentTable/EnvironmentTable.tsx @@ -17,7 +17,6 @@ import useEnvironmentApi, { createSortOrderPayload, } from 'hooks/api/actions/useEnvironmentApi/useEnvironmentApi'; import { formatUnknownError } from 'utils/formatUnknownError'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { EnvironmentRow } from './EnvironmentRow/EnvironmentRow'; import { EnvironmentNameCell } from './EnvironmentNameCell/EnvironmentNameCell'; import { EnvironmentActionCell } from './EnvironmentActionCell/EnvironmentActionCell'; @@ -123,27 +122,28 @@ export const EnvironmentTable = () => { - 0} - show={ - - No environments found matching “ - {globalFilter} - ” - - } - elseShow={ - - No environments available. Get started by adding - one. - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No environments found matching “ + {globalFilter} + ” + + } + elseShow={ + + No environments available. Get started by adding + one. + + } + /> + ) : ( + + No environments available. Get started by adding one. + + )} ); }; diff --git a/frontend/src/component/environments/EnvironmentTable/EnvironmentTableSingle.tsx b/frontend/src/component/environments/EnvironmentTable/EnvironmentTableSingle.tsx index 1db478e66542..b7de0a0c7fec 100644 --- a/frontend/src/component/environments/EnvironmentTable/EnvironmentTableSingle.tsx +++ b/frontend/src/component/environments/EnvironmentTable/EnvironmentTableSingle.tsx @@ -4,7 +4,6 @@ import { useTable } from 'react-table'; import { SortableTableHeader, Table, TableCell } from 'component/common/Table'; import { EnvironmentIconCell } from 'component/environments/EnvironmentTable/EnvironmentIconCell/EnvironmentIconCell'; import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useMemo } from 'react'; const StyledTable = styled(Table)(({ theme }) => ({ @@ -62,21 +61,18 @@ export const EnvironmentTableSingle = ({ }) => ( {value} - 0, - )} - > - {original.enabledToggleCount === 1 - ? '1 toggle enabled' - : `${original.enabledToggleCount} toggles enabled`} - - } - /> + {warnEnabledToggles ? ( + 0, + )} + > + {original.enabledToggleCount === 1 + ? '1 toggle enabled' + : `${original.enabledToggleCount} toggles enabled`} + + ) : null} ), }, diff --git a/frontend/src/component/events/EventCard/EventCard.tsx b/frontend/src/component/events/EventCard/EventCard.tsx index 60d6cf0be3b4..dccac6a9ae37 100644 --- a/frontend/src/component/events/EventCard/EventCard.tsx +++ b/frontend/src/component/events/EventCard/EventCard.tsx @@ -1,5 +1,4 @@ import EventDiff from 'component/events/EventDiff/EventDiff'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useLocationSettings } from 'hooks/useLocationSettings'; import { formatDateYMDHMS } from 'utils/formatDate'; import { Link } from 'react-router-dom'; @@ -89,59 +88,43 @@ const EventCard = ({ entry }: IEventCardProps) => {
    {entry.type}
    Changed by:
    {entry.createdBy}
    - - - Project: - -
    - - {entry.project} - -
    - - } - /> - - - Feature: - -
    - - {entry.featureName} - -
    - - } - /> - - - Environment: - -
    {entry.environment}
    - - } - /> + {entry.project ? ( + <> + Project: +
    + + {entry.project} + +
    + + ) : null} + {entry.featureName ? ( + <> + Feature: +
    + + {entry.featureName} + +
    + + ) : null} + {entry.environment ? ( + <> + + Environment: + +
    {entry.environment}
    + + ) : null} - - Changes: - - - } - /> + {entry.data || entry.preData ? ( + + Changes: + + + ) : null} ); }; diff --git a/frontend/src/component/events/EventLog/EventLog.tsx b/frontend/src/component/events/EventLog/EventLog.tsx index 7cdffb402d32..ef735ad5880a 100644 --- a/frontend/src/component/events/EventLog/EventLog.tsx +++ b/frontend/src/component/events/EventLog/EventLog.tsx @@ -8,7 +8,6 @@ import { useState, useEffect } from 'react'; import { Search } from 'component/common/Search/Search'; import theme from 'themes/theme'; import { useLegacyEventSearch } from 'hooks/api/getters/useEventSearch/useLegacyEventSearch'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useOnVisible } from 'hooks/useOnVisible'; import { styled } from '@mui/system'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; @@ -99,14 +98,13 @@ const NewEventLog = ({ title, project, feature }: IEventLogProps) => { } else { return ( - {events.map((entry) => ( - } - elseShow={() => } - /> - ))} + {events.map((entry) => + eventSettings.showData ? ( + + ) : ( + + ), + )} ); } @@ -137,19 +135,16 @@ const NewEventLog = ({ title, project, feature }: IEventLogProps) => { /> {resultComponent()} - 25} - show={ - - } - /> + {total > 25 ? ( + + ) : null} ); }; @@ -209,25 +204,20 @@ export const LegacyEventLog = ({ title, project, feature }: IEventLogProps) => { } > - No events found.

    } - /> - 0)} - show={ - - {cache?.map((entry) => ( - } - elseShow={() => } - /> - ))} - - } - /> + {cache && cache.length === 0 ?

    No events found.

    : null} + {cache && cache.length > 0 ? ( + + {cache?.map((entry) => + eventSettings.showData ? ( + + ) : ( + + ), + )} + + ) : ( + + )}
    ); diff --git a/frontend/src/component/feature/CopyFeature/CopyFeature.tsx b/frontend/src/component/feature/CopyFeature/CopyFeature.tsx index caf6bddebdf5..96f1c3063774 100644 --- a/frontend/src/component/feature/CopyFeature/CopyFeature.tsx +++ b/frontend/src/component/feature/CopyFeature/CopyFeature.tsx @@ -16,7 +16,6 @@ import { import FileCopy from '@mui/icons-material/FileCopy'; import { formatUnknownError } from 'utils/formatUnknownError'; import { trim } from 'component/common/util'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { getTogglePath } from 'utils/routePathHelpers'; import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; @@ -132,20 +131,14 @@ export const CopyFeatureToggle = () => { Copy {featureId} - {apiError}} - /> - - Copy functionality is disabled for this project because - change request is enabled for at least one environment - in this project. - - } - /> + {apiError ? {apiError} : null} + {isChangeRequestConfiguredInAnyEnv() ? ( + + Copy functionality is disabled for this project because + change request is enabled for at least one environment in + this project. + + ) : null} You are about to create a new feature flag by cloning the @@ -157,14 +150,9 @@ export const CopyFeatureToggle = () => { you can proceed. - - } - /> + {displayFeatureNamingInfo ? ( + + ) : null} { documentationLinkLabel='Feature flag types documentation' formatApiCode={formatApiCode} > - - Feature flag project limit reached. To - be able to create more feature flags in this project - please increase the feature flag upper limit in the - project settings. - - } - /> - + {projectFlagLimitReached ? ( + + Feature flag project limit reached. To be + able to create more feature flags in this project please + increase the feature flag upper limit in the project + settings. + + ) : null} { clearErrors={clearErrors} featureNaming={projectInfo.featureNaming} Limit={ - - } - /> + resourceLimitsEnabled ? ( + + ) : null } > What feature do you want to depend on? - { - setParentValue({ status: 'enabled' }); - setParent(status); - }} - /> - } - /> + {showDependencyDialogue ? ( + { + setParentValue({ status: 'enabled' }); + setParent(status); + }} + /> + ) : null} - - - What feature status do you want to depend - on? - - - - } - /> + {showStatus ? ( + + + What feature status do you want to depend on? + + + + ) : null} - - - What variant do you want to depend - on? - - - - ) - } - /> + {showVariants + ? parentValue.status === 'enabled_with_variants' && ( + + + What variant do you want to depend on? + + + + ) + : null} ); diff --git a/frontend/src/component/feature/FeatureForm/FeatureForm.tsx b/frontend/src/component/feature/FeatureForm/FeatureForm.tsx index c72556e2b269..9ef700765a80 100644 --- a/frontend/src/component/feature/FeatureForm/FeatureForm.tsx +++ b/frontend/src/component/feature/FeatureForm/FeatureForm.tsx @@ -15,7 +15,6 @@ import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes'; import KeyboardArrowDownOutlined from '@mui/icons-material/KeyboardArrowDownOutlined'; import { projectFilterGenerator } from 'utils/projectFilterGenerator'; import FeatureProjectSelect from '../FeatureView/FeatureSettings/FeatureSettingsProject/FeatureProjectSelect/FeatureProjectSelect'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { trim } from 'component/common/util'; import Input from 'component/common/Input/Input'; import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions'; @@ -149,12 +148,9 @@ const FeatureForm: React.FC = ({ What would you like to call your flag? - - } - /> + {displayFeatureNamingInfo ? ( + + ) : null} = ({ {renderToggleDescription()} - - In which project do you want to save the flag? - - } - /> + {editable ? ( + + In which project do you want to save the flag? + + ) : null} {/* TODO: this can be removed after new create flag flow goes live */} ({ @@ -39,24 +38,18 @@ export const FeatureNamingPatternInfo: React.FC = ({
    ^{featureNaming.pattern}$
    - -
    Example
    -
    {featureNaming?.example}
    - - } - /> - -
    Description
    -
    {featureNaming?.description}
    - - } - /> + {featureNaming?.example ? ( + <> +
    Example
    +
    {featureNaming?.example}
    + + ) : null} + {featureNaming?.description ? ( + <> +
    Description
    +
    {featureNaming?.description}
    + + ) : null} ); diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx index 08dc98273084..653532d9de3f 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx @@ -5,7 +5,6 @@ import Add from '@mui/icons-material/Add'; import HelpOutline from '@mui/icons-material/HelpOutline'; import type { IConstraint } from 'interfaces/strategy'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { HelpIcon } from 'component/common/HelpIcon/HelpIcon'; import { type IConstraintAccordionListRef, @@ -98,74 +97,67 @@ export const FeatureStrategyConstraintAccordionList = forwardRef< return ( - - - Constraints - - - Constraints are advanced - targeting rules that you can use - to enable a feature flag for a - subset of your users. Read more - about constraints{' '} - - here - - - - } - /> - - + + Constraints + + + Constraints are advanced targeting + rules that you can use to enable a + feature flag for a subset of your + users. Read more about constraints{' '} + + here + + + + } /> - - ({ - marginTop: theme.spacing(2), - marginBottom: theme.spacing(2), - })} - > - - } + + + + ({ + marginTop: theme.spacing(2), + marginBottom: theme.spacing(2), + })} + > + {resourceLimitsEnabled ? ( + - - - -
    - } - /> + ) : null} +
    + + + + ) : null} ); }, diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx index 25edd4794c78..437fdb8cb20e 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyCreate/FeatureStrategyCreate.tsx @@ -38,7 +38,6 @@ import { FeatureStrategyForm } from '../FeatureStrategyForm/FeatureStrategyForm' import { NewStrategyVariants } from 'component/feature/StrategyTypes/NewStrategyVariants'; import { useUiFlag } from 'hooks/useUiFlag'; import { Limit } from 'component/common/Limit/Limit'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const useStrategyLimit = (strategyCount: number) => { const resourceLimitsEnabled = useUiFlag('resourceLimits'); @@ -247,17 +246,14 @@ export const FeatureStrategyCreate = () => { /> } Limit={ - - } - /> + resourceLimitsEnabled ? ( + + ) : null } disabled={limitReached} /> diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/CopyButton/CopyButton.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/CopyButton/CopyButton.tsx index 4d849dca5fd4..916461322d4a 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/CopyButton/CopyButton.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/CopyButton/CopyButton.tsx @@ -12,7 +12,6 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import type { IFeatureEnvironment } from 'interfaces/featureToggle'; import AccessContext from 'contexts/AccessContext'; import { CREATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface ICopyButtonProps { environmentId: IFeatureEnvironment['name']; @@ -84,14 +83,11 @@ export const CopyButton: VFC = ({ onClick={() => onClick(environment)} disabled={!access} > - - - - } - /> + {!access ? ( + + + + ) : null} Copy from {environment} diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/FeatureStrategyEmpty.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/FeatureStrategyEmpty.tsx index 41035391d592..29a828504401 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/FeatureStrategyEmpty.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEmpty/FeatureStrategyEmpty.tsx @@ -5,7 +5,6 @@ import useToast from 'hooks/useToast'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { formatUnknownError } from 'utils/formatUnknownError'; import { useFeatureImmutable } from 'hooks/api/getters/useFeature/useFeatureImmutable'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { CopyButton } from './CopyButton/CopyButton'; import { useChangeRequestAddStrategy } from 'hooks/useChangeRequestAddStrategy'; import { ChangeRequestDialogue } from 'component/changeRequest/ChangeRequestConfirmDialog/ChangeRequestConfirmDialog'; @@ -142,7 +141,6 @@ export const FeatureStrategyEmpty = ({ /> } /> - You have not defined any strategies yet. @@ -170,18 +168,15 @@ export const FeatureStrategyEmpty = ({ environmentId={environmentId} matchWidth={canCopyFromOtherEnvironment} /> - environment.name, - )} - onClick={onCopyStrategies} - /> - } - /> + {canCopyFromOtherEnvironment ? ( + environment.name, + )} + onClick={onCopyStrategies} + /> + ) : null} diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx index c3ed22619252..0479eaee082b 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyEnabled/FeatureStrategyEnabled.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react'; import { Link } from 'react-router-dom'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Alert } from '@mui/material'; import type { IFeatureToggle } from 'interfaces/featureToggle'; import { formatFeaturePath } from '../../FeatureStrategyEdit/FeatureStrategyEdit'; @@ -23,26 +22,19 @@ export const FeatureStrategyEnabled: FC = ({ const featurePageLink = feature flag page; - return ( - - This feature flag is currently enabled in the{' '} - {environmentId} environment. Any changes - made here will be available to users as soon as you hit{' '} - save. - - } - elseShow={ - - This feature flag is currently disabled in the{' '} - {environmentId} environment. Any changes - made here will not take effect until the flag has been - enabled on the {featurePageLink}. - - } - /> + return isFeatureEnabledInEnvironment(feature, environmentId) ? ( + + This feature flag is currently enabled in the{' '} + {environmentId} environment. Any changes made here + will be available to users as soon as you hit save. + + ) : ( + + This feature flag is currently disabled in the{' '} + {environmentId} environment. Any changes made here + will not take effect until the flag has been enabled on the{' '} + {featurePageLink}. + ); }; diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx index 213f02d9d14b..fe5cb14707f3 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx @@ -22,7 +22,6 @@ import { FeatureStrategyEnabled } from './FeatureStrategyEnabled/FeatureStrategy import { FeatureStrategyConstraints } from '../FeatureStrategyConstraints/FeatureStrategyConstraints'; import type { IFeatureToggle } from 'interfaces/featureToggle'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { STRATEGY_FORM_SUBMIT_ID } from 'utils/testIds'; import { useConstraintsValidation } from 'hooks/api/getters/useConstraintsValidation/useConstraintsValidation'; import PermissionButton from 'component/common/PermissionButton/PermissionButton'; @@ -354,14 +353,11 @@ export const FeatureStrategyForm = ({ {formatStrategyName(strategy.name || '')} - - {strategy.parameters?.rollout}% - - } - /> + {strategy.name === 'flexibleRollout' ? ( + + {strategy.parameters?.rollout}% + + ) : null} {foundEnvironment ? ( @@ -381,57 +377,45 @@ export const FeatureStrategyForm = ({ ) : null} - - - } - /> - } - /> + {hasChangeRequestInReviewForEnvironment ? ( + alert + ) : ( + + } + /> + )} - - Custom strategies are deprecated. We recommend not - adding them to any flags going forward and using the - predefined strategies like Gradual rollout with{' '} - - constraints - {' '} - instead. - - } - /> - - } - /> + {!BuiltInStrategies.includes(strategy.name || 'default') ? ( + + Custom strategies are deprecated. We recommend not + adding them to any flags going forward and using the + predefined strategies like Gradual rollout with{' '} + + constraints + {' '} + instead. + + ) : null} + {!isChangeRequest ? ( + + ) : null} - - - { - setStrategy((prev) => ({ - ...prev, - title, - })); - }} - /> - - - setStrategy((strategyState) => ({ - ...strategyState, - disabled: !strategyState.disabled, - })) - } - /> + {tab === 0 ? ( + <> + { + setStrategy((prev) => ({ + ...prev, + title, + })); + }} + /> - - - } - /> + + setStrategy((strategyState) => ({ + ...strategyState, + disabled: !strategyState.disabled, + })) + } + /> - - - Segmentation and constraints allow you to set - filters on your strategies, so that they will - only be evaluated for users and applications - that match the specified preconditions. - - + + + ) : null} - - - AND - - - - } - /> + {tab === 1 ? ( + <> + + Segmentation and constraints allow you to set + filters on your strategies, so that they will only + be evaluated for users and applications that match + the specified preconditions. + + - + + AND + + - } - /> + + ) : null} + + {tab === 2 ? ( + + ) : null} {Limit} diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx index 389fc88fda9d..71c50287d4fb 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyMenu/FeatureStrategyMenuCards/FeatureStrategyMenuCards.tsx @@ -1,7 +1,6 @@ import { List, ListItem, styled, Typography } from '@mui/material'; import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; import { FeatureStrategyMenuCard } from '../FeatureStrategyMenuCard/FeatureStrategyMenuCard'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface IFeatureStrategyMenuCardsProps { projectId: string; @@ -64,26 +63,23 @@ export const FeatureStrategyMenuCards = ({ /> ))} - 0} - show={ - <> - - Custom strategies - - {customStrategies.map((strategy) => ( - - - - ))} - - } - /> + {customStrategies.length > 0 ? ( + <> + + Custom strategies + + {customStrategies.map((strategy) => ( + + + + ))} + + ) : null} ); }; diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip.tsx index 1a7664767cb5..6f787daa61d9 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip.tsx @@ -4,7 +4,6 @@ import type { ISegment } from 'interfaces/segment'; import Clear from '@mui/icons-material/Clear'; import VisibilityOff from '@mui/icons-material/VisibilityOff'; import Visibility from '@mui/icons-material/Visibility'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { constraintAccordionListId } from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList'; import { styled, type Theme, Tooltip } from '@mui/material'; @@ -63,13 +62,12 @@ export const FeatureStrategySegmentChip = ({ }); }; - const togglePreviewIcon = ( - } - elseShow={} - /> - ); + const togglePreviewIcon = + segment === preview ? ( + + ) : ( + + ); const previewIconTooltip = segment === preview diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentList.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentList.tsx index b33e5b517435..84d62e03368b 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentList.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentList.tsx @@ -1,7 +1,6 @@ import type React from 'react'; import { Fragment, useState } from 'react'; import type { ISegment } from 'interfaces/segment'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { FeatureStrategySegmentChip } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip'; import { SegmentItem } from 'component/common/SegmentItem/SegmentItem'; import { styled } from '@mui/material'; @@ -47,14 +46,11 @@ export const FeatureStrategySegmentList = ({ return ( <> - 0} - show={ - - Selected Segments - - } - /> + {segments && segments.length > 0 ? ( + + Selected Segments + + ) : null} {segments.map((segment, i) => ( @@ -64,17 +60,13 @@ export const FeatureStrategySegmentList = ({ preview={preview} setPreview={setPreview} /> - AND} - /> + {i < lastSegmentIndex ? ( + AND + ) : null} ))} - } - /> + {preview ? : null} ); }; diff --git a/frontend/src/component/feature/FeatureToggleList/BulkDisableDialog.tsx b/frontend/src/component/feature/FeatureToggleList/BulkDisableDialog.tsx index 8be537914a83..69aced302ea8 100644 --- a/frontend/src/component/feature/FeatureToggleList/BulkDisableDialog.tsx +++ b/frontend/src/component/feature/FeatureToggleList/BulkDisableDialog.tsx @@ -10,7 +10,6 @@ import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface IExportDialogProps { showExportDialog: boolean; @@ -121,26 +120,18 @@ export const BulkDisableDialog = ({ value={selected} onChange={(option: string) => setSelected(option)} /> - - Change requests are enabled for this environment. - - } - /> - 0} - show={ - - {alreadyDisabledCount} feature{' '} - {alreadyDisabledCount > 1 - ? 'flags are ' - : 'flag is '} - already disabled. - - } - /> + {isChangeRequestConfigured(selected) ? ( + + Change requests are enabled for this environment. + + ) : null} + {alreadyDisabledCount > 0 ? ( + + {alreadyDisabledCount} feature{' '} + {alreadyDisabledCount > 1 ? 'flags are ' : 'flag is '} + already disabled. + + ) : null} ); diff --git a/frontend/src/component/feature/FeatureToggleList/BulkEnableDialog.tsx b/frontend/src/component/feature/FeatureToggleList/BulkEnableDialog.tsx index 29d748c0fc4a..bc78ff58d44e 100644 --- a/frontend/src/component/feature/FeatureToggleList/BulkEnableDialog.tsx +++ b/frontend/src/component/feature/FeatureToggleList/BulkEnableDialog.tsx @@ -10,7 +10,6 @@ import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface IExportDialogProps { showExportDialog: boolean; @@ -122,26 +121,18 @@ export const BulkEnableDialog = ({ value={selected} onChange={(option: string) => setSelected(option)} /> - - Change requests are enabled for this environment. - - } - /> - 0} - show={ - - {alreadyEnabledCount} feature{' '} - {alreadyEnabledCount > 1 - ? 'flags are ' - : 'flag is '} - already enabled. - - } - /> + {isChangeRequestConfigured(selected) ? ( + + Change requests are enabled for this environment. + + ) : null} + {alreadyEnabledCount > 0 ? ( + + {alreadyEnabledCount} feature{' '} + {alreadyEnabledCount > 1 ? 'flags are ' : 'flag is '} + already enabled. + + ) : null} ); diff --git a/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx b/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx index 6cd79682c488..31d12e0a6487 100644 --- a/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx +++ b/frontend/src/component/feature/FeatureToggleList/ExportDialog.tsx @@ -7,7 +7,6 @@ import useToast from 'hooks/useToast'; import type { FeatureSchema } from 'openapi'; import { formatUnknownError } from 'utils/formatUnknownError'; -import { ConditionallyRender } from '../../common/ConditionallyRender/ConditionallyRender'; interface IExportDialogProps { showExportDialog: boolean; @@ -88,21 +87,17 @@ export const ExportDialog = ({ secondaryButtonText='Cancel' > - 0} - show={ - - The current search filter will be used to export - feature flags. Currently {data.length} feature flags - will be exported. - - } - elseShow={ - - You will export all feature flags from this project. - - } - /> + {data.length > 0 ? ( + + The current search filter will be used to export feature + flags. Currently {data.length} feature flags will be + exported. + + ) : ( + + You will export all feature flags from this project. + + )}

    diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureStaleCell/FeatureStaleCell.tsx b/frontend/src/component/feature/FeatureToggleList/FeatureStaleCell/FeatureStaleCell.tsx index 847cdae6e43c..a8b29082ed2e 100644 --- a/frontend/src/component/feature/FeatureToggleList/FeatureStaleCell/FeatureStaleCell.tsx +++ b/frontend/src/component/feature/FeatureToggleList/FeatureStaleCell/FeatureStaleCell.tsx @@ -1,6 +1,5 @@ import type { VFC } from 'react'; import { Box, styled, type Theme, Typography } from '@mui/material'; -import { ConditionallyRender } from '../../../common/ConditionallyRender/ConditionallyRender'; interface IFeatureStaleCellProps { value?: boolean; @@ -23,19 +22,15 @@ const StyledBox = styled(Box)(({ theme }) => ({ export const FeatureStaleCell: VFC = ({ value }) => { return ( - - Stale - - } - elseShow={ - - Active - - } - /> + {value ? ( + + Stale + + ) : ( + + Active + + )} ); }; diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListActions/FeatureToggleListActions.tsx b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListActions/FeatureToggleListActions.tsx index 0d8482f05487..0cbff9ae378c 100644 --- a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListActions/FeatureToggleListActions.tsx +++ b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListActions/FeatureToggleListActions.tsx @@ -14,7 +14,6 @@ import Add from '@mui/icons-material/Add'; import FileDownload from '@mui/icons-material/FileDownload'; import MoreVert from '@mui/icons-material/MoreVert'; import { Link } from 'react-router-dom'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useUiFlag } from 'hooks/useUiFlag'; import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions'; import { PermissionHOC } from 'component/common/PermissionHOC/PermissionHOC'; @@ -123,31 +122,26 @@ export const FeatureToggleListActions: FC = ({ )} - { - onExportClick(); - handleClose(); - trackEvent('search-feature-buttons', { - props: { - action: 'export', - }, - }); - }} - > - - - - - - Export - - - - } - /> + {featuresExportImport ? ( + { + onExportClick(); + handleClose(); + trackEvent('search-feature-buttons', { + props: { + action: 'export', + }, + }); + }} + > + + + + + Export + + + ) : null} diff --git a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx index 5cdfc5303488..a2662d934503 100644 --- a/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx +++ b/frontend/src/component/feature/FeatureToggleList/FeatureToggleListTable.tsx @@ -15,7 +15,6 @@ import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightC import { DateCell } from 'component/common/Table/cells/DateCell/DateCell'; import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; import { FeatureTypeCell } from 'component/common/Table/cells/FeatureTypeCell/FeatureTypeCell'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import type { FeatureSchema, FeatureSearchResponseSchema } from 'openapi'; @@ -287,23 +286,18 @@ export const FeatureToggleListTable: VFC = () => { title='Search' actions={ <> - - - - - } - /> + {!isSmallScreen ? ( + <> + + + + ) : null} { {featureSearchFeedback !== false && featureSearchFeedback?.enabled && ( <> - - - - - - } - /> - - } - onClick={ - createFeedbackContext - } - > - Provide feedback - - } - />{' '} - - } + {variant === 'withoutText' ? ( + + - Provide feedback - - } - /> + + + + ) : null} + {variant === 'withText' ? ( + + ) : null}{' '} + {variant === 'withTextOutlined' ? ( + + ) : null} )} } > - - } - /> + {isSmallScreen ? ( + + ) : null} } > @@ -405,41 +375,35 @@ export const FeatureToggleListTable: VFC = () => { - ({ padding: theme.spacing(0, 2, 2) })}> - 0} - show={ - - No feature flags found matching “ - {tableState.query} - ” - - } - elseShow={ - - No feature flags found matching your - criteria. Get started by adding a new - feature flag. - - } - /> -
    - } - /> - setShowExportDialog(false)} - environments={enabledEnvironments} - /> - } - /> + {rows.length === 0 ? ( + ({ padding: theme.spacing(0, 2, 2) })}> + {(tableState.query || '')?.length > 0 ? ( + + No feature flags found matching “ + {tableState.query} + ” + + ) : ( + + No feature flags found matching your criteria. Get + started by adding a new feature flag. + + )} + + ) : ( + + No feature flags found matching your criteria. Get started + by adding a new feature flag. + + )} + {uiConfig?.flags?.featuresExportImport ? ( + setShowExportDialog(false)} + environments={enabledEnvironments} + /> + ) : null} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetrics.tsx b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetrics.tsx index e1ee6698dbf8..d9bfb2349878 100644 --- a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetrics.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetrics.tsx @@ -10,7 +10,6 @@ import { Grid } from '@mui/material'; import { FeatureMetricsContent } from './FeatureMetricsContent/FeatureMetricsContent'; import { FeatureMetricsChips } from './FeatureMetricsChips/FeatureMetricsChips'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { usePageTitle } from 'hooks/usePageTitle'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { @@ -101,59 +100,53 @@ export const FeatureMetrics = () => { - 0} - show={ - { - setQuery({ environment: value }); - }} - /> - } - /> + {environments.size > 0 ? ( + { + setQuery({ environment: value }); + }} + /> + ) : null} - 0} - show={ - { - if (allSelected) { - setQuery({ - applications: [defaultApplication], - }); - } else { - setQuery({ - applications: [...applications], - }); - } - }} - toggleValue={(value) => { - if (selectedApplications.includes(value)) { - setQuery({ - applications: - selectedApplications.filter( - (app) => app !== value, - ), - }); - } else { - setQuery({ - applications: [ - ...selectedApplications, - value, - ], - }); - } - }} - /> - } - /> + {applications.size > 0 ? ( + { + if (allSelected) { + setQuery({ + applications: [defaultApplication], + }); + } else { + setQuery({ + applications: [...applications], + }); + } + }} + toggleValue={(value) => { + if (selectedApplications.includes(value)) { + setQuery({ + applications: + selectedApplications.filter( + (app) => app !== value, + ), + }); + } else { + setQuery({ + applications: [ + ...selectedApplications, + value, + ], + }); + } + }} + /> + ) : null} ; children?: React.ReactNode; }> = ({ children, environments, onArchive, onUncomplete, loading }) => { - return ( - - } - elseShow={ - - {children} - - } + return isSafeToArchive(environments) ? ( + + ) : ( + + {children} + ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/MarkCompletedDialogue.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/MarkCompletedDialogue.tsx index a405a9f89a1f..17b64ccce2fc 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/MarkCompletedDialogue.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureLifecycle/MarkCompletedDialogue.tsx @@ -3,7 +3,6 @@ import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { LegalValueLabel } from 'component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/LegalValueLabel/LegalValueLabel'; import { useState } from 'react'; import useFeatureLifecycleApi from 'hooks/api/actions/useFeatureLifecycleApi/useFeatureLifecycleApi'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { SingleVariantOptions } from './SingleVariantOptions'; import { useParentVariantOptions } from 'hooks/api/getters/useFeatureDependencyOptions/useFeatureDependencyOptions'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; @@ -111,36 +110,28 @@ export const MarkCompletedDialogue = ({ }} control={} /> - 0} - show={ - } - /> - } - /> - 0 && - status === 'kept-with-variant' - } - show={ - { - setVariant(variant); - }} - /> - } - /> + {variantOptions.length > 0 ? ( + } + /> + ) : null} + {variantOptions.length > 0 && + status === 'kept-with-variant' ? ( + { + setVariant(variant); + }} + /> + ) : null} diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx index ed3674c66563..827ea802823c 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/EnvironmentAccordionBody.tsx @@ -8,10 +8,8 @@ import { Alert, Pagination, styled } from '@mui/material'; import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi'; import { formatUnknownError } from 'utils/formatUnknownError'; import useToast from 'hooks/useToast'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategyDraggableItem } from './StrategyDraggableItem/StrategyDraggableItem'; import type { IFeatureEnvironment } from 'interfaces/featureToggle'; -import { FeatureStrategyEmpty } from 'component/feature/FeatureStrategy/FeatureStrategyEmpty/FeatureStrategyEmpty'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; @@ -200,93 +198,104 @@ const EnvironmentAccordionBody = ({ return ( - 0 && isDisabled} - show={() => ( - - This environment is disabled, which means that none - of your strategies are executing. - - )} - /> - 0} - show={ - - {strategies.map((strategy, index) => ( - - ))} - - } - elseShow={ - <> - - We noticed you're using a high number of - activation strategies. To ensure a more - targeted approach, consider leveraging - constraints or segments. - -
    - {page.map((strategy, index) => ( - {}) as any} - onDragOver={(() => {}) as any} - onDragEnd={(() => {}) as any} - /> - ))} -
    - - setPageIndex(page - 1) + {strategies.length > 0 && isDisabled ? ( + + This environment is disabled, which means that none of + your strategies are executing. + + ) : null} + {strategies.length > 0 ? ( + + {strategies.map((strategy, index) => ( + - - } - /> - } - elseShow={ - + } + elseShow={ + <> + + We noticed you're using a high number of + activation strategies. To ensure a more + targeted approach, consider leveraging + constraints or segments. + +
    + {page.map((strategy, index) => ( + {}) as any} + onDragOver={(() => {}) as any} + onDragEnd={(() => {}) as any} + /> + ))} +
    + + setPageIndex(page - 1) + } + /> + + } + /> + ) : ( + <> + + We noticed you're using a high number of activation + strategies. To ensure a more targeted approach, + consider leveraging constraints or segments. + +
    + {page.map((strategy, index) => ( + {}) as any} + onDragOver={(() => {}) as any} + onDragEnd={(() => {}) as any} + /> + ))} +
    + setPageIndex(page - 1)} /> - } - /> + + )}
    ); diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx index 94ced968b121..8616e2f105fa 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyDraggableItem.tsx @@ -1,6 +1,5 @@ import { type DragEventHandler, type RefObject, useRef } from 'react'; import { Box, useMediaQuery, useTheme } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import type { IFeatureEnvironment } from 'interfaces/featureToggle'; import type { IFeatureStrategy } from 'interfaces/strategy'; @@ -65,11 +64,7 @@ export const StrategyDraggableItem = ({ onDragOver={onDragOver(ref, index)} sx={{ opacity: isDragging ? '0.5' : '1' }} > - 0} - show={} - /> - + {index > 0 ? : null} - Modified in draft} - /> - Deleted in draft} - /> + {change?.action === 'updateStrategy' ? ( + Modified in draft + ) : null} + {change?.action === 'deleteStrategy' ? ( + Deleted in draft + ) : null} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/CopyStrategyIconMenu/CopyStrategyIconMenu.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/CopyStrategyIconMenu/CopyStrategyIconMenu.tsx index 22dfae11fe47..ce950b353e66 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/CopyStrategyIconMenu/CopyStrategyIconMenu.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/CopyStrategyIconMenu/CopyStrategyIconMenu.tsx @@ -13,7 +13,6 @@ import type { IFeatureStrategyPayload } from 'interfaces/strategy'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import type { IFeatureEnvironment } from 'interfaces/featureToggle'; import { CREATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import useFeatureStrategyApi from 'hooks/api/actions/useFeatureStrategyApi/useFeatureStrategyApi'; import useToast from 'hooks/useToast'; @@ -170,14 +169,11 @@ export const CopyStrategyIconMenu: VFC = ({ onClick={() => onCopyStrategy(environment)} disabled={!access} > - - - - } - /> + {!access ? ( + + + + ) : null} {environment === environmentId ? 'Duplicate in current' diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/MenuStrategyRemove/DisableEnableStrategyDialog/DisableEnableStrategyDialog.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/MenuStrategyRemove/DisableEnableStrategyDialog/DisableEnableStrategyDialog.tsx index 457413736e40..e58002e84745 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/MenuStrategyRemove/DisableEnableStrategyDialog/DisableEnableStrategyDialog.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/MenuStrategyRemove/DisableEnableStrategyDialog/DisableEnableStrategyDialog.tsx @@ -3,7 +3,6 @@ import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { useEnableDisable } from './hooks/useEnableDisable'; import { useSuggestEnableDisable } from './hooks/useSuggestEnableDisable'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { FeatureStrategyChangeRequestAlert } from 'component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyChangeRequestAlert/FeatureStrategyChangeRequestAlert'; import type { IDisableEnableStrategyProps } from './IDisableEnableStrategyProps'; @@ -63,20 +62,16 @@ export const DisableEnableStrategyDialog = ({ onClick={onClick} onClose={() => onClose()} > - - } - elseShow={ - - {disabled ? 'Enabling' : 'Disabling'} the strategy will - change which users receive access to the feature. - - } - /> + {isChangeRequest ? ( + + ) : ( + + {disabled ? 'Enabling' : 'Disabling'} the strategy will + change which users receive access to the feature. + + )} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/ConstraintItem/ConstraintItem.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/ConstraintItem/ConstraintItem.tsx index 91680bc0983b..ee5bcf779db8 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/ConstraintItem/ConstraintItem.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/ConstraintItem/ConstraintItem.tsx @@ -1,5 +1,4 @@ import { Chip, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import StringTruncator from 'component/common/StringTruncator/StringTruncator'; interface IConstraintItemProps { @@ -30,31 +29,28 @@ const StyledChip = styled(Chip)(({ theme }) => ({ export const ConstraintItem = ({ value, text }: IConstraintItemProps) => { return ( - No {text}s added yet.

    } - elseShow={ -
    - - {value.length}{' '} - {value.length > 1 ? `${text}s` : text} will get - access. - - {value.map((v: string) => ( - - } - /> - ))} -
    - } - /> + {value.length === 0 ? ( +

    No {text}s added yet.

    + ) : ( +
    + + {value.length} {value.length > 1 ? `${text}s` : text}{' '} + will get access. + + {value.map((v: string) => ( + + } + /> + ))} +
    + )}
    ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx index 9f7bf3dbe801..df63bdfd3bdf 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution.tsx @@ -1,6 +1,5 @@ import { Fragment, useMemo, type VFC } from 'react'; import { Alert, Box, Chip, Link, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { ConstraintItem } from './ConstraintItem/ConstraintItem'; @@ -252,24 +251,20 @@ export const StrategyExecution: VFC = ({ return typeof parameters[name] !== 'undefined' ? ( {nameItem} - - {' is an empty string'} - - } - elseShow={ - <> - {isSetTo} - - - } - /> + {value === '' ? ( + + {' is an empty string'} + + ) : ( + <> + {isSetTo} + + + )} ) : null; } @@ -327,30 +322,23 @@ export const StrategyExecution: VFC = ({ return ( <> - } - /> - - 0} - show={ - - {listItems.map((item, index) => ( - - 0} - show={} - /> - {item} - - ))} - - } - elseShow={} - /> + {!BuiltInStrategies.includes(strategy.name || 'default') ? ( + + ) : null} + {listItems.length > 0 ? ( + + {listItems.map((item, index) => ( + + {index > 0 ? ( + + ) : null} + {item} + + ))} + + ) : ( + + )} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx index 2e7cd133ec74..e9e8508bbd56 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx @@ -8,7 +8,6 @@ import { UPDATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/perm import { formatEditStrategyPath } from 'component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { StrategyExecution } from './StrategyExecution/StrategyExecution'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { CopyStrategyIconMenu } from './CopyStrategyIconMenu/CopyStrategyIconMenu'; import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer'; import MenuStrategyRemove from './MenuStrategyRemove/MenuStrategyRemove'; @@ -52,18 +51,13 @@ export const StrategyItem: FC = ({ actions={ <> {headerChildren} - 0, - )} - show={() => ( - - )} - /> + {otherEnvironments && otherEnvironments?.length > 0 ? ( + + ) : null} = ({ } > - {strategy.variants && strategy.variants.length > 0 && (strategy.disabled ? ( diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.tsx index 5b6e340dffef..b4bb75f3b3de 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/FeatureOverviewEnvironment.tsx @@ -10,7 +10,6 @@ import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import useFeatureMetrics from 'hooks/api/getters/useFeatureMetrics/useFeatureMetrics'; import type { IFeatureEnvironment } from 'interfaces/featureToggle'; import { getFeatureMetrics } from 'utils/getFeatureMetrics'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import EnvironmentIcon from 'component/common/EnvironmentIcon/EnvironmentIcon'; import StringTruncator from 'component/common/StringTruncator/StringTruncator'; import EnvironmentAccordionBody from './EnvironmentAccordionBody/EnvironmentAccordionBody'; @@ -132,111 +131,88 @@ const FeatureOverviewEnvironment = ({ (featureEnvironment) => featureEnvironment.name === env.name, ); - return ( - - - } - > - - - -
    - -
    - - Disabled - - } - /> -
    - - - - -
    - - + + } + > + + + +
    + +
    + {!env.enabled ? ( + + Disabled + + ) : null} +
    + + -
    - - - name) - .filter((name) => name !== env.name)} + - 0 - } - show={ - <> - - - - - - } +
    + + + + + + + name) + .filter((name) => name !== env.name)} + /> + {(featureEnvironment?.strategies?.length || 0) > 0 ? ( + <> + + + + - - - - } - /> - ); + + ) : null} + + + + ) : null; }; export default FeatureOverviewEnvironment; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/DependencyRow.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/DependencyRow.tsx index b04afbdedf59..d2d9b50d205c 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/DependencyRow.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/DependencyRow.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { AddDependencyDialogue } from 'component/feature/Dependencies/AddDependencyDialogue'; import type { IFeatureToggle } from 'interfaces/featureToggle'; import { type FC, useState } from 'react'; @@ -100,118 +99,85 @@ export const DependencyRow: FC<{ feature: IFeatureToggle }> = ({ feature }) => { return ( <> - - - Dependency: - { - setShowDependencyDialogue(true); - }} - sx={(theme) => ({ - marginBottom: theme.spacing(0.4), - })} - > - Add parent feature - - - - } - /> - - - Dependency: - - {feature.dependencies[0]?.feature} - - - - setShowDependencyDialogue(true) - } - onDelete={deleteDependency} - /> - } + {canAddParentDependency ? ( + + + Dependency: + { + setShowDependencyDialogue(true); + }} + sx={(theme) => ({ + marginBottom: theme.spacing(0.4), + })} + > + Add parent feature + + + + ) : null} + {hasParentDependency ? ( + + + Dependency: + + {feature.dependencies[0]?.feature} + + + {checkAccess(UPDATE_FEATURE_DEPENDENCY, environment) ? ( + setShowDependencyDialogue(true)} + onDelete={deleteDependency} /> - - } - /> - - - Dependency value: - disabled - - - } - /> - - - Dependency value: - - - - } - /> - - - Children: - - - - } - /> - - setShowDependencyDialogue(false)} - showDependencyDialogue={showDependencyDialogue} - /> - } - /> + ) : null} + + ) : null} + {hasParentDependency && !feature.dependencies[0]?.enabled ? ( + + + Dependency value: + disabled + + + ) : null} + {hasParentDependency && + Boolean(feature.dependencies[0]?.variants?.length) ? ( + + + Dependency value: + + + + ) : null} + {hasChildren ? ( + + + Children: + + + + ) : null} + {feature.project ? ( + setShowDependencyDialogue(false)} + showDependencyDialogue={showDependencyDialogue} + /> + ) : null} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx index fc3421697d38..9d0fdfc98380 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewMetaData/FeatureOverviewMetaData.tsx @@ -2,7 +2,6 @@ import { Box, capitalize, styled } from '@mui/material'; import { Link, useNavigate } from 'react-router-dom'; import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import Edit from '@mui/icons-material/Edit'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import { UPDATE_FEATURE } from 'component/providers/AccessProvider/permissions'; @@ -139,67 +138,60 @@ const FeatureOverviewMetaData = () => { Project: {project} - - Lifecycle: - setShowDelDialog(true)} - onComplete={() => - setShowMarkCompletedDialogue(true) - } - onUncomplete={refetchFeature} - /> - - } - /> + {feature.lifecycle ? ( + + Lifecycle: + setShowDelDialog(true)} + onComplete={() => + setShowMarkCompletedDialogue(true) + } + onUncomplete={refetchFeature} + /> + + ) : null} - - Description: - - - {description} - - - - - - - } - elseShow={ -
    - - No description.{' '} - - - - -
    - } - /> + {description ? ( + + Description: + + + {description} + + + + + + + ) : ( +
    + + No description.{' '} + + + + +
    + )} @@ -218,62 +210,49 @@ const FeatureOverviewMetaData = () => { /> - ( - - - - Created by: - {feature.createdBy?.name} - - - - - )} - /> - } - /> + {feature.createdBy ? ( + + + + Created by: + {feature.createdBy?.name} + + + + + ) : null} + {showDependentFeatures ? ( + + ) : null} - 0} - show={ - setShowDelDialog(false)} - /> - } - elseShow={ - { - navigate(`/projects/${projectId}`); - }} - onClose={() => setShowDelDialog(false)} - projectId={projectId} - featureIds={[featureId]} - /> - } - /> - - } - /> + {feature.children.length > 0 ? ( + setShowDelDialog(false)} + /> + ) : ( + { + navigate(`/projects/${projectId}`); + }} + onClose={() => setShowDelDialog(false)} + projectId={projectId} + featureIds={[featureId]} + /> + )} + {feature.project ? ( + + ) : null} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx index 9921f1fd0502..0c3d195571ba 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.tsx @@ -1,5 +1,4 @@ import { Fragment } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { SegmentItem } from '../../../../common/SegmentItem/SegmentItem'; import type { ISegment } from 'interfaces/segment'; @@ -21,10 +20,7 @@ export const FeatureOverviewSegment = ({ <> {segments.map((segment, index) => ( - 0} - show={} - /> + {index > 0 ? : null} ))} diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentHider.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentHider.tsx index 5aca611bc732..a987badf2580 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentHider.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentHider.tsx @@ -2,7 +2,6 @@ import type { IFeatureEnvironment } from 'interfaces/featureToggle'; import { IconButton, styled } from '@mui/material'; import Visibility from '@mui/icons-material/Visibility'; import VisibilityOff from '@mui/icons-material/VisibilityOff'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledVisibilityToggle = styled(IconButton, { shouldForwardProp: (prop) => prop !== 'visibilityOff', @@ -37,11 +36,11 @@ export const FeatureOverviewSidePanelEnvironmentHider = ({ onClick={toggleHiddenEnvironments} visibilityOff={hiddenEnvironments.has(environment.name)} > - } - elseShow={} - /> + {hiddenEnvironments.has(environment.name) ? ( + + ) : ( + + )} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitches.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitches.tsx index 8092fcdcb0d8..bc6af1615bf1 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitches.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitches.tsx @@ -2,7 +2,6 @@ import type { IFeatureToggle } from 'interfaces/featureToggle'; import { FeatureOverviewSidePanelEnvironmentSwitch } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelEnvironmentSwitches/FeatureOverviewSidePanelEnvironmentSwitch/FeatureOverviewSidePanelEnvironmentSwitch'; import { Link, styled, Tooltip } from '@mui/material'; import { Link as RouterLink } from 'react-router-dom'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import VariantsWarningTooltip from 'component/feature/FeatureView/FeatureVariants/VariantsTooltipWarning'; const StyledContainer = styled('div')(({ theme }) => ({ @@ -98,15 +97,12 @@ export const FeatureOverviewSidePanelEnvironmentSwitches = ({ {strategiesLabel} {variantsLink} - - - - - } - /> + {hasWarning ? ( + <> + + + + ) : null} diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelTags/FeatureOverviewSidePanelTags.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelTags/FeatureOverviewSidePanelTags.tsx index af22d2f70035..ef900e3ac7e3 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelTags/FeatureOverviewSidePanelTags.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewSidePanel/FeatureOverviewSidePanelTags/FeatureOverviewSidePanelTags.tsx @@ -12,7 +12,6 @@ import type { ITag } from 'interfaces/tags'; import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledContainer = styled('div')(({ theme }) => ({ display: 'flex', @@ -102,25 +101,19 @@ export const FeatureOverviewSidePanelTags = ({ ); })} - - 0} - show={} - /> - } - onClick={() => setOpenTagDialog(true)} - > - Add new tag - - - } - /> + {canUpdateTags ? ( + <> + {tags.length > 0 ? : null} + } + onClick={() => setOpenTagDialog(true)} + > + Add new tag + + + ) : null} = ({ value={tagType} onChange={handleTagTypeChange} /> - - No{' '} - - tag types - {' '} - available. - - } - elseShow={ - - } - /> + {!tagTypesLoading && tagTypes.length === 0 ? ( + + No{' '} + + tag types + {' '} + available. + + ) : ( + + )} diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/ManageTagsDialog/TagsInput.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/ManageTagsDialog/TagsInput.tsx index 7ebdc202e786..9e7daa709374 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/ManageTagsDialog/TagsInput.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/ManageTagsDialog/TagsInput.tsx @@ -11,7 +11,6 @@ import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox'; import type { ITag, ITagType } from 'interfaces/tags'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import Add from '@mui/icons-material/Add'; export type TagOption = { @@ -65,22 +64,20 @@ export const TagsInput = ({ ) ?? false; return (
  • - theme.spacing(0.5) }} />} - elseShow={ - } - indeterminateIcon={ - - } - sx={{ mr: (theme) => theme.spacing(0.5) }} - checked={selected && !isIndeterminate} - indeterminate={isIndeterminate} - /> - } - /> + {option.inputValue ? ( + theme.spacing(0.5) }} /> + ) : ( + } + indeterminateIcon={ + + } + sx={{ mr: (theme) => theme.spacing(0.5) }} + checked={selected && !isIndeterminate} + indeterminate={isIndeterminate} + /> + )} {option.title}
  • ); diff --git a/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettings.tsx b/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettings.tsx index fd22dc61ae93..a276ddbe32af 100644 --- a/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettings.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettings.tsx @@ -1,7 +1,6 @@ import { useState } from 'react'; import { PageContent } from 'component/common/PageContent/PageContent'; import { Box, List, ListItem, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import FeatureSettingsProject from './FeatureSettingsProject/FeatureSettingsProject'; import { FeatureSettingsInformation } from './FeatureSettingsInformation/FeatureSettingsInformation'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; @@ -62,19 +61,15 @@ export const FeatureSettings = () => { - - } - /> - } - /> + {settings === METADATA ? ( + + ) : null} + {settings === PROJECT && uiConfig.flags.P ? ( + + ) : null} diff --git a/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx b/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx index 4cd4a4bf6604..0f1cc7e7db61 100644 --- a/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureSettings/FeatureSettingsProject/FeatureSettingsProjectConfirm/FeatureSettingsProjectConfirm.tsx @@ -1,6 +1,5 @@ import { useMemo } from 'react'; import type { IFeatureToggle } from 'interfaces/featureToggle'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { arraysHaveSameItems } from 'utils/arraysHaveSameItems'; import { Alert, List, ListItem, styled } from '@mui/material'; @@ -61,123 +60,91 @@ const FeatureSettingsProjectConfirm = ({ const hasDependencies = feature.dependencies.length > 0 || feature.children.length > 0; - return ( - - - - This feature flag is compatible with the new - project. - + return hasSameEnvironments && + !hasDependencies && + !hasPendingChangeRequests && + !targetProjectHasChangeRequestsEnabled ? ( + + + + This feature flag is compatible with the new project. + +

    + Are you sure you want to change the project for this flag? +

    +
    +
    + ) : ( + + + + Cannot proceed with the move + + + {hasDependencies ? ( +

    + + The feature flag must not have any dependencies. + {' '} +
    + Please remove feature dependencies first. +

    + ) : null} + {!hasSameEnvironments ? ( +

    + In order to move a feature flag between two projects, + both projects must have the exact same environments + enabled. +

    + ) : null} + {hasPendingChangeRequests ? ( + <>

    - Are you sure you want to change the project for this - flag? + The feature flag must not have any pending change + requests. This feature flag is currently referenced + in the following change requests:

    -
    -
    - } - elseShow={ - - - - Cannot proceed with the move - - - - - The feature flag must not have any - dependencies. - {' '} -
    - - Please remove feature dependencies - first. - -

    - } - /> - - In order to move a feature flag between two - projects, both projects must have the exact - same environments enabled. -

    - } - /> - -

    - The feature flag must not have any - pending change requests. This feature - flag is currently referenced in the - following change requests: -

    - - {changeRequests?.map( - (changeRequest) => { - return ( - - - View change request{' '} - {changeRequest.id} - - - ); - }, - )} - - - } - /> - - You're not allowed to move the feature to - project{' '} - - {projectId} - - . This project has change requests enabled. -

    - } - /> -
    -
    - } - /> + + {changeRequests?.map((changeRequest) => { + return ( + + + View change request{' '} + {changeRequest.id} + + + ); + })} + + + ) : null} + {targetProjectHasChangeRequestsEnabled ? ( +

    + You're not allowed to move the feature to project{' '} + + {projectId} + + . This project has change requests enabled. +

    + ) : null} +
    + ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.tsx index 3de9a2ffc44d..3826c24518bd 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsCard.tsx @@ -2,7 +2,6 @@ import CloudCircle from '@mui/icons-material/CloudCircle'; import { styled, Link } from '@mui/material'; import type { IFeatureEnvironment } from 'interfaces/featureToggle'; import { EnvironmentVariantsTable } from './EnvironmentVariantsTable/EnvironmentVariantsTable'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Badge } from 'component/common/Badge/Badge'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useVariantsFromScheduledRequests } from './useVariantsFromScheduledRequests'; @@ -92,58 +91,46 @@ export const EnvironmentVariantsCard = ({ {environment.name} - 0} - show={ - - - - } - /> + {scheduledRequestIds.length > 0 ? ( + + + + ) : null} {children} - 0} - show={ - <> - - - - 1} - show={ - <> - -

    Stickiness:

    - {stickiness} -
    - - By overriding the stickiness you can - control which parameter is used to - ensure consistent traffic allocation - across variants.{' '} - - Read more - - - - } + {variants.length > 0 ? ( + <> + + - - } - /> + + {variants.length > 1 ? ( + <> + +

    Stickiness:

    + {stickiness} +
    + + By overriding the stickiness you can control + which parameter is used to ensure consistent + traffic allocation across variants.{' '} + + Read more + + + + ) : null} + + ) : null} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx index 25f76b06266a..8a3a35371538 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx @@ -1,5 +1,4 @@ import { TableBody, TableRow, useMediaQuery, useTheme } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { SortableTableHeader, Table, @@ -164,21 +163,18 @@ export const EnvironmentVariantsTable = ({ - 0} - show={ - - No variants found matching “ - {searchValue} - ” - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No variants found matching “ + {searchValue} + ” + + } + /> + ) : null} ); }; diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCopyFrom/EnvironmentVariantsCopyFrom.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCopyFrom/EnvironmentVariantsCopyFrom.tsx index f8569b2c2a63..ad13af941998 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCopyFrom/EnvironmentVariantsCopyFrom.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCopyFrom/EnvironmentVariantsCopyFrom.tsx @@ -1,5 +1,4 @@ import { ListItemText, Menu, MenuItem, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import PermissionButton from 'component/common/PermissionButton/PermissionButton'; import type { IFeatureEnvironment } from 'interfaces/featureToggle'; import { useState } from 'react'; @@ -36,54 +35,44 @@ export const EnvironmentVariantsCopyFrom = ({ const variants = environment.variants ?? []; - return ( - 0 && variants.length === 0 - } - show={ - <> - { - setCopyFromAnchorEl(e.currentTarget); - }} - id={`copy-from-menu-${environment.name}`} - aria-controls={copyFromOpen ? 'basic-menu' : undefined} - aria-haspopup='true' - aria-expanded={copyFromOpen ? 'true' : undefined} - variant='outlined' - permission={permission} - projectId={projectId} - environmentId={environmentId} + return otherEnvsWithVariants.length > 0 && variants.length === 0 ? ( + <> + { + setCopyFromAnchorEl(e.currentTarget); + }} + id={`copy-from-menu-${environment.name}`} + aria-controls={copyFromOpen ? 'basic-menu' : undefined} + aria-haspopup='true' + aria-expanded={copyFromOpen ? 'true' : undefined} + variant='outlined' + permission={permission} + projectId={projectId} + environmentId={environmentId} + > + Copy variants from + + setCopyFromAnchorEl(null)} + MenuListProps={{ + 'aria-labelledby': `copy-from-menu-${environment.name}`, + }} + > + {otherEnvsWithVariants.map((otherEnvironment) => ( + + onCopyVariantsFrom(otherEnvironment, environment) + } > - Copy variants from - - setCopyFromAnchorEl(null)} - MenuListProps={{ - 'aria-labelledby': `copy-from-menu-${environment.name}`, - }} - > - {otherEnvsWithVariants.map((otherEnvironment) => ( - - onCopyVariantsFrom( - otherEnvironment, - environment, - ) - } - > - - {`Copy from ${otherEnvironment.name}`} - - - ))} - - - } - /> - ); + + {`Copy from ${otherEnvironment.name}`} + + + ))} + + + ) : null; }; diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx index b4794a14c2dd..bd0709e8b438 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx @@ -3,7 +3,6 @@ import FormTemplate from 'component/common/FormTemplate/FormTemplate'; import { SidebarModal } from 'component/common/SidebarModal/SidebarModal'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import { type FormEvent, useEffect, useMemo, useState, memo } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { IFeatureEnvironment, IFeatureVariant, @@ -354,28 +353,25 @@ export const EnvironmentVariantsModal = ({ - - Change requests are - enabled - {environment - ? ` for ${environment.name}` - : ''} - . Your changes need to be approved - before they will be live. All the - changes you do now will be added into a - draft that you can submit for review. - - } - /> - } - /> + {hasChangeRequestInReviewForEnvironment ? ( + alert + ) : ( + + Change requests are enabled + {environment + ? ` for ${environment.name}` + : ''} + . Your changes need to be approved before + they will be live. All the changes you do + now will be added into a draft that you can + submit for review. + + } + /> + )} {variantsEdit.map((variant) => ( - 0} - show={ - <> - -

    Stickiness

    -
    - - By overriding the stickiness you can control - which parameter is used to ensure consistent - traffic allocation across variants.{' '} - - Read more - - -
    - - onStickinessChange(e.target.value) - } - /> -
    - - } - elseShow={ + {variantsEdit.length > 0 ? ( + <> + +

    Stickiness

    +
    - This environment has no variants. Get started by - adding a variant. + By overriding the stickiness you can control + which parameter is used to ensure consistent + traffic allocation across variants.{' '} + + Read more + - } - /> +
    + + onStickinessChange(e.target.value) + } + /> +
    + + ) : ( + + This environment has no variants. Get started by + adding a variant. + + )}
    + + + + + ) : null; }; diff --git a/frontend/src/component/feedbackNew/FeedbackList.tsx b/frontend/src/component/feedbackNew/FeedbackList.tsx index 4cba8fffb314..90b1c2daf6a9 100644 --- a/frontend/src/component/feedbackNew/FeedbackList.tsx +++ b/frontend/src/component/feedbackNew/FeedbackList.tsx @@ -6,7 +6,6 @@ import { sortTypes } from 'utils/sortTypes'; import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Search } from 'component/common/Search/Search'; import { useMediaQuery } from '@mui/material'; import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; @@ -122,30 +121,24 @@ export const FeedbackList = () => { title={`Feedbacks posted (${rows.length})`} actions={ <> - - - - - } - /> + {!isSmallScreen ? ( + <> + + + + ) : null} } > - - } - /> + {isSmallScreen ? ( + + ) : null} } > diff --git a/frontend/src/component/filter/FilterItem/FilterItemChip/FilterItemChip.tsx b/frontend/src/component/filter/FilterItem/FilterItemChip/FilterItemChip.tsx index 4fab6eec5f49..227c5e939a4c 100644 --- a/frontend/src/component/filter/FilterItem/FilterItemChip/FilterItemChip.tsx +++ b/frontend/src/component/filter/FilterItem/FilterItemChip/FilterItemChip.tsx @@ -1,7 +1,6 @@ import type { ComponentProps, FC, ReactNode } from 'react'; import ArrowDropDown from '@mui/icons-material/ArrowDropDown'; import Close from '@mui/icons-material/Close'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Chip, IconButton, styled } from '@mui/material'; import { FilterItemOperator } from './FilterItemOperator/FilterItemOperator'; import { FILTER_ITEM } from 'utils/testIds'; @@ -112,42 +111,37 @@ export const FilterItemChip: FC = ({ label={ {label} - } - elseShow={() => ( - <> - - - {explicitOptions.join(', ')} - {remainingOptions > 0 - ? ` +${remainingOptions}` - : ''} - - - )} - /> - ( - { - event.preventDefault(); - event.stopPropagation(); - onDelete?.(); - }} - size='small' - > - - - )} - /> + {!hasSelectedOptions ? ( + + ) : ( + <> + + + {explicitOptions.join(', ')} + {remainingOptions > 0 + ? ` +${remainingOptions}` + : ''} + + + )} + {onDelete ? ( + { + event.preventDefault(); + event.stopPropagation(); + onDelete?.(); + }} + size='small' + > + + + ) : null} } color='primary' diff --git a/frontend/src/component/filter/Filters/Filters.tsx b/frontend/src/component/filter/Filters/Filters.tsx index 472e22145f2d..e12bf2359196 100644 --- a/frontend/src/component/filter/Filters/Filters.tsx +++ b/frontend/src/component/filter/Filters/Filters.tsx @@ -1,6 +1,5 @@ import { type FC, useEffect, useState } from 'react'; import { Box, Icon, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { AddFilterButton } from '../AddFilterButton'; import { FilterDateItem } from 'component/common/FilterDateItem/FilterDateItem'; import { FilterItem, type FilterItemParams } from '../FilterItem/FilterItem'; @@ -168,19 +167,15 @@ export const Filters: FC = ({ /> ); })} - - - } - /> + {hasAvailableFilters ? ( + + ) : null} ); }; diff --git a/frontend/src/component/insights/InsightsCharts.tsx b/frontend/src/component/insights/InsightsCharts.tsx index 6384b0779f41..3a7516562fa1 100644 --- a/frontend/src/component/insights/InsightsCharts.tsx +++ b/frontend/src/component/insights/InsightsCharts.tsx @@ -21,7 +21,6 @@ import type { GroupedDataByProject } from './hooks/useGroupedProjectTrends'; import { allOption } from 'component/common/ProjectSelect/ProjectSelect'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import { WidgetTitle } from './components/WidgetTitle/WidgetTitle'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; export interface IChartsProps { flags: InstanceInsightsSchema['flags']; @@ -125,178 +124,165 @@ export const InsightsCharts: FC = ({ return ( - - - - - - - - - - - - - - - - - - - - - } - elseShow={ - <> - - - - - - - - - - - - - - - - - - - - } - /> - - - - - } - /> - - - - - - - - - - + {showAllProjects ? ( + <> + + + + + + + + + + + + + + + + + + + + ) : ( + <> + + + + + + + + + + + + + + + + + + + + )} + {isEnterprise() ? ( + <> + + + + } + /> + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - } - /> + + + + + + + + + + ) : null} ); }; diff --git a/frontend/src/component/insights/LegacyInsightsCharts.tsx b/frontend/src/component/insights/LegacyInsightsCharts.tsx index c83d3a82997d..deee3d08d6f9 100644 --- a/frontend/src/component/insights/LegacyInsightsCharts.tsx +++ b/frontend/src/component/insights/LegacyInsightsCharts.tsx @@ -1,6 +1,5 @@ import type { VFC } from 'react'; import { Box, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Widget } from './components/Widget/Widget'; import { UserStats } from './componentsStat/UserStats/UserStats'; import { UsersChart } from './componentsChart/UsersChart/UsersChart'; @@ -104,50 +103,42 @@ export const LegacyInsightsCharts: VFC = ({ return ( <> - - - - } - elseShow={ - - - - } - /> - - - - } - elseShow={ - - - - } - /> + {showAllProjects ? ( + + + + ) : ( + + + + )} + {showAllProjects ? ( + + + + ) : ( + + + + )} = ({ isLoading={loading} /> - - - - } - elseShow={ - - - - } - /> - - - - - - - - - - - - - - - } - /> - - + + + ) : ( + + + + )} + {isEnterprise() ? ( <> - + + + - + + + - theme.spacing(2) }} + - - + - } - /> + ) : null} + + {isEnterprise() ? ( + <> + + + + theme.spacing(2) }} + > + + + + ) : null} ); }; diff --git a/frontend/src/component/insights/components/Gauge/Gauge.tsx b/frontend/src/component/insights/components/Gauge/Gauge.tsx index def392ceda89..5bbaeda5d19e 100644 --- a/frontend/src/component/insights/components/Gauge/Gauge.tsx +++ b/frontend/src/component/insights/components/Gauge/Gauge.tsx @@ -1,6 +1,5 @@ import { Fragment, type VFC } from 'react'; import { Box, useTheme } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const polarToCartesian = ( centerX: number, @@ -172,18 +171,15 @@ export const Gauge: VFC = ({ value, min = 0, max = 100 }) => { strokeWidth={lineWidth - 0.01} strokeLinecap='round' /> - - } - /> + {value !== undefined ? ( + + ) : null} diff --git a/frontend/src/component/insights/components/InsightsHeader/InsightsHeader.tsx b/frontend/src/component/insights/components/InsightsHeader/InsightsHeader.tsx index 7a2dee00e29e..e48ab20a7c4e 100644 --- a/frontend/src/component/insights/components/InsightsHeader/InsightsHeader.tsx +++ b/frontend/src/component/insights/components/InsightsHeader/InsightsHeader.tsx @@ -10,7 +10,6 @@ import { useTheme, } from '@mui/material'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; type DashboardHeaderProps = { actions?: ReactNode; @@ -84,14 +83,11 @@ export const InsightsHeader: VFC = ({ actions }) => { } actions={ - - {actions} - - } - /> + {!isSmallScreen ? ( + + {actions} + + ) : null} - } - /> - } - /> - - No events have been registered for this - integration configuration. -

    + hasMore ? ( + + ) : null } /> + {integrationEvents.length === 0 ? ( +

    + No events have been registered for this integration + configuration. +

    + ) : null} diff --git a/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx b/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx index bdae52fb65b9..bb867d22f65d 100644 --- a/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx +++ b/frontend/src/component/integrations/IntegrationForm/IntegrationForm.tsx @@ -47,7 +47,6 @@ import { StyledRaisedSection, } from './IntegrationForm.styles'; import { GO_BACK } from 'constants/navigate'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { IntegrationDelete } from './IntegrationDelete/IntegrationDelete'; import { IntegrationStateSwitch } from './IntegrationStateSwitch/IntegrationStateSwitch'; import { capitalizeFirst } from 'utils/capitalizeFirst'; @@ -317,29 +316,23 @@ export const IntegrationForm: VFC = ({ {displayName || (name ? capitalizeFirst(name) : '')}{' '} integration - setEventsModalOpen(true)}> - View events - - } - /> + {editMode && isAdmin && integrationEventsEnabled ? ( + setEventsModalOpen(true)}> + View events + + ) : null} - ( - - {alerts?.map(({ type, text }) => ( - - {text} - - ))} - - )} - /> + {alerts ? ( + + {alerts?.map(({ type, text }) => ( + + {text} + + ))} + + ) : null} = ({ /> - ( - - )} - /> + {installation ? ( + + ) : null} = ({ /> ), )} - - } - /> + {isEnterprise() && signalsEnabled ? ( + + ) : null} {/* TODO: sort providers from backend with custom providers */} {customProviders?.map( ({ name, displayName, description }) => ( diff --git a/frontend/src/component/integrations/IntegrationList/ConfiguredIntegrations/ConfiguredIntegrations.tsx b/frontend/src/component/integrations/IntegrationList/ConfiguredIntegrations/ConfiguredIntegrations.tsx index 4ca4018d2321..2942ec906469 100644 --- a/frontend/src/component/integrations/IntegrationList/ConfiguredIntegrations/ConfiguredIntegrations.tsx +++ b/frontend/src/component/integrations/IntegrationList/ConfiguredIntegrations/ConfiguredIntegrations.tsx @@ -6,7 +6,6 @@ import type { VFC } from 'react'; import { Typography, styled } from '@mui/material'; import { useSignalEndpoints } from 'hooks/api/getters/useSignalEndpoints/useSignalEndpoints'; import { useUiFlag } from 'hooks/useUiFlag'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; const StyledConfiguredSection = styled('section')(({ theme }) => ({ @@ -73,27 +72,22 @@ export const ConfiguredIntegrations: VFC = ({ /> ); })} - 0 - } - show={ - - } - /> + {isEnterprise() && + signalsEnabled && + signalEndpoints.length > 0 ? ( + + ) : null} ); diff --git a/frontend/src/component/integrations/IntegrationList/IntegrationCard/IntegrationCard.tsx b/frontend/src/component/integrations/IntegrationList/IntegrationCard/IntegrationCard.tsx index b98349a7a57a..aded00283525 100644 --- a/frontend/src/component/integrations/IntegrationList/IntegrationCard/IntegrationCard.tsx +++ b/frontend/src/component/integrations/IntegrationList/IntegrationCard/IntegrationCard.tsx @@ -2,7 +2,6 @@ import type { VFC } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import { Link, styled, Tooltip, Typography } from '@mui/material'; import { IntegrationIcon } from '../IntegrationIcon/IntegrationIcon'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import { Badge } from 'component/common/Badge/Badge'; import { IntegrationCardMenu } from './IntegrationCardMenu/IntegrationCardMenu'; @@ -143,41 +142,29 @@ export const IntegrationCard: VFC = ({ {title} - - Deprecated - - } - /> - - Enabled - - } - /> - Disabled} - /> - } - /> + {deprecated !== undefined ? ( + + Deprecated + + ) : null} + {isEnabled === true ? ( + + Enabled + + ) : null} + {isEnabled === false ? ( + Disabled + ) : null} + {isConfigured ? ( + + ) : null} {description} {configureActionText} - } - elseShow={} - /> + {isExternal ? : } = ({ }} onClose={handleMenuClick} > - - {({ hasAccess }) => ( - setEventsModalOpen(true)} - disabled={!hasAccess} - > - - - - View events - - )} - - } - /> + {integrationEventsEnabled ? ( + + {({ hasAccess }) => ( + setEventsModalOpen(true)} + disabled={!hasAccess} + > + + + + View events + + )} + + ) : null} { setIsToggleOpen(true); @@ -176,7 +172,6 @@ export const IntegrationCardMenu: VFC = ({ Delete - { header={} isLoading={loading} > - 0 || signalEndpoints.length > 0} - show={ - - } - /> + {addons.length > 0 || signalEndpoints.length > 0 ? ( + + ) : null} ); diff --git a/frontend/src/component/layout/Error/Error.tsx b/frontend/src/component/layout/Error/Error.tsx index 853d530d62e5..8ae27a200b5e 100644 --- a/frontend/src/component/layout/Error/Error.tsx +++ b/frontend/src/component/layout/Error/Error.tsx @@ -2,7 +2,6 @@ import { useEffect, type VFC } from 'react'; import { useNavigate } from 'react-router-dom'; import { Box, Button } from '@mui/material'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; @@ -51,24 +50,16 @@ export const Error: VFC = ({ error }) => { window?.location?.reload(); }} maxWidth='xl' - customButton={ - } - /> - } + customButton={showZendeskButton ? : null} > {error.message} - - {error.stack} - - } - /> + {error.stack ? ( + + {error.stack} + + ) : null} ); diff --git a/frontend/src/component/layout/LayoutPicker/LayoutPicker.tsx b/frontend/src/component/layout/LayoutPicker/LayoutPicker.tsx index 660a46cf0bef..b575def8e2aa 100644 --- a/frontend/src/component/layout/LayoutPicker/LayoutPicker.tsx +++ b/frontend/src/component/layout/LayoutPicker/LayoutPicker.tsx @@ -1,5 +1,4 @@ import type { FC, ReactNode } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { MainLayout } from '../MainLayout/MainLayout'; interface ILayoutPickerProps { @@ -10,10 +9,4 @@ interface ILayoutPickerProps { export const LayoutPicker: FC = ({ isStandalone, children, -}) => ( - {children}} - /> -); +}) => (isStandalone === true ? children : {children}); diff --git a/frontend/src/component/layout/MainLayout/DraftBanner/DraftBanner.tsx b/frontend/src/component/layout/MainLayout/DraftBanner/DraftBanner.tsx index 42cb3029364b..b5a3ee5484b2 100644 --- a/frontend/src/component/layout/MainLayout/DraftBanner/DraftBanner.tsx +++ b/frontend/src/component/layout/MainLayout/DraftBanner/DraftBanner.tsx @@ -1,6 +1,5 @@ import { type FC, Fragment, useMemo, useState, type VFC } from 'react'; import { Box, Button, styled, Typography } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ChangeRequestSidebar } from 'component/changeRequest/ChangeRequestSidebar/ChangeRequestSidebar'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; import type { ChangeRequestType } from 'component/changeRequest/changeRequest.types'; @@ -82,28 +81,25 @@ const DraftBannerContent: FC<{ Change request mode – You have changes{' '} - - in{' '} - {environments.map((env, i) => - i === 0 ? ( - - {env} - - ) : ( - - {i === environments.length - 1 - ? ' and ' - : ', '} - {env} - - ), - )} - - } - /> + {environments ? ( + <> + in{' '} + {environments.map((env, i) => + i === 0 ? ( + + {env} + + ) : ( + + {i === environments.length - 1 + ? ' and ' + : ', '} + {env} + + ), + )} + + ) : null} {explanation}. + {changeRequestPlaygroundEnabled && changeRequest ? ( + + + {}} + type={'text'} + disabled + InputProps={{ + endAdornment: ( + + + + + + ), + }} + /> - } - /> + + + ) : null} ); diff --git a/frontend/src/component/playground/Playground/PlaygroundGuidance/PlaygroundGuidanceSection/PlaygroundGuidanceSection.tsx b/frontend/src/component/playground/Playground/PlaygroundGuidance/PlaygroundGuidanceSection/PlaygroundGuidanceSection.tsx index c074a8b3abe8..74a6b1ca70a5 100644 --- a/frontend/src/component/playground/Playground/PlaygroundGuidance/PlaygroundGuidanceSection/PlaygroundGuidanceSection.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundGuidance/PlaygroundGuidanceSection/PlaygroundGuidanceSection.tsx @@ -1,5 +1,4 @@ import { Box, Typography } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { GuidanceIndicator } from 'component/common/GuidanceIndicator/GuidanceIndicator'; import type { VFC } from 'react'; @@ -29,14 +28,11 @@ export const PlaygroundGuidanceSection: VFC< {headerText} - - {bodyText} - - } - /> + {bodyText ? ( + + {bodyText} + + ) : null} diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureDetails/FeatureDetails.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureDetails/FeatureDetails.tsx index 4ebf9e60cc0b..d38e566dbbb0 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureDetails/FeatureDetails.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureDetails/FeatureDetails.tsx @@ -3,7 +3,6 @@ import { Alert, IconButton, Typography, useTheme, styled } from '@mui/material'; import { PlaygroundResultChip } from '../../PlaygroundResultChip/PlaygroundResultChip'; import CloseOutlined from '@mui/icons-material/CloseOutlined'; import type React from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { checkForEmptyValues, hasCustomStrategies, @@ -129,22 +128,18 @@ export const FeatureDetails = ({ {feature.name} - ( - - )} - elseShow={() => ( - - )} - /> + {feature?.strategies?.result !== 'unknown' ? ( + + ) : ( + + )} @@ -161,24 +156,18 @@ export const FeatureDetails = ({ . - - {noValueTxt} - - } - /> - - - {customStrategiesTxt} - - - } - /> + {noValueTxt ? ( + + {noValueTxt} + + ) : null} + {customStrategiesTxt ? ( + + + {customStrategiesTxt} + + + ) : null} ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultFeatureStrategyList.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultFeatureStrategyList.tsx index 396e7881ad3b..e13e57779ba3 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultFeatureStrategyList.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/PlaygroundResultFeatureStrategyList.tsx @@ -2,7 +2,6 @@ import { PlaygroundResultStrategyLists, WrappedPlaygroundResultStrategyList, } from './StrategyList/playgroundResultStrategyLists'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { PlaygroundFeatureSchema, PlaygroundRequestSchema } from 'openapi'; import { Alert } from '@mui/material'; @@ -26,52 +25,38 @@ export const PlaygroundResultFeatureStrategyList = ({ return ( <> - - There are no strategies added to this feature flag in - selected environment. - - } - /> - + There are no strategies added to this feature flag in + selected environment. + + ) : null} + {(feature.hasUnsatisfiedDependency || + !feature.isEnabledInCurrentEnvironment) && + Boolean(feature?.strategies?.data) ? ( + + ) : ( + <> + - } - elseShow={ - <> + {showDisabledStrategies ? ( - - } - /> - - } - /> + ) : null} + + )} ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx index 531ba7a1e935..c754c45534c5 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/FeatureStrategyItem.tsx @@ -7,7 +7,6 @@ import type { import { StrategyExecution } from './StrategyExecution/StrategyExecution'; import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer'; import { objectId } from 'utils/objectId'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { DisabledStrategyExecution } from './StrategyExecution/DisabledStrategyExecution'; interface IFeatureStrategyItemProps { @@ -49,22 +48,18 @@ export const FeatureStrategyItem = ({ /> } > - - } - elseShow={ - - } - /> + {strategy.disabled ? ( + + ) : ( + + )} ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx index 1cd27bac0f56..9ec58b324652 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecution.tsx @@ -4,7 +4,6 @@ import type { PlaygroundRequestSchema, } from 'openapi'; import { objectId } from 'utils/objectId'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { styled } from '@mui/material'; import { ConstraintAccordionView } from 'component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView'; @@ -32,24 +31,19 @@ export const ConstraintExecution: VFC = ({ {constraints?.map((constraint, index) => ( - 0} - show={} - /> + {index > 0 ? : null} } - elseShow={ - - } - /> + constraint.result ? ( + + ) : ( + + ) } /> diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecutionWithoutResults.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecutionWithoutResults.tsx index e53ac10b1481..99234c3d2113 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecutionWithoutResults.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/ConstraintExecution/ConstraintExecutionWithoutResults.tsx @@ -1,7 +1,6 @@ import { Fragment, type VFC } from 'react'; import type { PlaygroundConstraintSchema } from 'openapi'; import { objectId } from 'utils/objectId'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { styled } from '@mui/material'; import { ConstraintAccordionView } from 'component/common/ConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView'; @@ -25,10 +24,7 @@ export const ConstraintExecutionWithoutResults: VFC< {constraints?.map((constraint, index) => ( - 0} - show={} - /> + {index > 0 ? : null} - - - {' required parameter '} - - - - {' is not set '} - - - } - elseShow={ - <> - - {' set on parameter '} - - - - } - /> + {requiredError ? ( + <> + + {' required parameter '} + + + + {' is not set '} + + + ) : ( + <> + + {' set on parameter '} + + + + )} - } - elseShow={
    } - /> + {requiredError ? :
    } ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/CustomStrategyParams/CustomStrategyParams.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/CustomStrategyParams/CustomStrategyParams.tsx index 9478a9e0177a..f9955c95e67c 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/CustomStrategyParams/CustomStrategyParams.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/CustomStrategyParams/CustomStrategyParams.tsx @@ -4,7 +4,6 @@ import { parseParameterString, parseParameterStrings, } from 'utils/parseParameter'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { useStrategies } from 'hooks/api/getters/useStrategies/useStrategies'; import { CustomParameterItem } from './CustomParameterItem/CustomParameterItem'; @@ -103,10 +102,7 @@ export const CustomStrategyParams: VFC = ({ <> {items.map((item, index) => ( - 0} - show={} - /> + {index > 0 ? : null} {item} ))} diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/DisabledStrategyExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/DisabledStrategyExecution.tsx index c6ebe493d6fe..255390be8686 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/DisabledStrategyExecution.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/DisabledStrategyExecution.tsx @@ -1,5 +1,4 @@ import { Fragment, type VFC } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { styled } from '@mui/material'; import type { @@ -75,15 +74,12 @@ export const DisabledStrategyExecution: VFC< {items.map((item, index) => ( - 0 && - (strategyResult.name === 'flexibleRollout' - ? index < items.length - : index < items.length - 1) - } - show={} - /> + {index > 0 && + (strategyResult.name === 'flexibleRollout' + ? index < items.length + : index < items.length - 1) ? ( + + ) : null} {item} ))} diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/PlaygroundParameterItem/PlaygroundParameterItem.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/PlaygroundParameterItem/PlaygroundParameterItem.tsx index 951dd700e02c..41a32b4b5e17 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/PlaygroundParameterItem/PlaygroundParameterItem.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/PlaygroundParameterItem/PlaygroundParameterItem.tsx @@ -1,5 +1,4 @@ import { Chip, Typography, useTheme, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import StringTruncator from 'component/common/StringTruncator/StringTruncator'; import CancelOutlined from '@mui/icons-material/CancelOutlined'; @@ -64,55 +63,48 @@ export const PlaygroundParameterItem = ({ {`${input}`} - - {reason} - - } - /> - No {text}s added yet.

    } - elseShow={ -
    - - {value.length}{' '} - {value.length > 1 ? `${text}s` : text} will get - access. - - {value.map((v: string | number) => ( - - } - /> - ))} -
    - } - /> + {showReason ? ( + + {reason} + + ) : null} + {value.length === 0 ? ( +

    No {text}s added yet.

    + ) : ( +
    + + {value.length}{' '} + {value.length > 1 ? `${text}s` : text} will get + access. + + {value.map((v: string | number) => ( + + } + /> + ))} +
    + )}
    - - } - elseShow={
    } - /> + {showReason ? ( + + ) : ( +
    + )} ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx index 91007c58d236..28ec150b517d 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecution.tsx @@ -4,7 +4,6 @@ import { ConstraintExecution } from '../ConstraintExecution/ConstraintExecution' import CancelOutlined from '@mui/icons-material/CancelOutlined'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { styled, Typography } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { SegmentItem } from 'component/common/SegmentItem/SegmentItem'; interface ISegmentExecutionProps { @@ -39,35 +38,31 @@ export const SegmentExecution: VFC = ({ /> } headerContent={ - - - segment is false - - - - - - } - /> + !segment.result ? ( + + + segment is false + + + + + + ) : null } isExpanded /> - = 0 && - segments.length > 1 && - // Don't add if it's the last segment item - index !== segments.length - 1 - } - show={} - /> + { + // Add IF there is a next segment + index >= 0 && + segments.length > 1 && + // Don't add if it's the last segment item + index !== segments.length - 1 ? ( + + ) : null + } ))} diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecutionWithoutResult.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecutionWithoutResult.tsx index f6a5fe491c3d..c91b55fd5e3e 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecutionWithoutResult.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/SegmentExecution/SegmentExecutionWithoutResult.tsx @@ -1,7 +1,6 @@ import { Fragment, type VFC } from 'react'; import type { PlaygroundSegmentSchema } from 'openapi'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { SegmentItem } from 'component/common/SegmentItem/SegmentItem'; import { ConstraintExecutionWithoutResults } from '../ConstraintExecution/ConstraintExecutionWithoutResults'; @@ -28,16 +27,15 @@ export const SegmentExecutionWithoutResult: VFC< isExpanded disabled /> - = 0 && - segments.length > 1 && - // Don't add if it's the last segment item - index !== segments.length - 1 - } - show={} - /> + { + // Add IF there is a next segment + index >= 0 && + segments.length > 1 && + // Don't add if it's the last segment item + index !== segments.length - 1 ? ( + + ) : null + } ))} diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx index 67143ea1d2f3..82397e4b5310 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecution.tsx @@ -1,5 +1,4 @@ import { Fragment, type VFC } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator'; import { styled } from '@mui/material'; import type { @@ -70,15 +69,12 @@ export const StrategyExecution: VFC = ({ {items.map((item, index) => ( - 0 && - (strategyResult.name === 'flexibleRollout' - ? index < items.length - : index < items.length - 1) - } - show={} - /> + {index > 0 && + (strategyResult.name === 'flexibleRollout' + ? index < items.length + : index < items.length - 1) ? ( + + ) : null} {item} ))} diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecutionParameters/StrategyExecutionParameters.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecutionParameters/StrategyExecutionParameters.tsx index 79a29aa127c8..ca806b5147dc 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecutionParameters/StrategyExecutionParameters.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/FeatureResultInfoPopoverCell/FeatureStrategyList/StrategyList/StrategyItem/StrategyExecution/StrategyExecutionParameters/StrategyExecutionParameters.tsx @@ -12,7 +12,6 @@ import type { } from 'openapi'; import { getMappedParam } from '../helpers'; import { Badge } from 'component/common/Badge/Badge'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import DisabledPercentageCircle from 'component/common/PercentageCircle/DisabledPercentageCircle'; export interface PlaygroundResultStrategyExecutionParametersProps { @@ -59,21 +58,17 @@ export const PlaygroundResultStrategyExecutionParameters = ({ : theme.palette.text.secondary, })} > - - } - elseShow={ - - } - /> + {disabled ? ( + + ) : ( + + )} ( - 0} - show={ - <> - {`${ - titlePrefix - ? titlePrefix.concat(' strategies') - : 'Strategies' - } (${strategies?.length})`} - - {infoText} - - } - /> - - {strategies?.map((strategy, index) => ( - - 0} - show={} - /> - - - ))} - - - } - /> -); +}: PlaygroundResultStrategyListProps) => + strategies.length > 0 ? ( + <> + {`${ + titlePrefix ? titlePrefix.concat(' strategies') : 'Strategies' + } (${strategies?.length})`} + {infoText ? ( + + {infoText} + + ) : null} + + {strategies?.map((strategy, index) => ( + + {index > 0 ? : null} + + + ))} + + + ) : null; interface IWrappedPlaygroundResultStrategyListProps { feature: PlaygroundFeatureSchema; @@ -132,21 +119,18 @@ export const WrappedPlaygroundResultStrategyList = ({ titlePrefix={showDisabledStrategies ? 'Enabled' : ''} /> - - - - } - /> + {showDisabledStrategies ? ( + + + + ) : null} ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip.tsx index c5bd63cce791..019ca02e6ccb 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/PlaygroundResultChip/PlaygroundResultChip.tsx @@ -1,6 +1,5 @@ import type { VFC } from 'react'; import { useTheme } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ReactComponent as FeatureEnabledIcon } from 'assets/icons/isenabled-true.svg'; import { ReactComponent as FeatureDisabledIcon } from 'assets/icons/isenabled-false.svg'; import WarningOutlined from '@mui/icons-material/WarningOutlined'; @@ -19,55 +18,43 @@ export const PlaygroundResultChip: VFC = ({ showIcon = true, }) => { const theme = useTheme(); - const icon = ( - } - elseShow={ - - } - elseShow={ - - } - /> - } - /> - ); + const icon = + enabled === 'unknown' || enabled === 'unevaluated' ? ( + + ) : ( + + } + elseShow={ + + } + /> + ); - return ( + return enabled === 'unknown' || enabled === 'unevaluated' ? ( + + {label} + + ) : ( + {label} } elseShow={ - - {label} - - } - elseShow={ - - {label} - - } - /> + + {label} + } /> ); diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantCell.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantCell.tsx index 01be79b8461b..c916a3d4e831 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantCell.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantCell.tsx @@ -1,6 +1,5 @@ import InfoOutlined from '@mui/icons-material/InfoOutlined'; import { IconButton, Popover, styled, useTheme } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type React from 'react'; import { useState, type VFC } from 'react'; import { VariantInformation } from './VariantInformation/VariantInformation'; @@ -39,39 +38,34 @@ export const VariantCell: VFC = ({ return ( {variant} - 0 && isEnabled - } - show={ - <> - - - + {Boolean(variants) && variants.length > 0 && isEnabled ? ( + <> + + + - - - - - } - /> + + + + + ) : null} ); }; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx index 5d0ef2042f86..2047cdfc2c83 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx @@ -8,7 +8,6 @@ import { sortTypes } from 'utils/sortTypes'; import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; import { SortableTableHeader } from 'component/common/Table'; import CheckCircleOutlined from '@mui/icons-material/CheckCircleOutlined'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { IconCell } from 'component/common/Table/cells/IconCell/IconCell'; interface IVariantInformationProps { @@ -122,12 +121,7 @@ const COLUMNS = [ original: { selected }, }, }: any) => ( - <> - } />} - /> - + <>{selected ? } /> : null} ), maxWidth: 25, disableGlobalFilter: true, diff --git a/frontend/src/component/project/NewProjectCard/NewProjectCard.tsx b/frontend/src/component/project/NewProjectCard/NewProjectCard.tsx index 23198c0502dd..e3691d3310b7 100644 --- a/frontend/src/component/project/NewProjectCard/NewProjectCard.tsx +++ b/frontend/src/component/project/NewProjectCard/NewProjectCard.tsx @@ -1,5 +1,4 @@ import { DEFAULT_PROJECT_ID } from 'hooks/api/getters/useDefaultProject/useDefaultProjectId'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StyledProjectCard, StyledDivHeader, @@ -57,19 +56,16 @@ export const ProjectCard = ({

    {featureCount === 1 ? 'flag' : 'flags'}

    - - - {memberCount} - -

    - {memberCount === 1 ? 'member' : 'members'} -

    -
    - } - /> + {id !== DEFAULT_PROJECT_ID ? ( +
    + + {memberCount} + +

    + {memberCount === 1 ? 'member' : 'members'} +

    +
    + ) : null}
    {health}% diff --git a/frontend/src/component/project/NewProjectCard/ProjectOwners/ProjectOwners.tsx b/frontend/src/component/project/NewProjectCard/ProjectOwners/ProjectOwners.tsx index b96b01c87af1..8da49ecbd2f2 100644 --- a/frontend/src/component/project/NewProjectCard/ProjectOwners/ProjectOwners.tsx +++ b/frontend/src/component/project/NewProjectCard/ProjectOwners/ProjectOwners.tsx @@ -2,7 +2,6 @@ import type { FC } from 'react'; import { styled } from '@mui/material'; import type { ProjectSchema, ProjectSchemaOwners } from 'openapi'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { AvatarGroup } from 'component/common/AvatarGroup/AvatarGroup'; interface IProjectOwnersProps { @@ -71,11 +70,11 @@ export const ProjectOwners: FC = ({ owners = [] }) => { - {users[0]?.name}} - elseShow={
    } - /> + {owners.length === 1 ? ( + {users[0]?.name} + ) : ( +
    + )} ); }; diff --git a/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/ConfigButtons/ChangeRequestTable.tsx b/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/ConfigButtons/ChangeRequestTable.tsx index b92c791c74ba..a5f03174a050 100644 --- a/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/ConfigButtons/ChangeRequestTable.tsx +++ b/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/ConfigButtons/ChangeRequestTable.tsx @@ -10,7 +10,6 @@ import { } from 'component/common/Table'; import { sortTypes } from 'utils/sortTypes'; import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect'; import KeyboardArrowDownOutlined from '@mui/icons-material/KeyboardArrowDownOutlined'; import { useTheme } from '@mui/material/styles'; @@ -93,33 +92,26 @@ export const ChangeRequestTable = (props: TableProps) => { { Header: 'Required approvals', Cell: ({ row: { original } }: any) => { - return ( - - { - onRequiredApprovalsChange( - original, - approvals, - ); - }} - IconComponent={ - KeyboardArrowDownOutlined - } - fullWidth - /> - - } - /> - ); + return original.changeRequestEnabled ? ( + + { + onRequiredApprovalsChange( + original, + approvals, + ); + }} + IconComponent={KeyboardArrowDownOutlined} + fullWidth + /> + + ) : null; }, width: 100, disableGlobalFilter: true, diff --git a/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/CreateProjectDialog.tsx b/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/CreateProjectDialog.tsx index 3e45f6102a47..81d95cc927c1 100644 --- a/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/CreateProjectDialog.tsx +++ b/frontend/src/component/project/Project/CreateProject/NewCreateProjectForm/CreateProjectDialog.tsx @@ -19,7 +19,6 @@ import { Dialog, styled } from '@mui/material'; import { useUiFlag } from 'hooks/useUiFlag'; import useProjects from 'hooks/api/getters/useProjects/useProjects'; import { Limit } from 'component/common/Limit/Limit'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { DialogFormTemplate } from 'component/common/DialogFormTemplate/DialogFormTemplate'; import { MultiSelectConfigButton } from 'component/common/DialogFormTemplate/ConfigButtons/MultiSelectConfigButton'; import { SingleSelectConfigButton } from 'component/common/DialogFormTemplate/ConfigButtons/SingleSelectConfigButton'; @@ -251,16 +250,13 @@ export const CreateProjectDialog = ({ creatingProject || limitReached || loadingLimit, }} Limit={ - - } - /> + resourceLimitsEnabled ? ( + + ) : null } handleSubmit={handleSubmit} name={projectName} @@ -335,79 +331,70 @@ export const CreateProjectDialog = ({ onClose={clearDocumentationOverride} /> - { - setProjectMode(value); - }} - button={{ - label: projectMode, - icon: , - labelWidth: `${`protected`.length}ch`, - }} - search={{ - label: 'Filter project mode options', - placeholder: 'Select project mode', - }} - onOpen={() => - setDocumentation( - configButtonData.mode, - ) - } - onClose={clearDocumentationOverride} - /> - } - /> - , - labelWidth: `${ - 'nn environments configured' - .length - }ch`, - }} - search={{ - label: 'Filter environments', - placeholder: 'Filter environments', - }} - projectChangeRequestConfiguration={ - projectChangeRequestConfiguration - } - onOpen={() => - setDocumentation( - configButtonData.changeRequests, - ) - } - onClose={clearDocumentationOverride} - /> - } - /> + {isEnterprise() ? ( + { + setProjectMode(value); + }} + button={{ + label: projectMode, + icon: , + labelWidth: `${`protected`.length}ch`, + }} + search={{ + label: 'Filter project mode options', + placeholder: 'Select project mode', + }} + onOpen={() => + setDocumentation(configButtonData.mode) + } + onClose={clearDocumentationOverride} + /> + ) : null} + {isEnterprise() ? ( + , + labelWidth: `${ + 'nn environments configured'.length + }ch`, + }} + search={{ + label: 'Filter environments', + placeholder: 'Filter environments', + }} + projectChangeRequestConfiguration={ + projectChangeRequestConfiguration + } + onOpen={() => + setDocumentation( + configButtonData.changeRequests, + ) + } + onClose={clearDocumentationOverride} + /> + ) : null} } /> diff --git a/frontend/src/component/project/Project/DeleteProject/DeleteProjectDialogue.tsx b/frontend/src/component/project/Project/DeleteProject/DeleteProjectDialogue.tsx index a163647c4a16..126c2210e575 100644 --- a/frontend/src/component/project/Project/DeleteProject/DeleteProjectDialogue.tsx +++ b/frontend/src/component/project/Project/DeleteProject/DeleteProjectDialogue.tsx @@ -4,7 +4,6 @@ import { formatUnknownError } from 'utils/formatUnknownError'; import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi'; import useProjects from 'hooks/api/getters/useProjects/useProjects'; import useToast from 'hooks/useToast'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useUiFlag } from 'hooks/useUiFlag'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import { Typography } from '@mui/material'; @@ -55,10 +54,9 @@ export const DeleteProjectDialogue = ({ This will irreversibly remove the project, all feature flags archived in it, all API keys scoped to only this project - + {isEnterprise() && automatedActionsEnabled + ? ', and all actions configured for it' + : null} . diff --git a/frontend/src/component/project/Project/Import/ImportModal.tsx b/frontend/src/component/project/Project/Import/ImportModal.tsx index 9147065a723a..82964fde0029 100644 --- a/frontend/src/component/project/Project/Import/ImportModal.tsx +++ b/frontend/src/component/project/Project/Import/ImportModal.tsx @@ -1,7 +1,6 @@ import { styled } from '@mui/material'; import { SidebarModal } from 'component/common/SidebarModal/SidebarModal'; import { useEffect, useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ImportTimeline } from './ImportTimeline'; import type { StageName } from './StageName'; import { @@ -79,65 +78,56 @@ export const ImportModal = ({ open, setOpen, project }: IImportModalProps) => { Process - - } - importOptions={ - - } - importArea={ - - } - actions={ - setImportStage('validate')} - onClose={close} - /> - } - /> - } - /> - setImportStage('configure')} - onSubmit={() => setImportStage('import')} - onClose={close} - /> - } - /> - - } - /> + {importStage === 'configure' ? ( + + } + importOptions={ + + } + importArea={ + + } + actions={ + setImportStage('validate')} + onClose={close} + /> + } + /> + ) : null} + {importStage === 'validate' ? ( + setImportStage('configure')} + onSubmit={() => setImportStage('import')} + onClose={close} + /> + ) : null} + {importStage === 'import' ? ( + + ) : null} ); diff --git a/frontend/src/component/project/Project/Import/configure/ConfigurationStage.tsx b/frontend/src/component/project/Project/Import/configure/ConfigurationStage.tsx index 4d4dd7ba8fa0..24daeb1ca576 100644 --- a/frontend/src/component/project/Project/Import/configure/ConfigurationStage.tsx +++ b/frontend/src/component/project/Project/Import/configure/ConfigurationStage.tsx @@ -7,7 +7,6 @@ import { TextField, Typography, } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StyledFileDropZone } from './StyledFileDropZone'; import { PulsingAvatar } from '../PulsingAvatar'; import ArrowUpward from '@mui/icons-material/ArrowUpward'; @@ -79,58 +78,49 @@ export const ImportArea: FC<{ const [dragActive, setDragActive] = useState(false); const { setToastData } = useToast(); - return ( - { - setImportPayload(data); - setActiveTab('code'); - setToastData({ - type: 'success', - title: 'File uploaded', - }); - }} - onError={(error) => { - setImportPayload(''); - setToastData({ - type: 'error', - title: error, - }); - }} - onDragStatusChange={setDragActive} - > - - - - - {dragActive - ? 'Drop your file to upload' - : 'Drop your file here'} - - - or select a file from your device - - - JSON format: max 500 kB - - } - elseShow={ - setImportPayload(event.target.value)} - value={importPayload} - data-testid={CODE_TEXT_FIELD} - multiline - minRows={13} - maxRows={13} - /> - } + return activeTab === 'file' ? ( + { + setImportPayload(data); + setActiveTab('code'); + setToastData({ + type: 'success', + title: 'File uploaded', + }); + }} + onError={(error) => { + setImportPayload(''); + setToastData({ + type: 'error', + title: error, + }); + }} + onDragStatusChange={setDragActive} + > + + + + + {dragActive + ? 'Drop your file to upload' + : 'Drop your file here'} + + + or select a file from your device + + + JSON format: max 500 kB + + ) : ( + setImportPayload(event.target.value)} + value={importPayload} + data-testid={CODE_TEXT_FIELD} + multiline + minRows={13} + maxRows={13} /> ); }; diff --git a/frontend/src/component/project/Project/Import/import/ImportStage.tsx b/frontend/src/component/project/Project/Import/import/ImportStage.tsx index 3eac181e5176..9c48f9f7f60a 100644 --- a/frontend/src/component/project/Project/Import/import/ImportStage.tsx +++ b/frontend/src/component/project/Project/Import/import/ImportStage.tsx @@ -9,7 +9,6 @@ import Check from '@mui/icons-material/Check'; import ErrorIcon from '@mui/icons-material/Error'; import Pending from '@mui/icons-material/Pending'; import { PulsingAvatar } from '../PulsingAvatar'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Box } from '@mui/system'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; @@ -94,60 +93,37 @@ export const ImportStage: FC<{ return ( - - - - } - /> - - - - } - /> - - - - } - /> + {importStatus.status === 'loading' ? ( + + + + ) : null} + {importStatus.status === 'success' ? ( + + + + ) : null} + {importStatus.status === 'error' ? ( + + + + ) : null} - - - + {importStatus.status === 'loading' ? 'Importing...' : null} + {importStatus.status === 'success' + ? 'Import completed' + : null} + {importStatus.status === 'error' ? 'Import failed' : null} - - For this environment Change request is - enabled. This means that the import has generated a - change request which needs to be approved before the - configuration will be visible in the instance. - - } - /> - + {showChangeRequestInfo ? ( + + For this environment Change request is + enabled. This means that the import has generated a change + request which needs to be approved before the configuration + will be visible in the instance. + + ) : null} - } - /> + ) : null} + + ) : null} + {projectOverviewRefactorFeedback && !isSmallScreen ? ( + + ) : null} } > - - } - /> + {isSmallScreen ? ( + + ) : null} ); diff --git a/frontend/src/component/project/Project/Project.tsx b/frontend/src/component/project/Project/Project.tsx index b4daa05083c2..0c337d34ce1b 100644 --- a/frontend/src/component/project/Project/Project.tsx +++ b/frontend/src/component/project/Project/Project.tsx @@ -1,6 +1,5 @@ import { useNavigate } from 'react-router'; import useLoading from 'hooks/useLoading'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StyledDiv, StyledFavoriteIconButton, @@ -200,33 +199,27 @@ export const Project = () => { isFavorite={project?.favorite} /> - } - /> + {project?.mode === 'private' ? ( + + ) : null} {projectName} - setModalOpen(true)} - tooltipProps={{ title: 'Import' }} - data-testid={IMPORT_BUTTON} - data-loading-project - > - - - } - /> + {uiConfig?.flags?.featuresExportImport ? ( + setModalOpen(true)} + tooltipProps={{ title: 'Import' }} + data-testid={IMPORT_BUTTON} + data-loading-project + > + + + ) : null} @@ -254,17 +247,14 @@ export const Project = () => { } icon={ <> - - - Beta - - - } - /> + {tab.new ? ( + // extra span to avoid badge getting color override from the overly specific parent component + + + Beta + + + ) : null} {(tab.isEnterprise && isPro() && enterpriseIcon) || diff --git a/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx b/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx index 5cb9ac384e5b..dccc8f003618 100644 --- a/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx +++ b/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx @@ -12,7 +12,6 @@ import { TablePlaceholder, } from 'component/common/Table'; import { PageContent } from 'component/common/PageContent/PageContent'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { Badge } from 'component/common/Badge/Badge'; import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns'; @@ -225,21 +224,18 @@ export const ProjectDoraMetrics = () => { })} - 0} - show={ - - No features with data found “ - {globalFilter} - ” - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No features with data found “ + {globalFilter} + ” + + } + /> + ) : null} ); diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx index 952314a2b1dd..8d816320ed01 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ColumnsMenu/ColumnsMenu.tsx @@ -12,7 +12,6 @@ import { } from '@mui/material'; import ColumnIcon from '@mui/icons-material/ViewWeek'; import CloseIcon from '@mui/icons-material/Close'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { StyledBoxContainer, StyledBoxMenuHeader, @@ -119,7 +118,6 @@ export const ColumnsMenu: VFC = ({ - = ({ {allColumns .filter(({ hideInMenu }) => !hideInMenu) .map((column) => [ - } - />, + dividerBefore.includes(column.id) ? ( + + ) : null, { column.toggleHidden(column.isVisible); @@ -179,31 +176,22 @@ export const ColumnsMenu: VFC = ({ id={column.id} primary={ - ( - <>{column.Header} - )} - elseShow={() => ( - <> - {columnNameMap[ - column.id - ] || column.id} - - )} - /> + {typeof column.Header === + 'string' && column.Header ? ( + <>{column.Header} + ) : ( + <> + {columnNameMap[column.id] || + column.id} + + )} } /> , - } - />, + dividerAfter.includes(column.id) ? ( + + ) : null, ])} diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/createFeatureToggleCell.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/createFeatureToggleCell.tsx index e46a656c742c..3d8da002ba4a 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/createFeatureToggleCell.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/createFeatureToggleCell.tsx @@ -1,7 +1,6 @@ import React, { useMemo } from 'react'; import { styled } from '@mui/material'; import { flexRow } from 'themes/themeStyles'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import VariantsWarningTooltip from 'component/feature/FeatureView/FeatureVariants/VariantsTooltipWarning'; import { FeatureToggleSwitch } from './FeatureToggleSwitch'; import type { UseFeatureToggleSwitchType } from './FeatureToggleSwitch.types'; @@ -74,10 +73,7 @@ const FeatureToggleCellComponent = ({ environmentName={environmentName} onToggle={onToggle} /> - } - /> + {hasWarning ? : null} ); }; diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/useFeatureToggleSwitch.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/useFeatureToggleSwitch.tsx index 74a568ad3152..967458b30a69 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/useFeatureToggleSwitch.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/FeatureToggleSwitch/useFeatureToggleSwitch.tsx @@ -14,7 +14,6 @@ import type { OnFeatureToggleSwitchArgs, UseFeatureToggleSwitchType, } from './FeatureToggleSwitch.types'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; type Middleware = (next: () => void) => void; @@ -219,14 +218,9 @@ export const useFeatureToggleSwitch: UseFeatureToggleSwitchType = ( const modals = ( <> - - } - /> + {featureSelected ? ( + + ) : null} { diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/MoreActions.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/MoreActions.tsx index 88fa5c03937d..6e9a56e8c684 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/MoreActions.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/MoreActions.tsx @@ -14,7 +14,6 @@ import { UPDATE_FEATURE } from 'component/providers/AccessProvider/permissions'; import MoreVert from '@mui/icons-material/MoreVert'; import WatchLater from '@mui/icons-material/WatchLater'; import type { FeatureSchema } from 'openapi'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi'; import useToast from 'hooks/useToast'; import { formatUnknownError } from 'utils/formatUnknownError'; @@ -129,50 +128,44 @@ export const MoreActions: VFC = ({ > {({ hasAccess }) => ( <> - ( - - `${theme.shape.borderRadius}px`, - }} - > - - - - - - Mark as stale - - - - )} - /> - ( - - `${theme.shape.borderRadius}px`, - }} - > - - - - - - Un-mark as stale - - - - )} - /> + {hasUnstale ? ( + + `${theme.shape.borderRadius}px`, + }} + > + + + + + + Mark as stale + + + + ) : null} + {hasStale ? ( + + `${theme.shape.borderRadius}px`, + }} + > + + + + + + Un-mark as stale + + + + ) : null} )} diff --git a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/ProjectFeaturesBatchActions.tsx b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/ProjectFeaturesBatchActions.tsx index 30f59b866025..198c683302bf 100644 --- a/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/ProjectFeaturesBatchActions.tsx +++ b/frontend/src/component/project/Project/ProjectFeatureToggles/ProjectFeaturesBatchActions/ProjectFeaturesBatchActions.tsx @@ -9,7 +9,6 @@ import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import { BulkDisableDialog } from 'component/feature/FeatureToggleList/BulkDisableDialog'; import { BulkEnableDialog } from 'component/feature/FeatureToggleList/BulkEnableDialog'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface IProjectFeaturesBatchActionsProps { selectedIds: string[]; @@ -72,32 +71,24 @@ export const ProjectFeaturesBatchActions: FC< return ( <> - setShowBulkEnableDialog(true)} - > - Enable - - } - /> - setShowBulkDisableDialog(true)} - > - Disable - - } - /> + {uiConfig?.flags?.disableBulkToggle ? null : ( + + )} + {uiConfig?.flags?.disableBulkToggle ? null : ( + + )} { - } - /> + {outdatedSdksBannerEnabled ? ( + + ) : null} = ({ autoFocus required /> - What is your project name? = ({ data-testid={PROJECT_NAME_INPUT} required /> - What is your project description? @@ -157,102 +154,82 @@ const ProjectForm: React.FC = ({ onChange={(e) => setProjectDesc(e.target.value)} data-testid={PROJECT_DESCRIPTION_INPUT} /> - - - - What is the default stickiness for the project? - - - setProjectStickiness?.(e.target.value) + {setProjectStickiness != null ? ( + <> + + What is the default stickiness for the project? + + setProjectStickiness?.(e.target.value)} + editable + /> + + ) : null} + {mode === 'Edit' ? ( + <> + +

    Feature flag limit?

    + +
    + + Leave it empty if you don’t want to add a limit + + + setFeatureLimit!(e.target.value)} /> - - } - /> - ( - <> - -

    Feature flag limit?

    - -
    - - Leave it empty if you don’t want to add a limit - - - - setFeatureLimit!(e.target.value) - } - /> - - ({featureCount} of {featureLimit} used) - - } - /> - - - )} - /> - - -

    What is your project collaboration mode?

    - -
    - { - setProjectMode?.(e.target.value as ProjectMode); - }} - options={projectModeOptions} - /> - - } - /> + {featureCount !== undefined && Boolean(featureLimit) ? ( + + ({featureCount} of {featureLimit} used) + + ) : null} +
    + + ) : null} + {mode === 'Create' && isEnterprise() ? ( + <> + +

    What is your project collaboration mode?

    + +
    + { + setProjectMode?.(e.target.value as ProjectMode); + }} + options={projectModeOptions} + /> + + ) : null} {children} ); diff --git a/frontend/src/component/project/Project/ProjectHealth/ProjectHealth.tsx b/frontend/src/component/project/Project/ProjectHealth/ProjectHealth.tsx index 12cbd7e9a2c5..dcf3de754d2d 100644 --- a/frontend/src/component/project/Project/ProjectHealth/ProjectHealth.tsx +++ b/frontend/src/component/project/Project/ProjectHealth/ProjectHealth.tsx @@ -1,6 +1,5 @@ import { useHealthReport } from 'hooks/api/getters/useHealthReport/useHealthReport'; import ApiError from 'component/common/ApiError/ApiError'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { usePageTitle } from 'hooks/usePageTitle'; import { ReportCard } from './ReportTable/ReportCard/ReportCard'; import { ReportTable } from './ReportTable/ReportTable'; @@ -23,17 +22,14 @@ const ProjectHealth = () => { return (
    - - } - /> + {error ? ( + + ) : null} { Health rating - -1} - show={ - <> - - {healthReport.health}% - - - Last updated:{' '} - - - - } - /> + {healthReport.health > -1 ? ( + <> + + {healthReport.health}% + + + Last updated:{' '} + + + + ) : null} Flag report
  • - + {healthReport.activeCount ? renderActiveToggles : null}
  • - - Also includes potentially stale flags. - - } - /> + {healthReport.activeCount ? ( + + Also includes potentially stale flags. + + ) : null}
  • - + {healthReport.staleCount ? renderStaleToggles : null}
  • @@ -186,34 +171,28 @@ export const ReportCard = ({ healthReport }: IReportCardProps) => {
  • - + {healthReport.potentiallyStaleCount + ? renderPotentiallyStaleToggles + : null}
  • - - - Review your feature flags and delete unused - flags. - - - - Configure feature types lifetime - - - - } - elseShow={No action is required} - /> + {healthReport.potentiallyStaleCount ? ( + <> + + Review your feature flags and delete unused flags. + + + + Configure feature types lifetime + + + + ) : ( + No action is required + )}
    ); diff --git a/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportTable.tsx b/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportTable.tsx index 37b2468e5d3d..74ef6ef35523 100644 --- a/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportTable.tsx +++ b/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportTable.tsx @@ -19,7 +19,6 @@ import { FeatureTypeCell } from 'component/common/Table/cells/FeatureTypeCell/Fe import { FeatureNameCell } from 'component/common/Table/cells/FeatureNameCell/FeatureNameCell'; import { DateCell } from 'component/common/Table/cells/DateCell/DateCell'; import { FeatureStaleCell } from 'component/feature/FeatureToggleList/FeatureStaleCell/FeatureStaleCell'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Search } from 'component/common/Search/Search'; import { ReportExpiredCell } from './ReportExpiredCell/ReportExpiredCell'; import { ReportStatusCell } from './ReportStatusCell/ReportStatusCell'; @@ -211,27 +210,29 @@ export const ReportTable = ({ projectId, features }: IReportTableProps) => { rows={rows} /> - 0} - show={ - - No feature flags found matching “ - {globalFilter} - ” - - } - elseShow={ - - No feature flags available. Get started by - adding a new feature flag. - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No feature flags found matching “ + {globalFilter} + ” + + } + elseShow={ + + No feature flags available. Get started by adding a + new feature flag. + + } + /> + ) : ( + + No feature flags available. Get started by adding a new + feature flag. + + )} ); }; diff --git a/frontend/src/component/project/Project/ProjectInfo/MetaWidget.tsx b/frontend/src/component/project/Project/ProjectInfo/MetaWidget.tsx index 5468cd8a5fde..f0f10fca5a61 100644 --- a/frontend/src/component/project/Project/ProjectInfo/MetaWidget.tsx +++ b/frontend/src/component/project/Project/ProjectInfo/MetaWidget.tsx @@ -5,7 +5,6 @@ import { StyledProjectInfoWidgetContainer, StyledWidgetTitle, } from './ProjectInfo.styles'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { WidgetFooterLink } from './WidgetFooterLink'; interface IMetaWidgetProps { @@ -35,30 +34,24 @@ export const MetaWidget: FC = ({ id, description }) => { {' '} {id || '__________'} - theme.spacing(1.5), - marginBottom: 0, - textAlign: 'left', - }} - > - {description} - - } - /> - - Add description - - } - /> + {description ? ( + theme.spacing(1.5), + marginBottom: 0, + textAlign: 'left', + }} + > + {description} + + ) : null} + {!description ? ( + + Add description + + ) : null} ); }; diff --git a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx index 894138ae8cb6..a4ced0c79d9a 100644 --- a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx +++ b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx @@ -1,6 +1,5 @@ import { Box, styled, useMediaQuery, useTheme } from '@mui/material'; import type { ProjectStatsSchema } from 'openapi/models/projectStatsSchema'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { DEFAULT_PROJECT_ID } from 'hooks/api/getters/useDefaultProject/useDefaultProjectId'; import { HealthWidget } from './HealthWidget'; import { FlagTypesWidget } from './FlagTypesWidget'; @@ -69,34 +68,28 @@ const ProjectInfo = ({ : { gridTemplateColumns: 'repeat(2, 1fr)' } } > - - - - } - /> + {showChangeRequestsWidget ? ( + + + + ) : null} - - } - /> + {showProjectMembersWidget ? ( + + ) : null} diff --git a/frontend/src/component/project/Project/ProjectInsights/LeadTimeForChanges/LeadTimeForChanges.tsx b/frontend/src/component/project/Project/ProjectInsights/LeadTimeForChanges/LeadTimeForChanges.tsx index 82d52611585c..aff34886c4ce 100644 --- a/frontend/src/component/project/Project/ProjectInsights/LeadTimeForChanges/LeadTimeForChanges.tsx +++ b/frontend/src/component/project/Project/ProjectInsights/LeadTimeForChanges/LeadTimeForChanges.tsx @@ -9,7 +9,6 @@ import { TableRow, TablePlaceholder, } from 'component/common/Table'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Badge } from 'component/common/Badge/Badge'; import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns'; import theme from 'themes/theme'; @@ -242,21 +241,18 @@ export const LeadTimeForChanges = ({ - 0} - show={ - - No features with data found “ - {globalFilter} - ” - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No features with data found “ + {globalFilter} + ” + + } + /> + ) : null} ); }; diff --git a/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealth.tsx b/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealth.tsx index 6b15b4ea96f5..87db8d5a05c6 100644 --- a/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealth.tsx +++ b/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealth.tsx @@ -4,7 +4,6 @@ import { Link } from 'react-router-dom'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import type { ProjectInsightsSchemaHealth } from '../../../../../openapi'; import type { FC } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const Dot = styled('span', { shouldForwardProp: (prop) => prop !== 'color', @@ -49,16 +48,12 @@ export const ProjectHealth: FC<{ health: ProjectInsightsSchemaHealth }> = ({ return ( Project Health - 0} - show={ - - Health alert! Review your flags and delete the - stale flags - - } - /> - + {staleCount > 0 ? ( + + Health alert! Review your flags and delete the stale + flags + + ) : null} ({ diff --git a/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealthChart.tsx b/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealthChart.tsx index 45ddccdd7abe..c184a38db06c 100644 --- a/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealthChart.tsx +++ b/frontend/src/component/project/Project/ProjectInsights/ProjectHealth/ProjectHealthChart.tsx @@ -1,6 +1,5 @@ import type React from 'react'; import { useTheme } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; interface ProgressComponentProps { active: number; @@ -72,50 +71,40 @@ export const ProjectHealthChart: React.FC = ({ strokeDasharray={`${activeLength} ${circumference}`} transform={`rotate(${activeRotation} 50 50)`} /> - - 0} - show={ - - } - /> - - 0} - show={ - - } - /> - + {potentiallyStale > 0 ? ( + + ) : null} + {stale > 0 ? ( + + ) : null} - ({ @@ -103,47 +102,43 @@ export const StatusBox: FC = ({ {boxText} - - {customChangeElement} - - } - elseShow={ - - + {customChangeElement} + + ) : ( + + + {resolveIcon(change as number)} + - {resolveIcon(change as number)} - - {(change as number) > 0 ? '+' : ''} - {change} - {percentage ? '%' : ''} - - - - this month - - - } - elseShow={ - - - No change - - - } - /> - } - /> + {(change as number) > 0 ? '+' : ''} + {change} + {percentage ? '%' : ''} + + + + this month + + + } + elseShow={ + + + No change + + + } + /> + )} ); diff --git a/frontend/src/component/project/Project/ProjectSettings/ChangeRequestConfiguration/ChangeRequestProcessHelp/ChangeRequestProcessHelp.tsx b/frontend/src/component/project/Project/ProjectSettings/ChangeRequestConfiguration/ChangeRequestProcessHelp/ChangeRequestProcessHelp.tsx index 959fe8a08b66..1c045f955008 100644 --- a/frontend/src/component/project/Project/ProjectSettings/ChangeRequestConfiguration/ChangeRequestProcessHelp/ChangeRequestProcessHelp.tsx +++ b/frontend/src/component/project/Project/ProjectSettings/ChangeRequestConfiguration/ChangeRequestProcessHelp/ChangeRequestProcessHelp.tsx @@ -7,7 +7,6 @@ import { Popover, Box, } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import HelpOutline from '@mui/icons-material/HelpOutline'; import { ReactComponent as ChangeRequestProcessWithScheduleImage } from 'assets/img/changeRequestProcessWithSchedule.svg'; @@ -25,14 +24,11 @@ export const ChangeRequestProcessHelp: VFC< return ( <> - - Show change request process{' '} - - } - /> + {!isSmallScreen ? ( + + Show change request process{' '} + + ) : null} { Cell: ({ row: { original } }: any) => { const { hasAccess } = useContext(AccessContext); - return ( - - { - onRequiredApprovalsChange( - original, - approvals, - ); - }} - disabled={ - !hasAccess( - [ - UPDATE_PROJECT, - PROJECT_CHANGE_REQUEST_WRITE, - ], - projectId, - ) - } - IconComponent={ - KeyboardArrowDownOutlined - } - fullWidth - /> - - } - /> - ); + return original.changeRequestEnabled ? ( + + { + onRequiredApprovalsChange( + original, + approvals, + ); + }} + disabled={ + !hasAccess( + [ + UPDATE_PROJECT, + PROJECT_CHANGE_REQUEST_WRITE, + ], + projectId, + ) + } + IconComponent={KeyboardArrowDownOutlined} + fullWidth + /> + + ) : null; }, width: 100, disableGlobalFilter: true, @@ -243,7 +235,6 @@ export const ChangeRequestTable: VFC = () => { in that environment needs to be approved before it will be applied - []} @@ -263,7 +254,6 @@ export const ChangeRequestTable: VFC = () => { })}
    - { trackEvent('change_request', { @@ -290,30 +280,23 @@ export const ChangeRequestTable: VFC = () => { You are about to{' '} {dialogState.isEnabled ? 'disable' : 'enable'} “Change request” - - {' '} - for{' '} - {dialogState.enableEnvironment} - - } - /> + {dialogState.enableEnvironment ? ( + <> + {' '} + for {dialogState.enableEnvironment} + + ) : null} . - - To enable change requests for an environment, you - need to ensure that your Unleash Admin has created - the necessary custom project roles in your Unleash - instance. This will allow you to assign project - members from the project access page. - - } - /> + {!dialogState.isEnabled ? ( + + To enable change requests for an environment, you need + to ensure that your Unleash Admin has created the + necessary custom project roles in your Unleash instance. + This will allow you to assign project members from the + project access page. + + ) : null} ); diff --git a/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsDetails/ProjectActionsEventsDetailsAction.tsx b/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsDetails/ProjectActionsEventsDetailsAction.tsx index de7fffb83830..407a6ceaee00 100644 --- a/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsDetails/ProjectActionsEventsDetailsAction.tsx +++ b/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsDetails/ProjectActionsEventsDetailsAction.tsx @@ -1,7 +1,6 @@ import CheckCircleOutline from '@mui/icons-material/CheckCircleOutline'; import ErrorOutline from '@mui/icons-material/ErrorOutline'; import { Alert, CircularProgress, Divider, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { IActionEvent } from 'interfaces/action'; import type { ReactNode } from 'react'; @@ -90,10 +89,9 @@ export const ProjectActionsEventsDetailsAction = ({
    {children}
    {actionState} - {details}} - /> + {details ? ( + {details} + ) : null} diff --git a/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsModal.tsx b/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsModal.tsx index 79b74bb1376d..8a36ece5cad5 100644 --- a/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsModal.tsx +++ b/frontend/src/component/project/Project/ProjectSettings/ProjectActions/ProjectActionsTable/ProjectActionsEventsModal/ProjectActionsEventsModal.tsx @@ -6,7 +6,6 @@ import FormTemplate from 'component/common/FormTemplate/FormTemplate'; import { SidePanelList } from 'component/common/SidePanelList/SidePanelList'; import { formatDateYMDHMS } from 'utils/formatDate'; import { useLocationSettings } from 'hooks/useLocationSettings'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { ProjectActionsEventsStateCell } from './ProjectActionsEventsStateCell'; import { ProjectActionsEventsDetails } from './ProjectActionsEventsDetails/ProjectActionsEventsDetails'; @@ -134,25 +133,16 @@ export const ProjectActionsEventsModal = ({ return children; }} listEnd={ - - Load more - - } - /> - } - /> - - No events have been registered for this action - set. -

    + hasMore ? ( + + ) : null } /> + {actionEvents.length === 0 ? ( +

    + No events have been registered for this action set. +

    + ) : null}
    - ({ padding: theme.spacing(0, 2, 2) })}> - 0} - show={ - - No applications found matching “ - {query} - ” - - } - elseShow={ - - No applications found matching your - criteria. - - } - /> - - } - /> + {rows.length === 0 ? ( + ({ padding: theme.spacing(0, 2, 2) })}> + {(query || '')?.length > 0 ? ( + + No applications found matching “ + {query} + ” + + ) : ( + + No applications found matching your criteria. + + )} + + ) : ( + + No applications found matching your criteria. + + )} ); }; diff --git a/frontend/src/component/project/ProjectEnvironment/ProjectEnvironment.tsx b/frontend/src/component/project/ProjectEnvironment/ProjectEnvironment.tsx index 5cb2338b6101..c6505cb66627 100644 --- a/frontend/src/component/project/ProjectEnvironment/ProjectEnvironment.tsx +++ b/frontend/src/component/project/ProjectEnvironment/ProjectEnvironment.tsx @@ -1,5 +1,4 @@ import { useMemo, useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions'; @@ -236,10 +235,7 @@ const ProjectEnvironmentList = () => { return ( - + {error ? renderError() : null} Important! In order for your application to retrieve configured activation strategies for a specific @@ -274,27 +270,28 @@ const ProjectEnvironmentList = () => { - 0} - show={ - - No environments found matching “ - {globalFilter} - ” - - } - elseShow={ - - No environments available. Get started by - adding one. - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No environments found matching “ + {globalFilter} + ” + + } + elseShow={ + + No environments available. Get started by adding + one. + + } + /> + ) : ( + + No environments available. Get started by adding one. + + )} = ({ sectionTitle, projects, loading, searchValue }) => { return (
    - ({ marginBottom: theme.spacing(2) })} - > - {sectionTitle} - - } - /> - 0} - show={ - - No projects found matching “ - {searchValue} - ” - - } - elseShow={ - - No projects available. - - } - /> - } - elseShow={ - - ( - <> - {loadingData.map( - (project: IProjectCard) => ( - {}} - key={project.id} - name={project.name} - id={project.id} - mode={project.mode} - memberCount={2} - health={95} - featureCount={4} - /> - ), - )} - - )} - elseShow={() => ( - <> - {projects.map((project: IProjectCard) => ( - - {}} - name={project.name} - mode={project.mode} - memberCount={ - project.memberCount ?? 0 - } - health={project.health} - id={project.id} - featureCount={ - project.featureCount - } - isFavorite={project.favorite} - owners={project.owners} - /> - - ))} - - )} - /> - - } - /> + {sectionTitle ? ( + ({ marginBottom: theme.spacing(2) })} + > + {sectionTitle} + + ) : null} + {projects.length < 1 && !loading ? ( + 0} + show={ + + No projects found matching “ + {searchValue} + ” + + } + elseShow={ + + No projects available. + + } + /> + ) : ( + No projects available. + )}
    ); }; diff --git a/frontend/src/component/project/ProjectList/ProjectList.tsx b/frontend/src/component/project/ProjectList/ProjectList.tsx index e429978fbaea..0b900ca38460 100644 --- a/frontend/src/component/project/ProjectList/ProjectList.tsx +++ b/frontend/src/component/project/ProjectList/ProjectList.tsx @@ -1,7 +1,6 @@ import { type FC, useContext, useEffect, useMemo, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import useProjects from 'hooks/api/getters/useProjects/useProjects'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { IProjectCard } from 'interfaces/project'; import { PageContent } from 'component/common/PageContent/PageContent'; import AccessContext from 'contexts/AccessContext'; @@ -189,44 +188,35 @@ export const ProjectListNew = () => { title={`Projects (${projectCount})`} actions={ <> - - - - - } - /> + {!isSmallScreen ? ( + <> + + + + ) : null} } > - - } - /> + {isSmallScreen ? ( + + ) : null} } > - ( - - )} - /> + {error ? ( + + ) : null} { > - ( - toggleModal(false)} - onRemove={onRemove} - /> - )} - /> + {showModal ? ( + toggleModal(false)} + onRemove={onRemove} + /> + ) : null} ); }; diff --git a/frontend/src/component/segments/SegmentDelete/SegmentDelete.tsx b/frontend/src/component/segments/SegmentDelete/SegmentDelete.tsx index c60bdac0412e..a89f08093c19 100644 --- a/frontend/src/component/segments/SegmentDelete/SegmentDelete.tsx +++ b/frontend/src/component/segments/SegmentDelete/SegmentDelete.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useStrategiesBySegment } from 'hooks/api/getters/useStrategiesBySegment/useStrategiesBySegment'; import type { ISegment } from 'interfaces/segment'; import { SegmentDeleteConfirm } from './SegmentDeleteConfirm/SegmentDeleteConfirm'; @@ -25,26 +24,20 @@ export const SegmentDelete = ({ return null; } - return ( - - } - elseShow={ - - } + return canDeleteSegment ? ( + + ) : ( + ); }; diff --git a/frontend/src/component/segments/SegmentEmpty.tsx b/frontend/src/component/segments/SegmentEmpty.tsx index 52c2468df315..e59e15ed1478 100644 --- a/frontend/src/component/segments/SegmentEmpty.tsx +++ b/frontend/src/component/segments/SegmentEmpty.tsx @@ -4,7 +4,6 @@ import { CREATE_SEGMENT, UPDATE_PROJECT_SEGMENT, } from 'component/providers/AccessProvider/permissions'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import AccessContext from 'contexts/AccessContext'; import { useContext } from 'react'; import { useOptionalPathParam } from 'hooks/useOptionalPathParam'; @@ -50,17 +49,11 @@ export const SegmentEmpty = () => { your feature. The segment is often a collection of constraints and can be reused. - - Create your first segment - - } - /> + {hasAccess([CREATE_SEGMENT, UPDATE_PROJECT_SEGMENT], projectId) ? ( + + Create your first segment + + ) : null} ); }; diff --git a/frontend/src/component/segments/SegmentForm.tsx b/frontend/src/component/segments/SegmentForm.tsx index fe6199d4722c..d05f2ca78741 100644 --- a/frontend/src/component/segments/SegmentForm.tsx +++ b/frontend/src/component/segments/SegmentForm.tsx @@ -4,7 +4,6 @@ import { SegmentFormStepTwo } from './SegmentFormStepTwo'; import type React from 'react'; import { useState } from 'react'; import { SegmentFormStepList } from 'component/segments/SegmentFormStepList'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { styled } from '@mui/material'; export type SegmentFormStep = 1 | 2; @@ -54,36 +53,30 @@ export const SegmentForm: React.FC = ({ <> - - } - /> - - {children} - - } - /> + {currentStep === 1 ? ( + + ) : null} + {currentStep === 2 ? ( + + {children} + + ) : null} ); diff --git a/frontend/src/component/segments/SegmentFormStepOne.tsx b/frontend/src/component/segments/SegmentFormStepOne.tsx index cb5a8b87ef5b..1be1c48fd9d6 100644 --- a/frontend/src/component/segments/SegmentFormStepOne.tsx +++ b/frontend/src/component/segments/SegmentFormStepOne.tsx @@ -8,7 +8,6 @@ import { SEGMENT_DESC_ID, SEGMENT_NEXT_BTN_ID, } from 'utils/testIds'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import useProjects from 'hooks/api/getters/useProjects/useProjects'; import { useOptionalPathParam } from 'hooks/useOptionalPathParam'; import { GO_BACK } from 'constants/navigate'; @@ -172,50 +171,42 @@ export const SegmentFormStepOne: React.FC = ({ errorText={errors.description} data-testid={SEGMENT_DESC_ID} /> - - - Is this segment tied to a specific project? - - { - setProject(newValue?.id); - }} - options={availableProjects} - getOptionLabel={(option) => option.name} - renderInput={(params) => ( - - )} - disabled={projectsUsed.size > 1} - /> - - - } - /> + {!projectId && !loading ? ( + <> + + Is this segment tied to a specific project? + + { + setProject(newValue?.id); + }} + options={availableProjects} + getOptionLabel={(option) => option.name} + renderInput={(params) => ( + + )} + disabled={projectsUsed.size > 1} + /> + + + ) : null} - - - } - /> + {resourceLimitsEnabled ? ( + + ) : null} -
    ); }; diff --git a/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsForm/SignalEndpointsTokens/SignalEndpointsTokens.tsx b/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsForm/SignalEndpointsTokens/SignalEndpointsTokens.tsx index 26fc31799a77..1e4f22b92ad2 100644 --- a/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsForm/SignalEndpointsTokens/SignalEndpointsTokens.tsx +++ b/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsForm/SignalEndpointsTokens/SignalEndpointsTokens.tsx @@ -28,7 +28,6 @@ import { sortTypes } from 'utils/sortTypes'; import { SignalEndpointsTokensCreateDialog } from './SignalEndpointsTokensCreateDialog'; import { SignalEndpointsTokensDialog } from './SignalEndpointsTokensDialog'; import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; import { type SignalEndpointTokenPayload, @@ -241,39 +240,50 @@ export const SignalEndpointsTokens = ({ prepareRow={prepareRow} /> - 0} - show={ - - No tokens found matching “ - {searchValue} - ” - - } - elseShow={ - - - You have no tokens for this signal endpoint - yet. - - - Create a token to start using this signal - endpoint. - - - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No tokens found matching “ + {searchValue} + ” + + } + elseShow={ + + + You have no tokens for this signal endpoint yet. + + + Create a token to start using this signal + endpoint. + + + + } + /> + ) : ( + + + You have no tokens for this signal endpoint yet. + + + Create a token to start using this signal endpoint. + + + + )} Your token: - ( - <> - - You can call your signal endpoint with the newly - created token like this: - - - {`curl --request POST '${ - uiConfig.unleashUrl - }/api/signal-endpoint/${signalEndpoint!.name}' \\ - --header 'Authorization: Bearer ${token || 'YOUR_TOKEN'}' \\ - --header 'Content-Type: application/json' \\ - --data-raw '{ - "Jason": "json" - }'`} - - - )} - /> + {signalEndpoint ? ( + <> + + You can call your signal endpoint with the newly created + token like this: + + + {`curl --request POST '${ + uiConfig.unleashUrl + }/api/signal-endpoint/${signalEndpoint!.name}' \\ +--header 'Authorization: Bearer ${token || 'YOUR_TOKEN'}' \\ +--header 'Content-Type: application/json' \\ +--data-raw '{ +"Jason": "json" +}'`} + + + ) : null} ); }; diff --git a/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsModal.tsx b/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsModal.tsx index 3f25780d2410..8dd41725a786 100644 --- a/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsModal.tsx +++ b/frontend/src/component/signals/SignalEndpointsModal/SignalEndpointsModal.tsx @@ -17,7 +17,6 @@ import { TokenGeneration, useSignalEndpointsForm, } from './SignalEndpointsForm/useSignalEndpointsForm'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; const StyledHeader = styled('div')(({ theme }) => ({ display: 'flex', @@ -162,10 +161,9 @@ export const SignalEndpointsModal = ({ > {title} - View signals} - /> + {editing ? ( + View signals + ) : null} import('component/common/ReactJSONEditor/ReactJSONEditor'), @@ -146,25 +145,17 @@ export const SignalEndpointsSignalsModal = ({ )} listEnd={ - - Load more - - } - /> - } - /> - - No signals have been received on this signal - endpoint. -

    + hasMore ? ( + + ) : null } /> + {signalEndpointSignals.length === 0 ? ( +

    + No signals have been received on this signal + endpoint. +

    + ) : null} - } - /> + {!hasSubmittedFeedback ? ( + + ) : null} { - <> { headerGroups={headerGroups} prepareRow={prepareRow} /> - - No signal endpoints available. Get started by - adding one. - - } - /> + {rows.length === 0 ? ( + + No signal endpoints available. Get started by adding + one. + + ) : null} { const smallScreen = useMediaQuery('(max-width:700px)'); const navigate = useNavigate(); - return ( - navigate('/strategies/create')} - permission={CREATE_STRATEGY} - size='large' - tooltipProps={{ title: 'New custom strategy' }} - > - - - } - elseShow={ - navigate('/strategies/create')} - color='primary' - permission={CREATE_STRATEGY} - data-testid={ADD_NEW_STRATEGY_ID} - > - New custom strategy - - } - /> + return smallScreen ? ( + navigate('/strategies/create')} + permission={CREATE_STRATEGY} + size='large' + tooltipProps={{ title: 'New custom strategy' }} + > + + + ) : ( + navigate('/strategies/create')} + color='primary' + permission={CREATE_STRATEGY} + data-testid={ADD_NEW_STRATEGY_ID} + > + New custom strategy + ); }; diff --git a/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx b/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx index 0ee82dba8ea0..2642f38db362 100644 --- a/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx +++ b/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx @@ -11,7 +11,6 @@ import { TablePlaceholder, } from 'component/common/Table'; import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { Dialogue } from 'component/common/Dialogue/Dialogue'; @@ -284,14 +283,11 @@ export const StrategiesList = () => { subtitle={description} to={`/strategies/${name}`} > - ( - - Disabled - - )} - /> + {deprecated ? ( + + Disabled + + ) : null} ); }, @@ -307,24 +303,19 @@ export const StrategiesList = () => { deprecated={original.deprecated} onToggle={onToggle(original)} /> - - - onEditStrategy(original)} - /> - - onDeleteStrategy(original) - } - /> - - } - /> + {original.editable ? ( + <> + + onEditStrategy(original)} + /> + onDeleteStrategy(original)} + /> + + ) : null} ), width: 150, @@ -420,14 +411,11 @@ export const StrategiesList = () => { })} - - No strategies available. - - } - /> + {rows.length === 0 ? ( + + No strategies available. + + ) : null} { })} - } - /> + {customRows.length === 0 ? : null} = ({ }) => { const id = useId(); - return ( - - - - } - elseShow={ - -
    - - - -
    -
    - } - /> + return strategy?.editable ? ( + + + + ) : ( + +
    + + + +
    +
    ); }; diff --git a/frontend/src/component/strategies/StrategiesList/StrategyEditButton/StrategyEditButton.tsx b/frontend/src/component/strategies/StrategiesList/StrategyEditButton/StrategyEditButton.tsx index c973057e27b5..f3f44acf163a 100644 --- a/frontend/src/component/strategies/StrategiesList/StrategyEditButton/StrategyEditButton.tsx +++ b/frontend/src/component/strategies/StrategiesList/StrategyEditButton/StrategyEditButton.tsx @@ -1,5 +1,4 @@ import type { VFC } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import Edit from '@mui/icons-material/Edit'; import { IconButton, Tooltip } from '@mui/material'; @@ -18,27 +17,21 @@ export const StrategyEditButton: VFC = ({ }) => { const id = useId(); - return ( - - - - } - elseShow={ - -
    - - - -
    -
    - } - /> + return strategy?.editable ? ( + + + + ) : ( + +
    + + + +
    +
    ); }; diff --git a/frontend/src/component/strategies/StrategyForm/StrategyParameters/StrategyParameter/StrategyParameter.tsx b/frontend/src/component/strategies/StrategyForm/StrategyParameters/StrategyParameter/StrategyParameter.tsx index c8af669e60ca..749793597f1a 100644 --- a/frontend/src/component/strategies/StrategyForm/StrategyParameters/StrategyParameter/StrategyParameter.tsx +++ b/frontend/src/component/strategies/StrategyForm/StrategyParameters/StrategyParameter/StrategyParameter.tsx @@ -10,7 +10,6 @@ import { import Delete from '@mui/icons-material/Delete'; import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect'; import Input from 'component/common/Input/Input'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type React from 'react'; import type { IStrategyParameter } from 'interfaces/strategy'; @@ -104,23 +103,20 @@ export const StrategyParameter = ({ return ( - - Parameters let you provide arguments to your strategy - that it can access for evaluation. Read more in the{' '} - - parameter types documentation - - . - - } - /> + {index === 0 ? ( + + Parameters let you provide arguments to your strategy that + it can access for evaluation. Read more in the{' '} + + parameter types documentation + + . + + ) : null} 0) { return params.map(({ name, type, description, required }, i) => ( - - - - - - } - elseShow={ - - - - - - } - /> + {required ? ( + + + + + + ) : ( + + + + + + )} @@ -65,16 +60,13 @@ export const StrategyDetails = ({ return (
    - -
    - Deprecated -
    -
    - } - /> + {strategy.deprecated ? ( + +
    + Deprecated +
    +
    + ) : null}
    Parameters

    diff --git a/frontend/src/component/strategies/StrategyView/StrategyView.tsx b/frontend/src/component/strategies/StrategyView/StrategyView.tsx index b783ec8bccf3..0c7f8b8e558a 100644 --- a/frontend/src/component/strategies/StrategyView/StrategyView.tsx +++ b/frontend/src/component/strategies/StrategyView/StrategyView.tsx @@ -8,7 +8,6 @@ import { StrategyDetails } from './StrategyDetails/StrategyDetails'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import Edit from '@mui/icons-material/Edit'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; export const StrategyView = () => { @@ -31,19 +30,16 @@ export const StrategyView = () => { title={strategy?.name} subtitle={strategy?.description} actions={ - - - - } - /> + strategy.editable ? ( + + + + ) : null } /> } diff --git a/frontend/src/component/strategies/TogglesLinkList/TogglesLinkList.tsx b/frontend/src/component/strategies/TogglesLinkList/TogglesLinkList.tsx index 59df446bd891..de66d26433de 100644 --- a/frontend/src/component/strategies/TogglesLinkList/TogglesLinkList.tsx +++ b/frontend/src/component/strategies/TogglesLinkList/TogglesLinkList.tsx @@ -9,7 +9,6 @@ import Pause from '@mui/icons-material/Pause'; import PlayArrow from '@mui/icons-material/PlayArrow'; import styles from 'component/common/common.module.scss'; import { Link } from 'react-router-dom'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { FeatureSchema } from 'openapi'; interface ITogglesLinkListProps { @@ -18,24 +17,19 @@ interface ITogglesLinkListProps { export const TogglesLinkList = ({ toggles }: ITogglesLinkListProps) => ( - 0} - show={toggles.map(({ name, description = '-', enabled }) => ( + {toggles.length > 0 ? ( + toggles.map(({ name, description = '-', enabled }) => ( - - - - } - elseShow={ - - - - } - /> + {enabled ? ( + + + + ) : ( + + + + )} ( secondary={description} /> - ))} - /> + )) + ) : ( + + + + )} ); diff --git a/frontend/src/component/tags/TagTypeList/AddTagTypeButton/AddTagTypeButton.tsx b/frontend/src/component/tags/TagTypeList/AddTagTypeButton/AddTagTypeButton.tsx index 80f33171ee5d..345422c749e1 100644 --- a/frontend/src/component/tags/TagTypeList/AddTagTypeButton/AddTagTypeButton.tsx +++ b/frontend/src/component/tags/TagTypeList/AddTagTypeButton/AddTagTypeButton.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import PermissionButton from 'component/common/PermissionButton/PermissionButton'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import { CREATE_TAG_TYPE } from 'component/providers/AccessProvider/permissions'; @@ -11,26 +10,20 @@ export const AddTagTypeButton = () => { const navigate = useNavigate(); const smallScreen = useMediaQuery('(max-width:700px)'); - return ( - navigate('/tag-types/create')} - size='large' - permission={CREATE_TAG_TYPE} - > - - - } - elseShow={ - navigate('/tag-types/create')} - > - New tag type - - } - /> + return smallScreen ? ( + navigate('/tag-types/create')} + size='large' + permission={CREATE_TAG_TYPE} + > + + + ) : ( + navigate('/tag-types/create')} + > + New tag type + ); }; diff --git a/frontend/src/component/tags/TagTypeList/TagTypeList.tsx b/frontend/src/component/tags/TagTypeList/TagTypeList.tsx index 98f096a036f3..b4e4c83ec234 100644 --- a/frontend/src/component/tags/TagTypeList/TagTypeList.tsx +++ b/frontend/src/component/tags/TagTypeList/TagTypeList.tsx @@ -14,7 +14,6 @@ import Edit from '@mui/icons-material/Edit'; import Label from '@mui/icons-material/Label'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { PageContent } from 'component/common/PageContent/PageContent'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { DELETE_TAG_TYPE, UPDATE_TAG_TYPE, @@ -223,26 +222,27 @@ export const TagTypeList = () => { - 0} - show={ - - No tags found matching “ - {globalFilter} - ” - - } - elseShow={ - - No tags available. Get started by adding one. - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No tags found matching “ + {globalFilter} + ” + + } + elseShow={ + + No tags available. Get started by adding one. + + } + /> + ) : ( + + No tags available. Get started by adding one. + + )} - } - /> + {!authDetails.defaultHidden ? : null} ); } else if (authDetails.type === SIMPLE_TYPE) { @@ -72,10 +68,7 @@ const Authentication = ({ content = ( <> - } - /> + {!authDetails.defaultHidden ? : null} ); } else { @@ -85,10 +78,7 @@ const Authentication = ({ return ( <>
    - {error}} - /> + {error ? {error} : null}
    {content} diff --git a/frontend/src/component/user/ForgottenPassword/ForgottenPassword.tsx b/frontend/src/component/user/ForgottenPassword/ForgottenPassword.tsx index 7c5ba26d40c8..9ff4677c78e4 100644 --- a/frontend/src/component/user/ForgottenPassword/ForgottenPassword.tsx +++ b/frontend/src/component/user/ForgottenPassword/ForgottenPassword.tsx @@ -5,7 +5,6 @@ import { Link } from 'react-router-dom'; import useLoading from 'hooks/useLoading'; import { FORGOTTEN_PASSWORD_FIELD } from 'utils/testIds'; import { formatApiPath } from 'utils/formatPath'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import DividerText from 'component/common/DividerText/DividerText'; import StandaloneLayout from '../common/StandaloneLayout'; import { @@ -80,31 +79,24 @@ const ForgottenPassword = () => { Forgotten password - - Attempted to send email - We've attempted to send a reset password email to: - {attemptedEmail} - If you did not receive an email, please verify that - you typed in the correct email, and contact your - administrator to make sure that you are in the - system. - - } - /> - - - Too many password reset attempts - - Please wait another minute before your next attempt - - } - /> + {state === 'attempted' ? ( + + Attempted to send email + We've attempted to send a reset password email to: + {attemptedEmail} + If you did not receive an email, please verify that you + typed in the correct email, and contact your + administrator to make sure that you are in the system. + + ) : null} + {state === 'too_many_attempts' ? ( + + + Too many password reset attempts + + Please wait another minute before your next attempt + + ) : null} Please provide your email address. If it exists in the @@ -129,11 +121,11 @@ const ForgottenPassword = () => { color='primary' disabled={state === 'loading'} > - Submit} - elseShow={Try again} - /> + {state === 'initial' ? ( + Submit + ) : ( + Try again + )} - - - } - /> - ); + + setUsername(evt.target.value)} + value={username} + error={Boolean(usernameError)} + helperText={usernameError} + autoComplete='username' + data-testid={LOGIN_EMAIL_ID} + variant='outlined' + size='small' + autoFocus + /> + setPassword(evt.target.value)} + name='password' + id='password' + value={password} + error={Boolean(passwordError)} + helperText={passwordError} + autoComplete='off' + data-testid={LOGIN_PASSWORD_ID} + /> + + + + ) : null; }; const { options = [] } = authDetails; return ( <> - 0} - show={ - <> - - - } - /> - {renderLoginForm()} - - } - elseShow={renderLoginForm()} - /> + {options.length > 0 ? ( + <> + + {!authDetails.defaultHidden ? ( + + ) : null} + {renderLoginForm()} + + ) : ( + renderLoginForm() + )} ); }; diff --git a/frontend/src/component/user/Profile/PasswordTab/PasswordTab.tsx b/frontend/src/component/user/Profile/PasswordTab/PasswordTab.tsx index 89b4d3f42c5f..7c1debb19a66 100644 --- a/frontend/src/component/user/Profile/PasswordTab/PasswordTab.tsx +++ b/frontend/src/component/user/Profile/PasswordTab/PasswordTab.tsx @@ -1,5 +1,4 @@ import { Alert, Button, styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import PasswordField from 'component/common/PasswordField/PasswordField'; import PasswordChecker, { @@ -84,74 +83,70 @@ export const PasswordTab = () => { return ( - - Password based login is currently disabled for your - Unleash instance. - - } - elseShow={ - - - , - ) => setOldPassword(e.target.value)} - /> - , - ) => setPassword(e.target.value)} - /> - , - ) => setConfirmPassword(e.target.value)} - /> - - - - } - /> + {simpleAuthConfig.disabled ? ( + + Password based login is currently disabled for your Unleash + instance. + + ) : ( + + + ) => + setOldPassword(e.target.value) + } + /> + ) => + setPassword(e.target.value) + } + /> + ) => + setConfirmPassword(e.target.value) + } + /> + + + + )} ); }; diff --git a/frontend/src/component/user/Profile/PersonalAPITokensTab/CreatePersonalAPIToken/PersonalAPITokenForm/PersonalAPITokenForm.tsx b/frontend/src/component/user/Profile/PersonalAPITokensTab/CreatePersonalAPIToken/PersonalAPITokenForm/PersonalAPITokenForm.tsx index 560c4b2568d1..3dd3d41de3bc 100644 --- a/frontend/src/component/user/Profile/PersonalAPITokensTab/CreatePersonalAPIToken/PersonalAPITokenForm/PersonalAPITokenForm.tsx +++ b/frontend/src/component/user/Profile/PersonalAPITokensTab/CreatePersonalAPIToken/PersonalAPITokenForm/PersonalAPITokenForm.tsx @@ -2,7 +2,6 @@ import Input from 'component/common/Input/Input'; import SelectMenu from 'component/common/select'; import { formatDateYMD } from 'utils/formatDate'; import { useLocationSettings } from 'hooks/useLocationSettings'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { DateTimePicker } from 'component/common/DateTimePicker/DateTimePicker'; import { Alert, styled, Typography } from '@mui/material'; import { useEffect } from 'react'; @@ -194,61 +193,53 @@ export const PersonalAPITokenForm = ({ } options={expirationOptions} /> - ( - { - clearError(ErrorField.EXPIRES_AT); - if (date < new Date()) { - setError( - ErrorField.EXPIRES_AT, - 'Invalid date, must be in the future', - ); - } - setExpiresAt(date); - }} - min={new Date()} - error={Boolean(errors.expiresAt)} - errorText={errors.expiresAt} - required - /> - )} - elseShow={ - - The token will never{' '} - expire! - + {customExpiration ? ( + { + clearError(ErrorField.EXPIRES_AT); + if (date < new Date()) { + setError( + ErrorField.EXPIRES_AT, + 'Invalid date, must be in the future', + ); } - elseShow={() => ( - - Token will expire on{' '} - - {formatDateYMD( - expiresAt!, - locationSettings.locale, - )} - - - )} - /> - } - /> + setExpiresAt(date); + }} + min={new Date()} + error={Boolean(errors.expiresAt)} + errorText={errors.expiresAt} + required + /> + ) : ( + + The token will never expire! + + } + elseShow={ + + Token will expire on{' '} + + {formatDateYMD( + expiresAt!, + locationSettings.locale, + )} + + + } + /> + )} - - We strongly recommend that you set an expiration date - for your token to help keep your information secure. - - } - /> + {neverExpires ? ( + + We strongly recommend that you set an expiration date for + your token to help keep your information secure. + + ) : null} ); }; diff --git a/frontend/src/component/user/Profile/PersonalAPITokensTab/PersonalAPITokensTab.tsx b/frontend/src/component/user/Profile/PersonalAPITokensTab/PersonalAPITokensTab.tsx index 4b920ce5015a..ec89ec79c351 100644 --- a/frontend/src/component/user/Profile/PersonalAPITokensTab/PersonalAPITokensTab.tsx +++ b/frontend/src/component/user/Profile/PersonalAPITokensTab/PersonalAPITokensTab.tsx @@ -9,7 +9,6 @@ import { useMediaQuery, useTheme, } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { Search } from 'component/common/Search/Search'; @@ -251,19 +250,16 @@ export const PersonalAPITokensTab = () => { })`} actions={ <> - - - - - } - /> + {!isSmallScreen ? ( + <> + + + + ) : null} - - } - /> - } - /> + {rows.length === 0 ? ( + 0} + show={ + + No tokens found matching “ + {searchValue} + ” + + } + elseShow={ + + + You have no personal API tokens yet. + + + Need an API token for scripts or testing? Create + a personal API token for quick access to the + Unleash API. + + + + } + /> + ) : ( + + + You have no personal API tokens yet. + + + Need an API token for scripts or testing? Create a + personal API token for quick access to the Unleash API. + + + + )} { return ( - } - /> - } - /> - } - /> + {tab === 'profile' ? : null} + {tab === 'password' ? : null} + {tab === 'pat' ? : null} ); }; diff --git a/frontend/src/component/user/Profile/ProfileTab/ProfileTab.tsx b/frontend/src/component/user/Profile/ProfileTab/ProfileTab.tsx index f1a1ff564108..ab77cdb69e7c 100644 --- a/frontend/src/component/user/Profile/ProfileTab/ProfileTab.tsx +++ b/frontend/src/component/user/Profile/ProfileTab/ProfileTab.tsx @@ -17,7 +17,6 @@ import type { IUser } from 'interfaces/user'; import TopicOutlinedIcon from '@mui/icons-material/TopicOutlined'; import { useNavigate } from 'react-router-dom'; import { PageContent } from 'component/common/PageContent/PageContent'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { RoleBadge } from 'component/common/RoleBadge/RoleBadge'; const StyledHeader = styled('div')(({ theme }) => ({ @@ -136,25 +135,21 @@ export const ProfileTab = ({ user }: IProfileTabProps) => { Access - ( - <> - - Your root role - - - {profile?.rootRole.name} - - - )} - /> + {profile?.rootRole ? ( + <> + + Your root role + + + {profile?.rootRole.name} + + + ) : null} Projects - ( + {profile?.projects.length ? ( + profile?.projects.map((project) => ( { {project} - ))} - elseShow={ - - No projects - - } - /> + )) + ) : ( + + No projects + + )} diff --git a/frontend/src/component/user/ResetPassword/ResetPassword.tsx b/frontend/src/component/user/ResetPassword/ResetPassword.tsx index 51b895688810..7e8ca9ccd97f 100644 --- a/frontend/src/component/user/ResetPassword/ResetPassword.tsx +++ b/frontend/src/component/user/ResetPassword/ResetPassword.tsx @@ -3,7 +3,6 @@ import { useNavigate } from 'react-router-dom'; import { OK } from 'constants/statusCodes'; import useLoading from 'hooks/useLoading'; import { styled, Typography } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import InvalidToken from '../common/InvalidToken/InvalidToken'; import useResetPassword from 'hooks/api/getters/useResetPassword/useResetPassword'; import StandaloneLayout from '../common/StandaloneLayout'; @@ -57,22 +56,18 @@ const ResetPassword = () => {
    - } - elseShow={ - <> - - Reset password - + {!isValidToken || passwordDisabled ? ( + + ) : ( + <> + + Reset password + - - {apiError} - - - - } - /> + {apiError} + + + )}
    diff --git a/frontend/src/component/user/StandaloneBanner.tsx b/frontend/src/component/user/StandaloneBanner.tsx index 7f1dd34b92f1..17fd02d103de 100644 --- a/frontend/src/component/user/StandaloneBanner.tsx +++ b/frontend/src/component/user/StandaloneBanner.tsx @@ -3,7 +3,6 @@ import { Typography, useTheme, useMediaQuery, styled } from '@mui/material'; import Gradient from 'component/common/Gradient/Gradient'; import { ReactComponent as Logo } from 'assets/icons/logoWhiteBg.svg'; import { ReactComponent as LogoWithText } from 'assets/img/logoWhiteTransparentHorizontal.svg'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { Theme } from '@mui/material'; interface IStandaloneBannerProps { @@ -98,13 +97,12 @@ const StandaloneBanner: FC = ({ title }) => { Committed to creating new ways of developing software - - } - elseShow={} - /> + {smallScreen ? ( + + ) : ( + + )} ); diff --git a/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.tsx b/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.tsx index b428ac4e3f80..de40edc79491 100644 --- a/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.tsx +++ b/frontend/src/component/user/UserProfile/UserProfileContent/UserProfileContent.tsx @@ -1,4 +1,3 @@ -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { Button, Link, Paper, styled } from '@mui/material'; import { basePath } from 'utils/formatPath'; import type { IUser } from 'interfaces/user'; @@ -62,44 +61,40 @@ export const UserProfileContent = ({ showProfile, setShowProfile, profile, -}: IUserProfileContentProps) => ( - - setShowProfile(false)} - > - View profile settings - +}: IUserProfileContentProps) => + showProfile ? ( + + setShowProfile(false)} + > + View profile settings + - + - - Privacy Policy - + + Privacy Policy + - + -
    - - Log out - -
    -
    - } - /> -); +
    + + Log out + +
    + + ) : null; diff --git a/frontend/src/component/user/common/AuthOptions/AuthOptions.tsx b/frontend/src/component/user/common/AuthOptions/AuthOptions.tsx index fc84d8ff24d6..3468071d68a2 100644 --- a/frontend/src/component/user/common/AuthOptions/AuthOptions.tsx +++ b/frontend/src/component/user/common/AuthOptions/AuthOptions.tsx @@ -3,7 +3,6 @@ import classnames from 'classnames'; import { useThemeStyles } from 'themes/themeStyles'; import { ReactComponent as GoogleSvg } from 'assets/icons/google.svg'; import LockRounded from '@mui/icons-material/LockRounded'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import type { IAuthOptions } from 'hooks/api/getters/useAuth/useAuthEndpoint'; import { SSO_LOGIN_BUTTON } from 'utils/testIds'; @@ -34,25 +33,21 @@ const AuthOptions = ({ options }: IAuthOptionProps) => { height: '40px', }} startIcon={ - - } - elseShow={ - - } - /> + o.type === 'google' ? ( + + ) : ( + + ) } > {o.message} diff --git a/frontend/src/component/user/common/InvalidToken/InvalidToken.tsx b/frontend/src/component/user/common/InvalidToken/InvalidToken.tsx index a634e74c7444..6a22ec3398ae 100644 --- a/frontend/src/component/user/common/InvalidToken/InvalidToken.tsx +++ b/frontend/src/component/user/common/InvalidToken/InvalidToken.tsx @@ -4,7 +4,6 @@ import { Link } from 'react-router-dom'; import { INVALID_TOKEN_BUTTON } from 'utils/testIds'; import { useThemeStyles } from 'themes/themeStyles'; import classnames from 'classnames'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useAuthDetails } from 'hooks/api/getters/useAuth/useAuthDetails'; import { useUserInvite } from 'hooks/api/getters/useUserInvite/useUserInvite'; @@ -25,57 +24,51 @@ const InvalidToken: VFC = () => { Invalid token - + {passwordDisabled ? ( + <> + + Your instance does not support password authentication. + Use correct work email to access your account. + + + + ) : ( + - Your instance does not support password - authentication. Use correct work email to access - your account. + Provided invite link is invalid or expired. Please + request a new URL in order to create your account. - - - } - elseShow={ - - Provided invite link is invalid or expired. - Please request a new URL in order to create your - account. + 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. - } - 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. - - - - } - /> - } - /> + + + } + /> + )}
    ); }; diff --git a/frontend/src/component/user/common/ResetPasswordForm/PasswordChecker.tsx b/frontend/src/component/user/common/ResetPasswordForm/PasswordChecker.tsx index e824d7c2a773..2957bdeba820 100644 --- a/frontend/src/component/user/common/ResetPasswordForm/PasswordChecker.tsx +++ b/frontend/src/component/user/common/ResetPasswordForm/PasswordChecker.tsx @@ -4,7 +4,6 @@ import { BAD_REQUEST, OK } from 'constants/statusCodes'; import { useCallback } from 'react'; import { formatApiPath } from 'utils/formatPath'; import { Alert } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { HelpIcon } from 'component/common/HelpIcon/HelpIcon'; interface IPasswordCheckerProps { @@ -242,14 +241,11 @@ const PasswordChecker = ({ - - You may not repeat three characters in a row. - - } - /> + {repeatingCharError ? ( + + You may not repeat three characters in a row. + + ) : null} ); diff --git a/frontend/src/component/user/common/ResetPasswordForm/PasswordMatcher.tsx b/frontend/src/component/user/common/ResetPasswordForm/PasswordMatcher.tsx index 9fd7b6df9fe6..9ee122037feb 100644 --- a/frontend/src/component/user/common/ResetPasswordForm/PasswordMatcher.tsx +++ b/frontend/src/component/user/common/ResetPasswordForm/PasswordMatcher.tsx @@ -1,5 +1,4 @@ import { styled } from '@mui/material'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; @@ -43,11 +42,7 @@ const PasswordMatcher = ({ return ( - } - elseShow={} - />{' '} + {error ? : }{' '} {label} ); diff --git a/frontend/src/component/user/common/ResetPasswordForm/ResetPasswordForm.tsx b/frontend/src/component/user/common/ResetPasswordForm/ResetPasswordForm.tsx index 47b9dcd0cbee..0a9df081dadd 100644 --- a/frontend/src/component/user/common/ResetPasswordForm/ResetPasswordForm.tsx +++ b/frontend/src/component/user/common/ResetPasswordForm/ResetPasswordForm.tsx @@ -1,7 +1,6 @@ import { Button, styled } from '@mui/material'; import type React from 'react'; import { type SyntheticEvent, useCallback, useEffect, useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import PasswordChecker from './PasswordChecker'; import PasswordMatcher from './PasswordMatcher'; import PasswordField from 'component/common/PasswordField/PasswordField'; @@ -82,17 +81,13 @@ const ResetPasswordForm = ({ onSubmit }: IResetPasswordProps) => { autoComplete='new-password' data-loading /> - - } - /> - + {showPasswordChecker ? ( + + ) : null}