Skip to content

Commit

Permalink
feat: add source selection form
Browse files Browse the repository at this point in the history
  • Loading branch information
BenElferink committed Feb 10, 2025
1 parent 34f27da commit e2bc390
Show file tree
Hide file tree
Showing 15 changed files with 917 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/@types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export * from './data-flow'
export * from './destinations'
export * from './instrumentation-rules'
export * from './metrics'
export * from './namespaces'
export * from './sources'
7 changes: 7 additions & 0 deletions src/@types/namespaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Source } from '@odigos/ui-utils'

export interface Namespace {
name: string
selected: boolean
sources?: Source[]
}
7 changes: 7 additions & 0 deletions src/@types/sources.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import type { Source } from '@odigos/ui-utils'

export interface SourceFormData {
otelServiceName: string
}

export type PersistSources = (
selectAppsList: { [namespace: string]: Pick<Source, 'name' | 'kind' | 'selected'>[] },
futureSelectAppsList: { [namespace: string]: boolean }
) => Promise<void>
8 changes: 2 additions & 6 deletions src/containers/source-drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@ import styled from 'styled-components'
import { buildCard } from './build-card'
import { SourceForm } from '../source-form'
import { useDrawerStore } from '../../store'
import type { SourceFormData } from '../../@types'
import { CodeIcon, ListIcon } from '@odigos/ui-icons'
import { OverviewDrawer, useSourceFormData } from '../../helpers'
import type { PersistSources, SourceFormData } from '../../@types'
import { ConditionDetails, DATA_CARD_FIELD_TYPES, DataCard, type DataCardFieldsProps, Segment } from '@odigos/ui-components'
import { type DescribeSource, DISPLAY_TITLES, ENTITY_TYPES, getEntityIcon, safeJsonStringify, type Source, type WorkloadId } from '@odigos/ui-utils'

interface SourceDrawerProps {
sources: Source[]
persistSources: (
selectAppsList: { [namespace: string]: Pick<Source, 'name' | 'kind' | 'selected'>[] },
futureSelectAppsList: { [namespace: string]: boolean }
) => Promise<void>
persistSources: PersistSources
updateSource: (sourceId: WorkloadId, payload: SourceFormData) => Promise<void>
describe?: DescribeSource
}
Expand Down Expand Up @@ -47,7 +44,6 @@ const SourceDrawer: FC<SourceDrawerProps> = ({ sources, persistSources, updateSo
const [isPrettyMode, setIsPrettyMode] = useState(true) // for "describe source"

const { formData, handleFormChange, resetFormData, loadFormWithDrawerItem } = useSourceFormData()
// const { data: describe, restructureForPrettyMode } = useDescribeSource(drawerEntityId as WorkloadId)

const thisItem = useMemo(() => {
if (isOpen) return null
Expand Down
86 changes: 86 additions & 0 deletions src/containers/source-modal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { type FC, useState } from 'react'
import { useModalStore } from '../../store'
import { useSourceSelectionFormData } from '../../helpers'
import { ENTITY_TYPES, useKeyDown } from '@odigos/ui-utils'
import type { Namespace, PersistSources } from '../../@types'
import { Modal, NavigationButtons } from '@odigos/ui-components'
import { SourceSelectionForm, type SourceSelectionFormProps } from '../source-selection-form'

interface SourceModalProps {
componentType?: SourceSelectionFormProps['componentType']
namespacesLoading: boolean
namespaces: Namespace[]
namespace?: Namespace
getNamespaceSources: (ns: string) => void
persistSources: PersistSources
}

const SourceModal: FC<SourceModalProps> = ({
componentType = 'FAST',
namespacesLoading,
namespaces,
namespace,
getNamespaceSources,
persistSources,
}) => {
const { currentModal, setCurrentModal } = useModalStore()
const isOpen = currentModal === ENTITY_TYPES.ACTION

const [selectedNamespace, setSelectedNamespace] = useState('')

const onSelectNamespace = (ns: string) => {
setSelectedNamespace((prev) => {
const val = prev === ns ? '' : ns

getNamespaceSources(val)

return val
})
}

const formState = useSourceSelectionFormData({ namespaces, namespace, selectedNamespace, onSelectNamespace })
const { getApiSourcesPayload, getApiFutureAppsPayload } = formState

const handleClose = () => {
setSelectedNamespace('')
setCurrentModal('')
}

const handleSubmit = () => {
persistSources(getApiSourcesPayload(), getApiFutureAppsPayload())
handleClose()
}

useKeyDown({ key: 'Enter', active: isOpen }, () => handleSubmit())

return (
<Modal
isOpen={isOpen}
onClose={handleClose}
header={{ title: 'Add Source' }}
actionComponent={
<NavigationButtons
buttons={[
{
label: 'DONE',
variant: 'primary',
onClick: handleSubmit,
},
]}
/>
}
>
<SourceSelectionForm
componentType={componentType}
isModal
namespaces={namespaces}
namespacesLoading={namespacesLoading}
selectedNamespace={selectedNamespace}
onSelectNamespace={onSelectNamespace}
{...formState}
/>
</Modal>
)
}

export { SourceModal, type SourceModalProps }
51 changes: 51 additions & 0 deletions src/containers/source-selection-form/fast/controls/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { FC } from 'react'
import styled from 'styled-components'
import { SearchIcon } from '@odigos/ui-icons'
import type { UseSourceSelectionFormData } from '../../../../helpers'
import { Divider, Input, SectionTitle, Toggle } from '@odigos/ui-components'

interface ControlsProps extends UseSourceSelectionFormData {
isModal?: boolean
}

const FlexContainer = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
`

// when bringin back the "Select all" checkbox, change the following width to 300px
const SearchWrapper = styled.div`
width: 444px;
`

const Controls: FC<ControlsProps> = ({ selectedSources, searchText, setSearchText, showSelectedOnly, setShowSelectedOnly }) => {
const selectedAppsCount = Object.values(selectedSources).reduce((prev, curr) => prev + curr.filter((s) => s.selected).length, 0)

return (
<>
<SectionTitle
title='Select Sources for Instrumentation'
badgeLabel={selectedAppsCount}
description='Select apps to monitor in each namespace. Odigos will instrument them and send telemetry data to your destinations.'
/>

<FlexContainer style={{ marginTop: 24 }}>
<SearchWrapper>
<Input
placeholder='Search Kubernetes Namespaces'
icon={SearchIcon}
value={searchText}
onChange={(e) => setSearchText(e.target.value.toLowerCase())}
/>
</SearchWrapper>
{/* <Checkbox title='Select all' value={selectAll} onChange={onSelectAll} /> */}
<Toggle title='Show selected only' initialValue={showSelectedOnly} onChange={setShowSelectedOnly} />
</FlexContainer>

<Divider margin='16px 0' />
</>
)
}

export { Controls, type ControlsProps }
17 changes: 17 additions & 0 deletions src/containers/source-selection-form/fast/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { type FC } from 'react'
import { ModalBody } from '../../../helpers'
import { type ListProps, List } from './list'
import { Controls, type ControlsProps } from './controls'

interface FastProps extends ControlsProps, ListProps {}

const Fast: FC<FastProps> = ({ isModal, ...props }) => {
return (
<ModalBody $isNotModal={!isModal}>
<Controls {...props} />
<List {...props} />
</ModalBody>
)
}

export { Fast, type FastProps }
Loading

0 comments on commit e2bc390

Please sign in to comment.