Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add environment processing UI #4812

Merged
merged 3 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions frontend/common/dispatcher/app-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,10 @@ const AppActions = Object.assign({}, require('./base/_app-actions'), {
pin,
})
},
createEnv(name, projectId, cloneId, description, metadata) {
createEnv(data) {
Dispatcher.handleViewAction({
actionType: Actions.CREATE_ENV,
cloneId,
description,
metadata,
name,
projectId,
...data,
})
},
createFlag(projectId, environmentId, flag, segmentOverrides) {
Expand Down
83 changes: 0 additions & 83 deletions frontend/common/providers/ProjectProvider.js

This file was deleted.

78 changes: 78 additions & 0 deletions frontend/common/providers/ProjectProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { FC, ReactNode, useEffect, useState } from 'react'
import OrganisationStore from 'common/stores/organisation-store'
import AppActions from 'common/dispatcher/app-actions'
import { Environment, Metadata, Project } from 'common/types/responses'
import ProjectStore from 'common/stores/project-store'
export type CreateEnvType = (data: {
name: string
projectId: string
cloneId?: string
description?: string
cloneFeatureStatesAsync?: boolean
metadata: Environment['metadata']
}) => void
export type ProjectProviderType = {
children: (props: {
createEnv: CreateEnvType
deleteEnv: typeof AppActions.deleteEnv
deleteProject: typeof AppActions.deleteProject
editEnv: typeof AppActions.editEnv
editProject: typeof AppActions.editProject
error: any
isLoading: boolean
isSaving: boolean
project: Project | null
}) => ReactNode
id?: string
onRemove?: () => void
onRemoveEnvironment?: (environment: Environment) => void
onSave?: (environment: Environment) => void
}

const ProjectProvider: FC<ProjectProviderType> = ({
children,
id,
onRemove,
onRemoveEnvironment,
onSave,
}) => {
const [_, setUpdated] = useState(Date.now())

useEffect(() => {
const _onChange = () => setUpdated(Date.now)
const _onRemove = () => onRemove?.()
const _onRemoveEnvironment = (environment: Environment) =>
onRemoveEnvironment?.(environment)
// @ts-ignore
const _onSave = () => onSave?.(ProjectStore.savedEnv)
OrganisationStore.on('removed', _onRemove)
ProjectStore.on('change', _onChange)
ProjectStore.on('removed', _onRemoveEnvironment)
ProjectStore.on('saved', _onSave)
return () => {
OrganisationStore.off('removed', _onRemove)
ProjectStore.off('change', _onChange)
ProjectStore.off('removed', _onRemoveEnvironment)
ProjectStore.off('saved', _onSave)
}
//eslint-disable-next-line
}, [])

return (
<>
{children({
createEnv: AppActions.createEnv,
deleteEnv: AppActions.deleteEnv,
deleteProject: AppActions.deleteProject,
editEnv: AppActions.editEnv,
editProject: AppActions.editProject,
error: ProjectStore.error,
isLoading: !ProjectStore.getEnvs() || ProjectStore.id !== id,
isSaving: ProjectStore.isSaving,
project: ProjectStore.model || null,
})}
</>
)
}

export default ProjectProvider
1 change: 1 addition & 0 deletions frontend/common/stores/base/_store.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = Object.assign({}, EventEmitter.prototype, {
// console.log('change', this.id)
this.trigger(DEFAULT_CHANGE_EVENT)
},
error: null,
goneABitWest() {
this.hasLoaded = true
this.isLoading = false
Expand Down
18 changes: 10 additions & 8 deletions frontend/common/stores/project-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ const BaseStore = require('./base/_store')
const data = require('../data/base/_data')

const controller = {
createEnv: (name, projectId, cloneId, description, metadata) => {
createEnv: ({
cloneFeatureStatesAsync,
cloneId,
description,
metadata,
name,
projectId,
}) => {
API.trackEvent(Constants.events.CREATE_ENVIRONMENT)
store.saving()
const req = cloneId
? data.post(`${Project.api}environments/${cloneId}/clone/`, {
clone_feature_states_async: cloneFeatureStatesAsync,
description,
name,
})
Expand Down Expand Up @@ -257,13 +265,7 @@ store.dispatcherIndex = Dispatcher.register(store, (payload) => {
controller.getProject(action.projectId)
break
case Actions.CREATE_ENV:
controller.createEnv(
action.name,
action.projectId,
action.cloneId,
action.description,
action.metadata,
)
controller.createEnv(action)
break
case Actions.EDIT_ENVIRONMENT:
controller.editEnv(action.env)
Expand Down
1 change: 1 addition & 0 deletions frontend/common/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export type Segment = {
export type Environment = {
id: number
name: string
is_creating: boolean
api_key: string
description?: string
banner_text?: string
Expand Down
42 changes: 42 additions & 0 deletions frontend/web/components/EnvironmentReadyChecker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { FC } from 'react'
import { useGetEnvironmentQuery } from 'common/services/useEnvironment'

type EnvironmentReadyCheckerType = {
match: {
params: {
environmentId?: string
}
}
}

const EnvironmentReadyChecker: FC<EnvironmentReadyCheckerType> = ({
children,
match,
}) => {
const { data, isLoading } = useGetEnvironmentQuery(
{
id: match.params.environmentId,
},
{ pollingInterval: 1000, skip: !match.params.environmentId },
)
if (!match?.params?.environmentId) {
return children
}
return isLoading ? (
<div className='text-center'>
<Loader />
</div>
) : data?.is_creating ? (
<div className='container'>
<div className='d-flex flex-column h-100 flex-1 justify-content-center align-items-center'>
<Loader />
<h3>Preparing your environment</h3>
<p>We are setting up your new environment...</p>
</div>
</div>
) : (
children
)
}

export default EnvironmentReadyChecker
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import NotFoundPage from 'components/pages/NotFoundPage'
import React from 'react'
import { RouteComponentProps, Route } from 'react-router-dom'
import EnvironmentReadyChecker from 'components/EnvironmentReadyChecker'

type ParameterizedRouteType = {
component: React.ComponentType<any>
Expand Down Expand Up @@ -32,17 +33,26 @@ export const ParameterizedRoute = ({
<Route
{...props}
render={(componentProps: RouteComponentProps) => (
<Component
{...componentProps}
<EnvironmentReadyChecker
match={{
...componentProps.match,
params: {
...componentProps.match.params,
...(organisationId && { organisationId: parsedOrganisationId }),
...(projectId && { projectId: parsedProjectId }),
environmentId: componentProps.match.params.environmentId,
},
}}
/>
>
<Component
{...componentProps}
match={{
...componentProps.match,
params: {
...componentProps.match.params,
...(organisationId && { organisationId: parsedOrganisationId }),
...(projectId && { projectId: parsedProjectId }),
},
}}
/>
</EnvironmentReadyChecker>
)}
/>
)
Expand Down
Loading
Loading