1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

feat: welcome to your project component (#8039)

Currently displaying always when flag enabled.


![image](https://github.com/user-attachments/assets/e4c48595-b2d9-4093-af98-360d5856e7d5)
This commit is contained in:
Jaanus Sellin 2024-09-02 15:09:00 +03:00 committed by GitHub
parent bd25bb633d
commit e4fcb252d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 158 additions and 4 deletions

View File

@ -39,6 +39,9 @@ import {
useProjectFeatureSearchActions,
} from './useProjectFeatureSearch';
import { AvatarCell } from './AvatarCell';
import { ProjectOnboarding } from './ProjectOnboarding/ProjectOnboarding';
import { useUiFlag } from 'hooks/useUiFlag';
import { styled } from '@mui/material';
interface IPaginatedProjectFeatureTogglesProps {
environments: string[];
@ -50,9 +53,16 @@ const formatEnvironmentColumnId = (environment: string) =>
const columnHelper = createColumnHelper<FeatureSearchResponseSchema>();
const getRowId = (row: { name: string }) => row.name;
const Container = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
}));
export const ProjectFeatureToggles = ({
environments,
}: IPaginatedProjectFeatureTogglesProps) => {
const onboardingUIEnabled = useUiFlag('onboardingUI');
const projectId = useRequiredPathParam('projectId');
const {
@ -383,7 +393,11 @@ export const ProjectFeatureToggles = ({
const selectedData = useSelectedData(features, rowSelection);
return (
<>
<Container>
<ConditionallyRender
condition={onboardingUIEnabled}
show={<ProjectOnboarding projectId={projectId} />}
/>
<PageContent
disableLoading
disablePadding
@ -486,6 +500,6 @@ export const ProjectFeatureToggles = ({
onChange={refetch}
/>
</BatchSelectionActionsBar>
</>
</Container>
);
};

View File

@ -41,7 +41,7 @@ const StyledResponsiveButton = styled(ResponsiveButton)(() => ({
whiteSpace: 'nowrap',
}));
const FlagCreationButton: FC = () => {
export const FlagCreationButton: FC = () => {
const [searchParams] = useSearchParams();
const projectId = useRequiredPathParam('projectId');
const showCreateDialog = Boolean(searchParams.get('create'));

View File

@ -0,0 +1,28 @@
import { styled } from '@mui/material';
import { WelcomeToProject } from './WelcomeToProject';
interface IProjectOnboardingProps {
projectId: string;
}
const Container = styled('div')(({ theme }) => ({
display: 'flex',
width: '100%',
gap: theme.spacing(2),
}));
const SdkExample = styled('div')(({ theme }) => ({
flexBasis: '30%',
padding: theme.spacing(2),
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadiusLarge,
}));
export const ProjectOnboarding = ({ projectId }: IProjectOnboardingProps) => {
return (
<Container>
<WelcomeToProject projectId={projectId} />
<SdkExample>View SDK example</SdkExample>
</Container>
);
};

View File

@ -0,0 +1,104 @@
import { styled, Typography } from '@mui/material';
import Add from '@mui/icons-material/Add';
import { CREATE_FEATURE } from 'component/providers/AccessProvider/permissions';
import { FlagCreationButton } from '../ProjectFeatureTogglesHeader/ProjectFeatureTogglesHeader';
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
interface IWelcomeToProjectProps {
projectId: string;
}
const Container = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
backgroundColor: theme.palette.background.paper,
flexBasis: '70%',
borderRadius: theme.shape.borderRadiusLarge,
}));
const TitleBox = styled('div')(({ theme }) => ({
padding: theme.spacing(2, 7, 2, 7),
borderBottom: '1px solid',
borderColor: theme.palette.divider,
}));
const Actions = styled('div')(({ theme }) => ({
display: 'flex',
flexGrow: 1,
}));
const ActionBox = styled('div')(({ theme }) => ({
flexBasis: '50%',
padding: theme.spacing(3, 2, 6, 8),
display: 'flex',
gap: theme.spacing(3),
flexDirection: 'column',
}));
const TitleContainer = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'row',
gap: theme.spacing(2),
alignItems: 'center',
fontSize: theme.spacing(1.75),
fontWeight: 'bold',
}));
const CircleContainer = styled('span')(({ theme }) => ({
width: '28px',
height: '28px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: theme.palette.neutral.border,
borderRadius: '50%',
}));
export const WelcomeToProject = ({ projectId }: IWelcomeToProjectProps) => {
return (
<Container>
<TitleBox>
<Typography fontWeight='bold'>
Welcome to your project
</Typography>
<Typography variant='body2'>
Complete the steps below to start working with this project
</Typography>
</TitleBox>
<Actions>
<ActionBox>
<TitleContainer>
<CircleContainer>1</CircleContainer>
Create a feature flag
</TitleContainer>
<Typography>
<div>
The project currently holds no feature toggles.
</div>
<div>Create a feature flag to get started.</div>
</Typography>
<FlagCreationButton />
</ActionBox>
<ActionBox>
<TitleContainer>
<CircleContainer>2</CircleContainer>
Connect an SDK
</TitleContainer>
<Typography>
We have not detected any connected SDKs on this project.
</Typography>
<ResponsiveButton
onClick={() => {}}
maxWidth='200px'
projectId={projectId}
Icon={Add}
disabled={true}
permission={CREATE_FEATURE}
>
Connect SDK
</ResponsiveButton>
</ActionBox>
</Actions>
</Container>
);
};

View File

@ -89,6 +89,7 @@ export type UiFlags = {
newEventSearch?: boolean;
archiveProjects?: boolean;
projectListImprovements?: boolean;
onboardingUI?: boolean;
};
export interface IVersionInfo {

View File

@ -134,6 +134,7 @@ exports[`should create default config 1`] = `
"navigationSidebar": true,
"newEventSearch": false,
"onboardingMetrics": false,
"onboardingUI": false,
"originMiddleware": false,
"outdatedSdksBanner": false,
"personalAccessTokensKillSwitch": false,

View File

@ -61,7 +61,8 @@ export type IFlagKey =
| 'projectListImprovements'
| 'useProjectReadModel'
| 'addonUsageMetrics'
| 'onboardingMetrics';
| 'onboardingMetrics'
| 'onboardingUI';
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
@ -302,6 +303,10 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_ONBOARDING_METRICS,
false,
),
onboardingUI: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_ONBOARDING_UI,
false,
),
};
export const defaultExperimentalOptions: IExperimentalOptions = {

View File

@ -56,6 +56,7 @@ process.nextTick(async () => {
useProjectReadModel: true,
addonUsageMetrics: true,
onboardingMetrics: true,
onboardingUI: true,
},
},
authentication: {