Skip to content

Commit

Permalink
feat: add useSetupStore
Browse files Browse the repository at this point in the history
  • Loading branch information
BenElferink committed Feb 10, 2025
1 parent 9630d77 commit 34f27da
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 21 deletions.
27 changes: 6 additions & 21 deletions src/containers/destination-modal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,18 @@
import React, { useState } from 'react'
import React, { type FC, useState } from 'react'
import styled from 'styled-components'
import { useModalStore } from '../../store'
import { ArrowIcon } from '@odigos/ui-icons'
import type { DestinationFormData } from '../../@types'
import { ChooseDestinationBody } from './choose-destination'
import { ModalBody, useDestinationFormData } from '../../helpers'
import { DestinationForm, type DestinationFormProps } from '../destination-form'
import { type StoredSetupDestination, useModalStore, useSetupStore } from '../../store'
import { DropdownProps, Modal, NavigationButtons, NavigationButtonsProps, Stepper } from '@odigos/ui-components'
import { CRUD, type Destination, type DestinationCategories, type DestinationOption, ENTITY_TYPES, FIELD_TYPES, useKeyDown } from '@odigos/ui-utils'

// defined here instead of global types, because it's specific to the AppStore in cluster UI
// TODO: consider refactoring this to be more generic
interface AppStoreDest {
type: string
displayName: string
imageUrl: string
category: string
exportedSignals: Destination['exportedSignals']
destinationTypeDetails: {
title: string
value: string
}[]
}
import { CRUD, type DestinationCategories, type DestinationOption, ENTITY_TYPES, FIELD_TYPES, useKeyDown } from '@odigos/ui-utils'

interface DestinationModalProps {
isOnboarding?: boolean
categories: DestinationCategories
potentialDestinations: DestinationOption[]
addConfiguredDestination: (payload: { form: DestinationFormData; stored: AppStoreDest }) => void
createDestination: (destination: DestinationFormData) => void
testConnection: DestinationFormProps['testConnection']
testLoading: DestinationFormProps['testLoading']
Expand All @@ -47,16 +32,16 @@ const SideMenuWrapper = styled.div`
}
`

const DestinationModal: React.FC<DestinationModalProps> = ({
const DestinationModal: FC<DestinationModalProps> = ({
isOnboarding,
categories,
potentialDestinations,
addConfiguredDestination,
createDestination,
testConnection,
testLoading,
testResult,
}) => {
const { addConfiguredDestination } = useSetupStore()
const { currentModal, setCurrentModal } = useModalStore()
const isOpen = currentModal === ENTITY_TYPES.DESTINATION

Expand Down Expand Up @@ -102,7 +87,7 @@ const DestinationModal: React.FC<DestinationModalProps> = ({
value: formData.name,
})

const storedDestination: AppStoreDest = {
const storedDestination: StoredSetupDestination = {
type: selectedItem?.type || '',
displayName: selectedItem?.displayName || '',
imageUrl: selectedItem?.imageUrl || '',
Expand Down
1 change: 1 addition & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './useModalStore'
export * from './useNotificationStore'
export * from './usePendingStore'
export * from './useSelectedStore'
export * from './useSetupStore'
68 changes: 68 additions & 0 deletions src/store/useSetupStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { create } from 'zustand'
import type { DestinationFormData } from '../@types'
import type { Destination, Source } from '@odigos/ui-utils'

export interface AvailableSourcesByNamespace {
[namespace: string]: Pick<Source, 'name' | 'kind' | 'selected' | 'numberOfInstances'>[]
}

export interface SourceSelectionFormData {
[namespace: string]: Pick<Source, 'name' | 'kind' | 'selected'>[]
}

export interface NamespaceSelectionFormData {
[namespace: string]: boolean
}

export interface StoredSetupDestination {
type: string
displayName: string
imageUrl: string
category: string
exportedSignals: Destination['exportedSignals']
destinationTypeDetails: {
title: string
value: string
}[]
}

export interface ISetupState {
// in onboarding this is used to keep state of sources that are available for selection in a namespace, in-case user goes back a page (from destinations to sources)
availableSources: AvailableSourcesByNamespace
// in onboarding this is used to keep state of added sources, until end of onboarding
configuredSources: SourceSelectionFormData
// in onboarding this is used to keep state of namespaces with future-apps selected, until end of onboarding
configuredFutureApps: NamespaceSelectionFormData
// in onbaording this is used to keep state of added destinations, until end of onboarding
configuredDestinations: { stored: StoredSetupDestination; form: DestinationFormData }[]
}

interface ISetupStateSetters {
setAvailableSources: (payload: ISetupState['availableSources']) => void
setConfiguredSources: (payload: ISetupState['configuredSources']) => void
setConfiguredFutureApps: (payload: ISetupState['configuredFutureApps']) => void

setConfiguredDestinations: (payload: ISetupState['configuredDestinations']) => void
addConfiguredDestination: (payload: { stored: StoredSetupDestination; form: DestinationFormData }) => void
removeConfiguredDestination: (payload: { type: string }) => void

resetState: () => void
}

export const useSetupStore = create<ISetupState & ISetupStateSetters>((set) => ({
availableSources: {},
configuredSources: {},
configuredFutureApps: {},
configuredDestinations: [],

setAvailableSources: (payload) => set({ availableSources: payload }),
setConfiguredSources: (payload) => set({ configuredSources: payload }),
setConfiguredFutureApps: (payload) => set({ configuredFutureApps: payload }),

setConfiguredDestinations: (payload) => set({ configuredDestinations: payload }),
addConfiguredDestination: (payload) => set((state) => ({ configuredDestinations: [...state.configuredDestinations, payload] })),
removeConfiguredDestination: (payload) =>
set((state) => ({ configuredDestinations: state.configuredDestinations.filter(({ stored }) => stored.type !== payload.type) })),

resetState: () => set(() => ({ availableSources: {}, configuredSources: {}, configuredFutureApps: {}, configuredDestinations: [] })),
}))

0 comments on commit 34f27da

Please sign in to comment.