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

Feature/reworking on plugins #50

Merged
merged 5 commits into from
Dec 2, 2023
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
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