Skip to content

Commit

Permalink
Merge pull request #36 from platformatic/bugfix/configure-services-re…
Browse files Browse the repository at this point in the history
…work-forms

Bugfix/configure services rework forms
  • Loading branch information
tonysnowboardunderthebridge authored Nov 30, 2023
2 parents ae8b388 + e353aa5 commit d2ae1e6
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 82 deletions.
17 changes: 15 additions & 2 deletions __mocks__/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ function getRandomInt (min, max) {

export const getTemplates = async () => {
return mockedTemplates.map(template => ({
...template,
envVars: Array.from(new Array(getRandomInt(1, mockedEnvList.length)).keys()).map(() => mockedEnvList[Math.floor(Math.random() * mockedEnvList.length)])
...template
// venvVars: Array.from(new Array(getRandomInt(1, mockedEnvList.length)).keys()).map(() => mockedEnvList[Math.floor(Math.random() * mockedEnvList.length)])
}))
}

Expand All @@ -22,3 +22,16 @@ export const getPlugins = async () => {
envVars: [...mockedVars]
}))
}

export const prepareFolder = async (_path, templates) => {
const pro = new Promise((resolve) => {
setTimeout(() => {
const ret = {}
templates.forEach(template => {
ret[`${template}`] = Array.from(new Array(getRandomInt(1, mockedEnvList.length)).keys()).map(() => mockedEnvList[Math.floor(Math.random() * mockedEnvList.length)])
})
return resolve(ret)
}, 2000)
})
return pro
}
6 changes: 2 additions & 4 deletions src/renderer/src/components/steps/GeneratingApplication.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,12 @@ function StepCreation ({ step, index, concludedStep, /* startTime = 0, endTime =

const GeneratingApplication = React.forwardRef(({ onClickComplete }, ref) => {
const globalState = useStackablesStore()
const { formData, services } = globalState
const { formData } = globalState

useEffect(() => {
async function generateApplication () {
try {
console.log('let\'scall createApp')
const obj = { projectName: formData.createApplication.application, services, ...formData.configureApplication }
console.log(`prjectDir: ${formData.createApplication.path}`)
const obj = { projectName: formData.createApplication.application, services: formData.configuredServices.services, ...formData.configureApplication }
console.log(obj)
} catch (error) {
console.log(`Error on prepareFolder ${error}`)
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/components/steps/PrepareFolder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const PrepareFolder = React.forwardRef(({ onNext }, ref) => {
})
setFolderPrepared(true)
} catch (error) {
console.log(`Error on prepareFolder ${error}`)
console.error(`Error on prepareFolder ${error}`)
}
}
prepareFolder()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,45 @@
'use strict'
import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import styles from './ConfigureEnvVarsTemplateAndPlugins.module.css'
import commonStyles from '~/styles/CommonStyles.module.css'
import TemplateAndPluginTreeSelector from '~/components/template-and-plugins/TemplateAndPluginTreeSelector'
import { CSSTransition } from 'react-transition-group'
import TemplateEnvVarsForm from '~/components/templates/TemplateEnvVarsForm'
import PluginEnvVarsForm from '~/components/plugins/PluginEnvVarsForm'
import useStackablesStore from '~/useStackablesStore'
import '~/components/component.animation.css'

function ConfigureEnvVarsTemplateAndPlugins () {
const globalState = useStackablesStore()
const { services } = globalState

const [serviceSelected, setServiceSelected] = useState(services[0])
function ConfigureEnvVarsTemplateAndPlugins ({
configuredServices,
handleChangeTemplateForm
}) {
const [serviceSelected, setServiceSelected] = useState(null)
const [pluginSelected, setPluginSelected] = useState(null)
const [currentComponent, setCurrentComponent] = useState(<></>)

useEffect(() => {
if (configuredServices !== null) {
setServiceSelected(configuredServices[0])
}
}, [configuredServices])

function handleChangeTemplateEnvVars (event) {
return handleChangeTemplateForm(event, serviceSelected.template, serviceSelected.name)
}

useEffect(() => {
if (serviceSelected) {
if (pluginSelected) {
setCurrentComponent(<PluginEnvVarsForm service={{ ...serviceSelected }} plugin={{ ...pluginSelected }} key={pluginSelected.name} />)
} else {
setCurrentComponent(<TemplateEnvVarsForm key={serviceSelected.name} service={{ ...serviceSelected }} />)
setCurrentComponent(
<TemplateEnvVarsForm
key={`${serviceSelected.name}-${serviceSelected.template}-${serviceSelected.updatedAt}`}
configuredServices={configuredServices}
serviceName={serviceSelected.name}
templateName={serviceSelected.template}
onChange={handleChangeTemplateEnvVars}
/>)
}
}
}, [serviceSelected, pluginSelected])
Expand Down Expand Up @@ -58,4 +75,21 @@ function ConfigureEnvVarsTemplateAndPlugins () {
)
}

ConfigureEnvVarsTemplateAndPlugins.propTypes = {
/**
* configuredServices
*/
configuredServices: PropTypes.array,
/**
* handleChangeTemplateForm
*/
handleChangeTemplateForm: PropTypes.func

}

ConfigureEnvVarsTemplateAndPlugins.defaultProps = {
configuredServices: [],
handleChangeTemplateForm: () => {}
}

export default ConfigureEnvVarsTemplateAndPlugins
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict'
import React from 'react'
import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import styles from './ConfigureServices.module.css'
import commonStyles from '~/styles/CommonStyles.module.css'
Expand All @@ -13,9 +13,75 @@ import ConfigureEnvVarsTemplateAndPlugins from './ConfigureEnvVarsTemplateAndPlu

const ConfigureServices = React.forwardRef(({ onNext }, ref) => {
const globalState = useStackablesStore()
const { formData, addFormData } = globalState
const { formData, addFormData, services } = globalState
const [disabled, setDisabled] = useState(true)
const [configuredServices, setConfiguredServices] = useState([])

useEffect(() => {
if (services.length > 0) {
let tmpTemplateForms = {}
let tmpTemplateValidations = {}
let tmpTemplateValidForm = {}
let tmpObj = {}
services.forEach(service => {
tmpTemplateForms = {}
tmpTemplateValidations = {}
tmpTemplateValidForm = {}
tmpObj = {}

tmpObj.name = service.name
tmpObj.template = service.template.name
let form
let validations
let formErrors

if (service.template.envVars.length > 0) {
form = {}
validations = {}
formErrors = {}
service.template.envVars.forEach(envVar => {
const { var: envName, configValue, type, default: envDefault, label } = envVar
form[envName] = {
label,
var: envName,
value: envDefault || '',
configValue,
type
}
validations[`${envName}Valid`] = envDefault !== ''
formErrors[envName] = ''
})
tmpTemplateForms = { ...form }
tmpTemplateValidations = { ...validations, formErrors }
tmpTemplateValidForm = Object.keys(validations).findIndex(element => validations[element] === false) === -1
}
tmpObj.form = { ...tmpTemplateForms }
tmpObj.validations = { ...tmpTemplateValidations }
tmpObj.validForm = tmpTemplateValidForm
tmpObj.updatedAt = new Date().toISOString()
})
setConfiguredServices([...configuredServices, tmpObj])
}
}, [services])

useEffect(() => {
if (configuredServices) {
setDisabled(configuredServices.find(configuredService => configuredService.validForm === false) !== undefined)
}
}, [configuredServices])

function onClickConfigureApplication () {
const services = configuredServices.map(({ name, template, form }) => ({
name,
template,
fields: Object.keys(form).map(k => {
const { label, ...rest } = form[k]
return { ...rest }
})
}))
addFormData({
configuredServices: { services }
})
onNext()
}

Expand All @@ -29,6 +95,45 @@ const ConfigureServices = React.forwardRef(({ onNext }, ref) => {
})
}

function handleChangeTemplateForm (event, templateName, serviceName) {
const fieldName = event.target.name
const fieldValue = event.target.value
const { form: newForm, validations: newValidations } = configuredServices.find(configuredService => configuredService.name === serviceName && configuredService.template === templateName)

newForm[fieldName].value = fieldValue

let tmpValid = newValidations[`${fieldName}Valid`]
const formErrors = { ...newValidations.formErrors }
switch (fieldName) {
default:
tmpValid = fieldValue.length > 0 && /^\S+$/g.test(fieldValue)
formErrors[fieldName] = fieldValue.length > 0 ? (tmpValid ? '' : 'The field is not valid, make sure you are using regular characters') : ''
break
}
const nextValidation = { ...newValidations, formErrors }
nextValidation[`${fieldName}Valid`] = tmpValid

const newFormValid = Object.keys(nextValidation).findIndex(element => nextValidation[element] === false) === -1

setConfiguredServices(configuredServices => {
return [...configuredServices.map(configuredService => {
if (configuredService.name === serviceName && configuredService.template === templateName) {
const { form, validations, validForm, ...rest } = configuredService
const newObject = {
form: newForm,
updatedAt: new Date().toISOString(),
validations: nextValidation,
validForm: newFormValid,
...rest
}
return newObject
} else {
return configuredService
}
})]
})
}

return (
<div className={styles.container} ref={ref}>
<div className={commonStyles.largeFlexBlock}>
Expand All @@ -43,12 +148,15 @@ const ConfigureServices = React.forwardRef(({ onNext }, ref) => {
<p className={`${typographyStyles.desktopBodyLarge} ${typographyStyles.textWhite} ${typographyStyles.opacity70}`}>Select a template and plugins for your service from our Stackables Marketplace. Once you have chosen a template you can add another Service.</p>
</div>
<div className={`${commonStyles.mediumFlexBlock} ${commonStyles.fullWidth} ${styles.content}`}>
<ConfigureEnvVarsTemplateAndPlugins />
<ConfigureEnvVarsTemplateAndPlugins
configuredServices={configuredServices}
handleChangeTemplateForm={handleChangeTemplateForm}
/>
</div>
</div>
<div className={`${styles.buttonContainer} ${commonStyles.fullWidth}`}>
<Button
/* disabled={prepareFolder} */
disabled={disabled}
label='Next - Configure Application'
onClick={() => onClickConfigureApplication()}
color={RICH_BLACK}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import useStackablesStore from '~/useStackablesStore'

function TemplateSelector ({ onTemplateSelected, service, serviceSelected }) {
let className = `${typographyStyles.desktopHeadline5} ${typographyStyles.textWhite} ${styles.ellipsisTemplate}`
if (serviceSelected?.template?.name !== service.template.name) {
if (serviceSelected?.template !== service.template.name) {
className += ` ${typographyStyles.opacity70}`
}
return (
Expand Down
Loading

0 comments on commit d2ae1e6

Please sign in to comment.