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

     1  import { ApolloClient } from '@apollo/client'
     2  
     3  import {
     4    AppsIcon,
     5    InstallIcon,
     6    WizardInstaller,
     7    WizardPicker,
     8    WizardStepConfig,
     9  } from '@pluralsh/design-system'
    10  
    11  import {
    12    Datatype,
    13    GetRecipeDocument,
    14    ListRecipesDocument,
    15    Provider,
    16    Recipe,
    17    RecipeSection,
    18    RootQueryType,
    19  } from '../../graphql/generated/graphql'
    20  import { Binding, ClientBindingFactory } from '../../services/wails'
    21  
    22  import { Application } from './Application'
    23  
    24  const toPickerItems = (applications: Array<any>, provider: Provider, forcedApps: any): Array<WizardStepConfig> => applications?.map(app => ({
    25    key: app.id,
    26    label: app.name,
    27    imageUrl: app.icon,
    28    node: <Application
    29      key={app.id}
    30      provider={provider}
    31    />,
    32    isRequired: Object.keys(forcedApps).includes(app.name),
    33    tooltip: forcedApps[app.name],
    34  })) || []
    35  
    36  const toDefaultSteps = (applications: any, provider: Provider, forcedApps: any): Array<WizardStepConfig> => [{
    37    key: 'apps',
    38    label: 'Apps',
    39    Icon: AppsIcon,
    40    node: <WizardPicker items={toPickerItems(applications, provider, forcedApps)} />,
    41    isDefault: true,
    42  },
    43  {
    44    key: 'placeholder',
    45    isPlaceholder: true,
    46  },
    47  {
    48    key: 'install',
    49    label: 'Install',
    50    Icon: InstallIcon,
    51    node: <WizardInstaller />,
    52    isDefault: true,
    53  }]
    54  
    55  const toDependencySteps = (applications: {section: RecipeSection, dependencyOf: Set<string>}[], provider: Provider): Array<WizardStepConfig> => [...applications.map(app => ({
    56    key: app.section.repository!.id,
    57    label: app.section.repository!.name,
    58    imageUrl: app.section.repository!.icon!,
    59    node: <Application
    60      key={app.section.repository!.id}
    61      provider={provider}
    62    />,
    63    isDependency: true,
    64    dependencyOf: app.dependencyOf,
    65  }))]
    66  
    67  const buildSteps = async (
    68    client: ApolloClient<unknown>,
    69    provider: Provider,
    70    selectedApplications: Array<WizardStepConfig>,
    71    installedApplications: Set<string>
    72  ) => {
    73    const dependencyMap = new Map<string, {section: RecipeSection, dependencyOf: Set<string>}>()
    74  
    75    for (const app of selectedApplications) {
    76      const { data: { recipes } = {} } = await client.query<Pick<RootQueryType, 'recipes'>>({
    77        query: ListRecipesDocument,
    78        variables: { repositoryId: app.key },
    79      })
    80  
    81      const { node: recipeBase } = recipes?.edges?.find(edge => edge!.node!.provider === provider) || { node: undefined }
    82  
    83      if (!recipeBase) continue
    84  
    85      const { data: recipe } = await client.query<{recipe: Recipe}>({
    86        query: GetRecipeDocument,
    87        variables: { id: recipeBase?.id },
    88      })
    89  
    90      const sections = recipe.recipe.recipeSections!
    91        .filter(section => section!.repository!.name !== app.label)
    92        .filter(section => !installedApplications.has(section!.repository!.name))
    93  
    94      sections.forEach(section => {
    95        if (selectedApplications.find(app => app.key === section!.repository!.id)) return
    96  
    97        if (!dependencyMap.has(section!.repository!.name)) {
    98          dependencyMap.set(section!.repository!.name, { section: section!, dependencyOf: new Set([app.label!]) })
    99  
   100          return
   101        }
   102  
   103        const dep = dependencyMap.get(section!.repository!.name)!
   104        const dependencyOf: Array<string> = [...Array.from(dep.dependencyOf.values()), app.label!]
   105  
   106        dependencyMap.set(section!.repository!.name, { section: section!, dependencyOf: new Set<string>(dependencyOf) })
   107      })
   108    }
   109  
   110    return toDependencySteps(Array.from(dependencyMap.values()), provider)
   111  }
   112  
   113  const install = async (client: ApolloClient<unknown>, apps: Array<WizardStepConfig<any>>) => {
   114    const toAPIContext = context => ({ ...Object.keys(context || {}).reduce((acc, key) => ({ ...acc, [key]: context[key].value }), {}) })
   115    const toDataTypeValues = (context, datatype) => Object.keys(context || {}).reduce((acc: Array<any>, key) => (context[key].type === datatype ? [...acc, context[key].value] : [...acc]), [])
   116    const install = ClientBindingFactory<void>(Binding.Install)
   117    const domains = apps.reduce((acc: Array<any>, app) => [...acc, ...toDataTypeValues(app.data?.context || {}, Datatype.Domain)], [])
   118    const buckets = apps.reduce((acc: Array<any>, app) => [...acc, ...toDataTypeValues(app.data?.context || {}, Datatype.Bucket)], [])
   119  
   120    // Filter out some form validation fields from context
   121    apps = apps.map(app => ({ ...app, data: { ...app.data, context: toAPIContext(app.data.context ?? {}) } }))
   122  
   123    return install(apps.map(app => ({ ...app, dependencyOf: Array.from(app.dependencyOf ?? []) })), domains, buckets)
   124  }
   125  
   126  export {
   127    toDependencySteps, toDefaultSteps, buildSteps, toPickerItems, install,
   128  }