Skip to content

Commit

Permalink
feat: userInput slice WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulFarault committed Jan 31, 2023
1 parent 5681f20 commit 339c478
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 84 deletions.
10 changes: 9 additions & 1 deletion src/components/Services/VariablesDisplay/Fields/ArrayList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { useState } from 'react'
import { setProperty } from 'src/features/userInput'
import { useAppDispatch } from 'src/store'
import { classNames } from 'src/utils'
import { useParamsContext } from '../../useParamsContext'
import { useVariablesContext } from '../VariablesContext'

export function ArrayList({
Expand All @@ -11,14 +14,19 @@ export function ArrayList({
value: any[]
dict?: string
}) {
const { serviceId, componentId } = useParamsContext()
const dispatch = useAppDispatch()

dispatch(setProperty({ serviceId, componentId, property, value }))

const { setNewVariables } = useVariablesContext()
const [error, setError] = useState(false)
const inputName = dict ? [dict, property].join('.') : property

function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setError(false)
try {
const newVariable = JSON.parse(event.target.value)
setError(false)
if (!dict) {
setNewVariables((prev: any) => ({ ...prev, [property]: newVariable }))
} else {
Expand Down
47 changes: 47 additions & 0 deletions src/components/Services/VariablesDisplay/Fields/PrimitiveField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Sidebar } from 'src/components/Layout'
import { ArrayList } from './ArrayList'
import { BooleanField } from './BooleanField'
import { StringNumberField } from './StringNumberField'

export function PrimitiveField({
property,
value,
dictId,
}: {
property: string
value: string | number | boolean | any[]
dictId?: string
}) {
return (
<Sidebar
key={property}
className="text-gray-600 text-sm"
space="0"
sideWidth="17rem"
>
<p className="w-20 font-bold overflow-auto">{property}:</p>
<div className="w-full">
{getPrimitiveField([dictId, property].join('.'), value)}
</div>
</Sidebar>
)
}

function getPrimitiveField(property: string, value: any) {
if (value === null) return <p>null</p>
switch (typeof value) {
case 'undefined':
return <p>undefined</p>
case 'string':
case 'number':
return <StringNumberField property={property} value={value} />
case 'boolean':
return <BooleanField property={property} value={value} />
case 'object':
if (Array.isArray(value)) {
return <ArrayList property={property} value={value} />
}
default:
return <p>Type error</p>
}
}
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
import { useState } from 'react'
import { setProperty } from 'src/features/userInput'
import { useAppDispatch } from 'src/store'
import { classNames } from 'src/utils'
import { useVariablesContext } from '../VariablesContext'
import { useParamsContext } from '../../useParamsContext'

export function StringNumberField({
property,
value,
dict,
}: {
property: string
value: string | number
dict: string
}) {
const { setNewVariables } = useVariablesContext()
const { serviceId, componentId } = useParamsContext()
const dispatch = useAppDispatch()
const [error, setError] = useState(false)
const inputName = parent ? [parent, property].join('.') : property

function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setError(false)
try {
const newVariable = JSON.parse(event.target.value)
setError(false)
if (!parent) {
setNewVariables((prev: any) => ({ ...prev, [property]: newVariable }))
} else {
setNewVariables((prev: any) => {
const data = { ...prev }
data[dict] = prev[dict] || {}
data[dict][property] = newVariable
return data
const newValue = JSON.parse(event.target.value)
dispatch(
setProperty({
serviceId,
componentId,
property,
value: newValue,
})
}
)
} catch (err) {
console.group(err)
setError(true)
}
}

return (
<div className="flex">
<input
name={inputName}
name={property}
className={classNames(
'flex-grow bg-gray-100',
error && 'bg-red-200',
Expand Down
30 changes: 0 additions & 30 deletions src/components/Services/VariablesDisplay/Fields/ViewField.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/components/Services/VariablesDisplay/Fields/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './ViewField'
export * from './PrimitiveField'
export * from './RawField'
47 changes: 20 additions & 27 deletions src/components/Services/VariablesDisplay/VariablesDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { useState } from 'react'
import { Disclosure, Sidebar } from 'src/components/Layout/primitives'
import { ViewField, RawField } from './Fields'
import { Disclosure } from 'src/components/Layout/primitives'
import { PrimitiveField, RawField } from './Fields'
import { RawViewButton } from './RawViewButton'

interface ReduceType {
primitiveTypeVariables: [string, string][]
objectTypeVariables: [string, Object][]
}

export function VariablesDisplay({ variables }: { variables: Object }) {
const [isRaw, setIsRaw] = useState(false)

Expand Down Expand Up @@ -38,17 +33,22 @@ export function DisplayRaw({ variables }: { variables: Object }) {
)
}

interface ReduceType {
primitiveTypeVariables: [string, string][]
objectTypeVariables: [string, Object][]
}

export function DisplayView({ variables }: { variables: Object }) {
const { primitiveTypeVariables, objectTypeVariables } = Object.entries(
variables
).reduce<ReduceType>(
(accumulator, currentValue) => {
({ primitiveTypeVariables, objectTypeVariables }, currentValue) => {
if (typeof currentValue[1] === 'object') {
accumulator.objectTypeVariables.push(currentValue)
objectTypeVariables.push(currentValue)
} else {
accumulator.primitiveTypeVariables.push(currentValue)
primitiveTypeVariables.push(currentValue)
}
return accumulator
return { objectTypeVariables, primitiveTypeVariables }
},
{ primitiveTypeVariables: [], objectTypeVariables: [] }
)
Expand All @@ -61,9 +61,12 @@ export function DisplayView({ variables }: { variables: Object }) {
</div>
{/* Display Service Variables Dicts */}
<div className="flex flex-col gap-2">
{objectTypeVariables.map(([k, v]) => (
<Disclosure key={k} title={k}>
<VariablesList variables={v ? Object.entries(v) : []} dict={k} />
{objectTypeVariables.map(([dictId, dictVariables]) => (
<Disclosure key={dictId} title={dictId}>
<VariablesList
variables={dictVariables ? Object.entries(dictVariables) : []}
dictId={dictId}
/>
</Disclosure>
))}
</div>
Expand All @@ -73,25 +76,15 @@ export function DisplayView({ variables }: { variables: Object }) {

export function VariablesList({
variables,
dict,
dictId,
}: {
variables: [string, string | number | boolean | any[]][]
dict?: string
dictId?: string
}) {
return (
<div className="flex flex-col gap-1">
{variables.map(([k, v]) => (
<Sidebar
key={k}
className="text-gray-600 text-sm"
space="0"
sideWidth="17rem"
>
<p className="w-20 font-bold overflow-auto">{k}:</p>
<div className="w-full">
<ViewField property={k} value={v} dict={dict} />
</div>
</Sidebar>
<PrimitiveField key={k} property={k} value={v} dictId={dictId} />
))}
</div>
)
Expand Down
59 changes: 51 additions & 8 deletions src/features/userInput/userInputSlice.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,62 @@
import { createSlice } from '@reduxjs/toolkit'
import { Service } from 'src/clients'
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { ComponentUpdate, ServiceUpdate } from 'src/clients'

const initialState = [] as Service[]
type AugmentedComponentUpdate = Omit<ComponentUpdate, 'message'> & {
id: string
}
type AugmentedServiceUpdate = Omit<ServiceUpdate, 'message'> & {
id: string
components?: AugmentedComponentUpdate[]
}

const initialState = [] as AugmentedServiceUpdate[]

//TODO: refaire avec comme slice {componentToUpdate: {serviceId: string, componentId: string, variables: Object}[], serviceToUpdate{serviceId: string, variables: Object}[]}

export const userInputSlice = createSlice({
name: 'userInput',
initialState,
reducers: {
setServiceProperty: (state, action) => {
setProperty: (
state,
action: PayloadAction<{
serviceId: string
componentId?: string
property: string
value: any
}>
) => {
if (action.payload.componentId) {
return userInputSlice.caseReducers.setComponentProperty(state, action)
} else {
return userInputSlice.caseReducers.setServiceProperty(state, action)
}
},
setServiceProperty: (
state,
action: PayloadAction<{
serviceId: string
property: string
value: any
}>
) => {
const { serviceId, property, value } = action.payload
const serviceIndex = state.findIndex((s) => s.id === serviceId)
state[serviceIndex].variables[property] = value
if (serviceIndex !== -1) {
state[serviceIndex].variables[property] = value
} else {
state.push({ id: serviceId, variables: { [property]: value } })
}
},
setComponentProperty: (state, action) => {
setComponentProperty: (
state,
action: PayloadAction<{
serviceId: string
componentId: string
property: string
value: any
}>
) => {
const { serviceId, componentId, property, value } = action.payload
const serviceIndex = state.findIndex((s) => s.id === serviceId)
const componentIndex = state[serviceIndex].components.findIndex(
Expand All @@ -23,7 +67,6 @@ export const userInputSlice = createSlice({
},
})

export const { setServiceProperty, setComponentProperty } =
userInputSlice.actions
export const { setProperty } = userInputSlice.actions

export default userInputSlice.reducer

0 comments on commit 339c478

Please sign in to comment.