github.com/pluralsh/plural-cli@v0.9.5/pkg/ui/web/src/routes/installer/Configuration.tsx (about)

     1  import {
     2    Dispatch,
     3    ReactElement,
     4    SetStateAction,
     5    useCallback,
     6    useEffect,
     7    useMemo,
     8  } from 'react'
     9  import { Flex, Span, Switch } from 'honorable'
    10  import { useActive, useNavigation } from '@pluralsh/design-system'
    11  
    12  import {
    13    Datatype,
    14    Maybe,
    15    Operation as OperationType,
    16    Recipe,
    17    RecipeConfiguration,
    18  } from '../../graphql/generated/graphql'
    19  
    20  import { ConfigurationItem } from './ConfigurationItem'
    21  
    22  const available = (config, context) => {
    23    if (!config.condition) return true
    24  
    25    const { condition } = config
    26  
    27    switch (condition.operation) {
    28    case OperationType.Not:
    29      return !(context[condition.field]?.value)
    30    case OperationType.Prefix:
    31      return context[condition.field]?.value?.startsWith(condition.value) ?? false
    32    case OperationType.Eq:
    33      return context[condition.field]?.value
    34    }
    35  
    36    return true
    37  }
    38  
    39  interface ConfigurationProps {
    40    recipe: Recipe,
    41    context: Record<string, any>
    42    setContext: Dispatch<SetStateAction<Record<string, any>>>
    43    oidc?: boolean
    44    setOIDC: Dispatch<boolean>
    45  }
    46  
    47  export function Configuration({
    48    recipe, context, setContext, oidc, setOIDC,
    49  }: ConfigurationProps): ReactElement {
    50    const {
    51      active, completed, setCompleted, setData,
    52    } = useActive<Record<string, unknown>>()
    53    const { onNext } = useNavigation()
    54    const sections = recipe.recipeSections
    55    const configurations = sections!.filter(section => section!.repository!.name === active.label).map(section => section!.configuration).flat().filter(c => !!c)
    56    const setValue = useCallback((
    57      fieldName, value, valid = true, type = Datatype.String
    58    ) => setContext(context => ({ ...context, ...{ [fieldName]: { value, valid, type } } })), [setContext])
    59    const hiddenConfigurations = useMemo(() => configurations.filter(conf => !available(conf, context)), [configurations, context])
    60  
    61    useEffect(() => {
    62      hiddenConfigurations.forEach(conf => {
    63        setContext(context => ({ ...context, ...{ [conf!.name!]: { value: context[conf!.name!]?.value, valid: true, type: Datatype.String } } }))
    64      })
    65      // eslint-disable-next-line react-hooks/exhaustive-deps
    66    }, [hiddenConfigurations.length, setContext])
    67  
    68    useEffect(() => {
    69      if (configurations.length === 0 && !completed && active.data?.id) setCompleted(true)
    70    }, [configurations.length, completed, active.data?.id, setCompleted])
    71  
    72    useEffect(() => {
    73      if (configurations.length === 0 && !active.data?.skipped && completed) {
    74        setData({ ...active.data, ...{ skipped: true } })
    75        onNext()
    76      }
    77    }, [active.data, completed, configurations.length, onNext, setData])
    78  
    79    return (
    80      <Flex
    81        gap="large"
    82        direction="column"
    83        marginRight="xsmall"
    84      >
    85        {configurations.filter(conf => available(conf, context)).map((conf?: Maybe<RecipeConfiguration>) => (
    86          <ConfigurationItem
    87            key={`${recipe.name}-${conf!.name}`}
    88            config={conf}
    89            ctx={context}
    90            setValue={setValue}
    91          />
    92        ))}
    93        {configurations?.length === 0 && (
    94          <Span
    95            color="text-light"
    96            body2
    97          >Nothing needs doing here! You can continue.
    98          </Span>
    99        )}
   100        {recipe.oidcEnabled && (
   101          <div>
   102            <Switch
   103              checked={oidc}
   104              onChange={({ target: { checked } }) => setOIDC(checked)}
   105            >Enable OIDC
   106            </Switch>
   107          </div>
   108        )}
   109      </Flex>
   110    )
   111  }