Skip to content

Commit

Permalink
Merge pull request #50 from platformatic/feature/reworking-on-plugins
Browse files Browse the repository at this point in the history
Feature/reworking on plugins
  • Loading branch information
tonysnowboardunderthebridge authored Dec 2, 2023
2 parents f898e63 + b1cad2d commit 6c93bd6
Show file tree
Hide file tree
Showing 7 changed files with 544 additions and 136 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"build:mac": "npm run build && electron-builder --mac --config",
"build:linux": "npm run build && electron-builder --linux --config",
"test:main": "standard | snazzy && vitest ./test/main --no-threads",
"test": "npm run test:main",
"test:renderer": "standard | snazzy && vitest ./test/renderer --no-threads",
"test": "npm run test:main && npm run test:renderer",
"clean": "rm -Rf ./out && rm -Rf ./dist && rm -Rf ./coverage",
"release:win": "electron-builder -p always --win --config",
"release:linux": "electron-builder -p always --linux --config",
Expand Down
114 changes: 52 additions & 62 deletions src/renderer/src/components/plugins/PluginEnvVarsForm.jsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,38 @@
'use strict'
import React, { useState, useEffect } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { BorderedBox, Forms } from '@platformatic/ui-components'
import commonStyles from '~/styles/CommonStyles.module.css'
import typographyStyles from '~/styles/Typography.module.css'
import { OPACITY_30, TRANSPARENT, WHITE } from '@platformatic/ui-components/src/components/constants'

function PluginEnvVarsForm ({ service, plugin }) {
const [form, setForm] = useState(null)
const [validations, setValidations] = useState({ })
// eslint-disable-next-line no-unused-vars
const [validForm, setValidForm] = useState(false)

useEffect(() => {
if (plugin) {
const tmp = {}
const validations = {}
const formErrors = {}

let envName
plugin.envVars.forEach(envVar => {
envName = envVar.name
tmp[envName] = ''
validations[`${envName}Valid`] = false
formErrors[envName] = ''
})
setForm({ ...tmp })
setValidations({ ...validations, formErrors })
}
}, [plugin])

function handleChange (event) {
const value = event.target.value
validateField(event.target.name, value, setForm(form => ({ ...form, [event.target.name]: value })))
}

function validateField (fieldName, fieldValue, callback = () => {}) {
let tmpValid = validations[`${fieldName}Valid`]
const formErrors = { ...validations.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 = { ...validations, formErrors }
nextValidation[`${fieldName}Valid`] = tmpValid
setValidations(nextValidation)
validateForm(nextValidation, callback())
}

function validateForm (validations, callback = () => {}) {
// eslint-disable-next-line no-unused-vars
const { _formErrors, ...restValidations } = validations
const valid = Object.keys(restValidations).findIndex(element => restValidations[element] === false) === -1
setValidForm(valid)
return callback
}
function PluginEnvVarsForm ({
configuredServices,
onChange,
templateName,
serviceName,
pluginName
}) {
const configuredServiceFound = configuredServices.find(configuredService => configuredService.template === templateName && configuredService.name === serviceName)
const pluginFound = configuredServiceFound.plugins.find(plugin => plugin.name === pluginName) || {}

function renderForm () {
return Object.keys(form).map((element) => (
if (Object.keys(pluginFound.form).length === 0) {
return <></>
}
return Object.keys(pluginFound.form).map((element) => (
<Forms.Field
title={plugin.envVars.find(env => env.name === element)?.path}
title={pluginFound.form[element].path}
titleColor={WHITE}
key={element}
>
<Forms.Input
placeholder='Env variable example'
name={element}
borderColor={WHITE}
value={form[element]}
onChange={handleChange}
errorMessage={validations.formErrors[element]}
value={pluginFound.form[element].value}
onChange={onChange}
errorMessage={pluginFound.validations.formErrors[element]}
backgroundTransparent
inputTextClassName={`${typographyStyles.desktopBody} ${typographyStyles.textWhite}`}
verticalPaddingClassName={commonStyles.noVerticalPadding}
Expand All @@ -82,28 +43,57 @@ function PluginEnvVarsForm ({ service, plugin }) {
))
}

function renderVariablesText () {
if (Object.keys(pluginFound.form).length === 0) {
return <span className={`${typographyStyles.desktopBody} ${typographyStyles.textWhite} ${typographyStyles.opacity70}`}>This plugin has no configurable variables. </span>
}
return <span>Variables</span>
}

return (
<BorderedBox
color={WHITE}
borderColorOpacity={OPACITY_30}
backgroundColor={TRANSPARENT}
classes={`${commonStyles.mediumFlexBlock} ${commonStyles.fullWidth}`}
>
<p className={`${typographyStyles.desktopBody} ${typographyStyles.textWhite} ${commonStyles.fullWidth}`}>{plugin.name} Variables</p>
<p className={`${typographyStyles.desktopBody} ${typographyStyles.textWhite} ${commonStyles.fullWidth}`}>{pluginName} {renderVariablesText()}</p>
<div className={`${commonStyles.mediumFlexBlock} ${commonStyles.fullWidth}`}>
{form && renderForm()}
{pluginFound && renderForm()}
</div>
</BorderedBox>
)
}

PluginEnvVarsForm.propTypes = {
/**
* plugin
* configuredServices
*/
configuredServices: PropTypes.array.isRequired,
/**
* templateName
*/
templateName: PropTypes.string,
/**
* serviceName
*/
plugin: PropTypes.object.isRequired
serviceName: PropTypes.string,
/**
* onChange
*/
onChange: PropTypes.func,
/**
* pluginName
*/
pluginName: PropTypes.string

}

// ConfigureEnvVarsPlugins.defaultProps = {}
PluginEnvVarsForm.defaultProps = {
templateName: '',
serviceName: '',
onChange: () => {},
pluginName: ''
}

export default PluginEnvVarsForm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import '~/components/component.animation.css'

function ConfigureEnvVarsTemplateAndPlugins ({
configuredServices,
handleChangeTemplateForm
handleChangeTemplateForm,
handleChangePluginForm
}) {
const [serviceSelected, setServiceSelected] = useState(null)
const [pluginSelected, setPluginSelected] = useState(null)
Expand All @@ -27,10 +28,22 @@ function ConfigureEnvVarsTemplateAndPlugins ({
return handleChangeTemplateForm(event, serviceSelected.template, serviceSelected.name)
}

function handleChangePluginEnvVars (event) {
return handleChangePluginForm(event, serviceSelected.template, serviceSelected.name, pluginSelected.name)
}

useEffect(() => {
if (serviceSelected) {
if (pluginSelected) {
setCurrentComponent(<PluginEnvVarsForm service={{ ...serviceSelected }} plugin={{ ...pluginSelected }} key={pluginSelected.name} />)
setCurrentComponent(
<PluginEnvVarsForm
key={`${serviceSelected.name}-${serviceSelected.template}-${serviceSelected.updatedAt}-${pluginSelected.name}-${pluginSelected.updatedAt}`}
configuredServices={configuredServices}
serviceName={serviceSelected.name}
templateName={serviceSelected.template}
onChange={handleChangePluginEnvVars}
pluginName={pluginSelected.name}
/>)
} else {
setCurrentComponent(
<TemplateEnvVarsForm
Expand Down Expand Up @@ -84,13 +97,18 @@ ConfigureEnvVarsTemplateAndPlugins.propTypes = {
/**
* handleChangeTemplateForm
*/
handleChangeTemplateForm: PropTypes.func
handleChangeTemplateForm: PropTypes.func,
/**
* handleChangeTemplateForm
*/
handleChangePluginForm: PropTypes.func

}

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

export default ConfigureEnvVarsTemplateAndPlugins
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import useStackablesStore from '~/useStackablesStore'
import Title from '~/components/ui/Title'
import '~/components/component.animation.css'
import ConfigureEnvVarsTemplateAndPlugins from './ConfigureEnvVarsTemplateAndPlugins'
import { generateForm, preapareFormForCreateApplication } from '../../../utils'

const ConfigureServices = React.forwardRef(({ onNext, onBack }, ref) => {
const globalState = useStackablesStore()
Expand All @@ -19,51 +20,7 @@ const ConfigureServices = React.forwardRef(({ onNext, onBack }, ref) => {

useEffect(() => {
if (services.length > 0) {
const tmpServices = []
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()
tmpObj.plugins = []
tmpServices.push(tmpObj)
})
setConfiguredServices(tmpServices)
setConfiguredServices(generateForm(services))
}
}, [services])

Expand All @@ -74,16 +31,8 @@ const ConfigureServices = React.forwardRef(({ onNext, onBack }, ref) => {
}, [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 }
configuredServices: { services: preapareFormForCreateApplication(configuredServices) }
})
onNext()
}
Expand All @@ -92,32 +41,68 @@ const ConfigureServices = React.forwardRef(({ onNext, onBack }, ref) => {
const fieldName = event.target.name
const fieldValue = event.target.value
const { form: newForm, validations: newValidations } = configuredServices.find(configuredService => configuredService.name === serviceName && configuredService.template === templateName)

let tmpValid
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') : ''
newValidations[`${fieldName}Valid`] = tmpValid
newValidations.formErrors[fieldName] = 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 = {
...rest,
form: newForm,
updatedAt: new Date().toISOString(),
validations: nextValidation,
validForm: newFormValid,
...rest
validations: newValidations,
validForm: Object.keys(newValidations).findIndex(element => newValidations[element] === false) === -1
}
return newObject
} else {
return configuredService
}
})]
})
}

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

newForm[fieldName].value = fieldValue

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

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

setConfiguredServices(configuredServices => {
return [...configuredServices.map(configuredService => {
if (configuredService.name === serviceName && configuredService.template === templateName) {
const { plugins, ...rest } = configuredService
const newPlugins = plugins.map(plugin => {
if (plugin.name === pluginName) {
return {
name: pluginName,
form: newForm,
updatedAt: new Date().toISOString(),
validations: newValidations,
validForm: newFormValid
}
} else {
return plugin
}
})
const newObject = {
...rest,
plugins: newPlugins
}
return newObject
} else {
Expand All @@ -143,6 +128,7 @@ const ConfigureServices = React.forwardRef(({ onNext, onBack }, ref) => {
<ConfigureEnvVarsTemplateAndPlugins
configuredServices={configuredServices}
handleChangeTemplateForm={handleChangeTemplateForm}
handleChangePluginForm={handleChangePluginForm}
/>
</div>
</div>
Expand Down
Loading

0 comments on commit 6c93bd6

Please sign in to comment.