diff --git a/frontend/webapp/app/layout.tsx b/frontend/webapp/app/layout.tsx index 12dd17d4d..baaa30393 100644 --- a/frontend/webapp/app/layout.tsx +++ b/frontend/webapp/app/layout.tsx @@ -11,6 +11,7 @@ const LAYOUT_STYLE: React.CSSProperties = { scrollbarWidth: 'none', width: '100vw', height: '100vh', + backgroundColor: theme.colors.dark, }; export default function RootLayout({ diff --git a/frontend/webapp/app/page.tsx b/frontend/webapp/app/page.tsx index bd420872c..b7b4128a3 100644 --- a/frontend/webapp/app/page.tsx +++ b/frontend/webapp/app/page.tsx @@ -1,24 +1,41 @@ 'use client'; -import { useQuery } from 'react-query'; import { useEffect } from 'react'; -import { getConfig } from '@/services/config'; +import { useQuery } from 'react-query'; import { useRouter } from 'next/navigation'; +import { getDestinations } from '@/services'; +import { getConfig } from '@/services/config'; +import { Loader } from '@keyval-dev/design-system'; import { ROUTES, CONFIG, QUERIES } from '@/utils/constants'; export default function App() { const router = useRouter(); - const { data } = useQuery([QUERIES.API_CONFIG], getConfig); - + const { data, isLoading: isConfigLoading } = useQuery( + [QUERIES.API_CONFIG], + getConfig + ); + const { isLoading: isDestinationLoading, data: destinationList } = useQuery( + [QUERIES.API_DESTINATIONS], + getDestinations + ); useEffect(() => { - data && renderCurrentPage(); - }, [data]); + if (isConfigLoading || isDestinationLoading) return; + + renderCurrentPage(); + }, [data, destinationList]); function renderCurrentPage() { const { installation } = data; + + if (destinationList.length > 0) { + router.push(ROUTES.OVERVIEW); + return; + } + const state = installation === CONFIG.APPS_SELECTED ? `?state=${CONFIG.APPS_SELECTED}` : ''; + switch (installation) { case CONFIG.NEW: case CONFIG.APPS_SELECTED: @@ -28,4 +45,6 @@ export default function App() { router.push(ROUTES.OVERVIEW); } } + + return ; } diff --git a/frontend/webapp/containers/overview/sources/new.source.flow.tsx b/frontend/webapp/containers/overview/sources/new.source.flow.tsx index 53502e548..1cf9d41b5 100644 --- a/frontend/webapp/containers/overview/sources/new.source.flow.tsx +++ b/frontend/webapp/containers/overview/sources/new.source.flow.tsx @@ -1,49 +1,22 @@ import React from 'react'; import theme from '@/styles/palette'; -import { setNamespaces } from '@/services'; -import { SelectedSources } from '@/types/sources'; -import { useNotification, useSectionData } from '@/hooks'; import { KeyvalButton, KeyvalText } from '@/design.system'; import { NOTIFICATION, OVERVIEW, SETUP } from '@/utils/constants'; +import { useNotification, useSectionData, useSources } from '@/hooks'; import { SourcesSectionWrapper, ButtonWrapper } from './sources.styled'; import { SourcesSection } from '@/containers/setup/sources/sources.section'; -import { useMutation } from 'react-query'; -export function NewSourcesList({ onSuccess, sources }) { +export function NewSourcesList({ onSuccess }) { const { sectionData, setSectionData, totalSelected } = useSectionData({}); - const { mutate } = useMutation((body: SelectedSources) => - setNamespaces(body) - ); - const { show, Notification } = useNotification(); - - function updateSectionDataWithSources() { - const sourceNamesSet = new Set( - sources.map((source: SelectedSources) => source.name) - ); - const updatedSectionData: SelectedSources = {}; + const { upsertSources } = useSources(); - for (const key in sectionData) { - const { objects, ...rest } = sectionData[key]; - const updatedObjects = objects.map((item) => ({ - ...item, - selected: item?.selected || sourceNamesSet.has(item.name), - })); - - updatedSectionData[key] = { - ...rest, - objects: updatedObjects, - }; - } + const { show, Notification } = useNotification(); - mutate(updatedSectionData, { - onSuccess, - onError: ({ response }) => { - const message = response?.data?.message || SETUP.ERROR; - show({ - type: NOTIFICATION.ERROR, - message, - }); - }, + function onError({ response }) { + const message = response?.data?.message || SETUP.ERROR; + show({ + type: NOTIFICATION.ERROR, + message, }); } @@ -53,7 +26,7 @@ export function NewSourcesList({ onSuccess, sources }) { {`${totalSelected} ${SETUP.SELECTED}`} upsertSources({ sectionData, onSuccess, onError })} style={{ width: 110 }} > diff --git a/frontend/webapp/containers/overview/sources/sources.list.container.tsx b/frontend/webapp/containers/overview/sources/sources.list.container.tsx index f193c1de4..193d09f0f 100644 --- a/frontend/webapp/containers/overview/sources/sources.list.container.tsx +++ b/frontend/webapp/containers/overview/sources/sources.list.container.tsx @@ -25,7 +25,7 @@ export function SourcesListContainer() { title={OVERVIEW.MENU.SOURCES} onBackClick={() => router.back()} /> - + ); diff --git a/frontend/webapp/containers/setup/setup.header/setup.header.tsx b/frontend/webapp/containers/setup/setup.header/setup.header.tsx index ace42edde..4ebbc0468 100644 --- a/frontend/webapp/containers/setup/setup.header/setup.header.tsx +++ b/frontend/webapp/containers/setup/setup.header/setup.header.tsx @@ -81,11 +81,7 @@ export function SetupHeader({ )} {currentStep?.id === SETUP.STEPS.ID.CHOOSE_SOURCE && ( - + {SETUP.NEXT} diff --git a/frontend/webapp/containers/setup/setup.section/setup.section.tsx b/frontend/webapp/containers/setup/setup.section/setup.section.tsx index c6cdd5ca9..58dce93ce 100644 --- a/frontend/webapp/containers/setup/setup.section/setup.section.tsx +++ b/frontend/webapp/containers/setup/setup.section/setup.section.tsx @@ -1,24 +1,21 @@ import React, { useEffect, useRef, useState } from 'react'; +import { STEPS, Step } from './utils'; +import { WhiteArrow } from '@/assets/icons/app'; +import { useSearchParams } from 'next/navigation'; +import { KeyvalText, Steps } from '@/design.system'; +import { SetupHeader } from '../setup.header/setup.header'; +import { SourcesSection } from '../sources/sources.section'; +import { CONFIG, NOTIFICATION, SETUP } from '@/utils/constants'; +import { ConnectionSection } from '../connection/connection.section'; +import { useSectionData, useNotification, useSources } from '@/hooks'; +import { DestinationSection } from '../destination/destination.section'; + import { SetupContentWrapper, SetupSectionContainer, StepListWrapper, BackButtonWrapper, } from './setup.section.styled'; -import { SetupHeader } from '../setup.header/setup.header'; -import { DestinationSection } from '../destination/destination.section'; -import { ConnectionSection } from '../connection/connection.section'; -import { SourcesSection } from '../sources/sources.section'; -import { KeyvalText, Steps } from '@/design.system'; -import { CONFIG, NOTIFICATION, SETUP } from '@/utils/constants'; -import { useSectionData, useNotification } from '@/hooks'; -import { STEPS, Step } from './utils'; -import { setNamespaces } from '@/services'; -import { useSearchParams } from 'next/navigation'; -import { useMutation } from 'react-query'; -import { SelectedSources } from '@/types/sources'; -import { WhiteArrow } from '@/assets/icons/app'; - const STATE = 'state'; const sectionComponents = { @@ -29,11 +26,10 @@ const sectionComponents = { export function SetupSection() { const [currentStep, setCurrentStep] = useState(STEPS[0]); - const { sectionData, setSectionData, totalSelected } = useSectionData({}); - const { mutate } = useMutation((body: SelectedSources) => - setNamespaces(body) - ); + + const { upsertSources } = useSources(); const { show, Notification } = useNotification(); + const { sectionData, setSectionData, totalSelected } = useSectionData({}); const searchParams = useSearchParams(); const search = searchParams.get(STATE); @@ -78,7 +74,9 @@ export function SetupSection() { if (currentStep?.id === SETUP.STEPS.ID.CHOOSE_SOURCE) { previousSourceState.current = sectionData; - mutate(sectionData, { + + upsertSources({ + sectionData, onSuccess: () => { setCurrentStep(nextStep); setSectionData({}); diff --git a/frontend/webapp/containers/setup/sources/sources.section.tsx b/frontend/webapp/containers/setup/sources/sources.section.tsx index 44621f0ef..e55ed83da 100644 --- a/frontend/webapp/containers/setup/sources/sources.section.tsx +++ b/frontend/webapp/containers/setup/sources/sources.section.tsx @@ -7,11 +7,6 @@ import { NOTIFICATION, QUERIES } from '@/utils/constants'; import { KeyvalLoader } from '@/design.system'; import { useNotification } from '@/hooks'; -const DEFAULT_CONFIG = { - selected_all: false, - future_selected: false, -}; - const DEFAULT = 'default'; export function SourcesSection({ sectionData, setSectionData }: any) { @@ -55,6 +50,7 @@ export function SourcesSection({ sectionData, setSectionData }: any) { const sourceData = useMemo(() => { let namespace = sectionData[currentNamespace?.name]; + //filter by search query namespace = searchFilter ? namespace?.objects.filter((item: any) => diff --git a/frontend/webapp/hooks/index.tsx b/frontend/webapp/hooks/index.tsx index 1cfe3af1f..cfa79eb1d 100644 --- a/frontend/webapp/hooks/index.tsx +++ b/frontend/webapp/hooks/index.tsx @@ -1,4 +1,5 @@ -export { useSectionData } from "./useSectionData"; -export { useNotification } from "./useNotification"; -export { useOnClickOutside } from "./useOnClickOutside"; -export { useKeyDown } from "./useKeyDown"; +export { useSectionData } from './useSectionData'; +export { useNotification } from './useNotification'; +export { useOnClickOutside } from './useOnClickOutside'; +export { useKeyDown } from './useKeyDown'; +export * from './sources'; diff --git a/frontend/webapp/hooks/sources/index.ts b/frontend/webapp/hooks/sources/index.ts new file mode 100644 index 000000000..da4dcad8c --- /dev/null +++ b/frontend/webapp/hooks/sources/index.ts @@ -0,0 +1 @@ +export * from './useSources'; diff --git a/frontend/webapp/hooks/sources/useSources.ts b/frontend/webapp/hooks/sources/useSources.ts new file mode 100644 index 000000000..d469109c6 --- /dev/null +++ b/frontend/webapp/hooks/sources/useSources.ts @@ -0,0 +1,39 @@ +import { QUERIES } from '@/utils/constants'; +import { SelectedSources } from '@/types/sources'; +import { useMutation, useQuery } from 'react-query'; +import { getSources, setNamespaces } from '@/services'; + +export function useSources() { + const { data: sources } = useQuery([QUERIES.API_SOURCES], getSources); + + const { mutate } = useMutation((body: SelectedSources) => + setNamespaces(body) + ); + + function upsertSources({ sectionData, onSuccess, onError }) { + const sourceNamesSet = new Set( + sources.map((source: SelectedSources) => source.name) + ); + const updatedSectionData: SelectedSources = {}; + + for (const key in sectionData) { + const { objects, ...rest } = sectionData[key]; + const updatedObjects = objects.map((item) => ({ + ...item, + selected: item?.selected || sourceNamesSet.has(item.name), + })); + + updatedSectionData[key] = { + ...rest, + objects: updatedObjects, + }; + } + + mutate(updatedSectionData, { + onSuccess, + onError, + }); + } + + return { upsertSources }; +}