Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task 165 manage source #368

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1006d44
WIP
alonkeyval Jul 31, 2023
537aa75
new back button
alonkeyval Jul 31, 2023
ab32b46
WIP
alonkeyval Jul 31, 2023
042cb10
Merge branch 'main' of github.com:alonkeyval/odigos into overview-sou…
alonkeyval Jul 31, 2023
0d97d64
filter instromented apps
alonkeyval Jul 31, 2023
f38568b
WIP
alonkeyval Jul 31, 2023
d57d024
WIP
alonkeyval Jul 31, 2023
6b1a812
WIP
alonkeyval Jul 31, 2023
d6e9f6f
WIP
alonkeyval Jul 31, 2023
7c655a0
WIP
alonkeyval Jul 31, 2023
fbe5504
WIP
alonkeyval Aug 1, 2023
8a93e8a
fixed pr comments
alonkeyval Aug 1, 2023
d9958c8
fixed pr comments
alonkeyval Aug 1, 2023
5d5bf9b
fixed pr comments
alonkeyval Aug 1, 2023
15ba9c3
Merge remote-tracking branch 'upstream/TASK-141-sources-overview' int…
alonkeyval Aug 1, 2023
a131614
fixed pr comments
alonkeyval Aug 1, 2023
180fd5d
hide checkboxs
alonkeyval Aug 1, 2023
d4d5211
WIP
alonkeyval Aug 1, 2023
97e1983
Merge branch 'main' of github.com:alonkeyval/odigos into TASK-161-zer…
alonkeyval Aug 1, 2023
61fc2fc
WIP
alonkeyval Aug 1, 2023
49f6983
fixed pr comments
alonkeyval Aug 1, 2023
b1f12e7
remove scrollbars
alonkeyval Aug 1, 2023
f81d618
WIP
alonkeyval Aug 1, 2023
5e68cdd
added quick help
alonkeyval Aug 2, 2023
32bec3d
WIP
alonkeyval Aug 2, 2023
4d7b99d
Merge remote-tracking branch 'upstream/TASK-141-sources-overview' int…
alonkeyval Aug 2, 2023
f91d357
create destinaion flow match url
alonkeyval Aug 2, 2023
f0e6d64
new dest flow
alonkeyval Aug 2, 2023
0a30a23
manage dest flow
alonkeyval Aug 2, 2023
71e52b7
fixed pr comments
alonkeyval Aug 2, 2023
60a61ee
WIP
alonkeyval Aug 2, 2023
c44837e
WIP
alonkeyval Aug 2, 2023
59029f1
Merge branch 'TASK-141-sources-overview' into TASK-156-match-url-to-a…
alonkeyval Aug 2, 2023
924cee2
fixed pr comments
alonkeyval Aug 2, 2023
004ca63
restruce file system
alonkeyval Aug 2, 2023
cf77635
wip
alonkeyval Aug 2, 2023
4616dcf
add pen icon and danger zone
alonkeyval Aug 2, 2023
5d85d7c
manage delete source
alonkeyval Aug 3, 2023
b655e18
WIP
alonkeyval Aug 3, 2023
592be7e
WIP
alonkeyval Aug 3, 2023
ef93cc6
WIP
alonkeyval Aug 3, 2023
9e322bf
WIP
alonkeyval Aug 3, 2023
5ad8d1d
WIP
alonkeyval Aug 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions frontend/webapp/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from "react";
import { ThemeProvider } from "styled-components";
import theme from "@/styles/palette";
import { QueryClient, QueryClientProvider } from "react-query";
import Head from "next/head";

const LAYOUT_STYLE: React.CSSProperties = {
margin: 0,
Expand Down Expand Up @@ -30,6 +31,9 @@ export default function RootLayout({
<html lang="en">
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={theme}>
<Head>
<title>Odigos</title>
</Head>
<body suppressHydrationWarning={true} style={LAYOUT_STYLE}>
{children}
</body>
Expand Down
111 changes: 111 additions & 0 deletions frontend/webapp/app/overview/destinations/create/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"use client";
import React, { useEffect } from "react";
import { NOTIFICATION, OVERVIEW, QUERIES } from "@/utils/constants";
import { useMutation, useQuery } from "react-query";
import {
getDestination,
getDestinationsTypes,
setDestination,
} from "@/services";
import { ManageDestination, OverviewHeader } from "@/components/overview";
import { useNotification, useSectionData } from "@/hooks";
import { useRouter, useSearchParams } from "next/navigation";
import { styled } from "styled-components";

const DEST = "dest";

const NewDestinationContainer = styled.div`
padding: 20px 36px;
`;

export default function NewDestinationFlow() {
const { sectionData, setSectionData } = useSectionData(null);
const { show, Notification } = useNotification();
const { mutate } = useMutation((body) => setDestination(body));
const searchParams = useSearchParams();
const router = useRouter();

const { data: destinationType } = useQuery(
[QUERIES.API_DESTINATION_TYPE, sectionData?.type],
() => getDestination(sectionData?.type),
{
enabled: !!sectionData,
}
);

const { data: destinationsList } = useQuery(
[QUERIES.API_DESTINATION_TYPES],
getDestinationsTypes
);

useEffect(onPageLoad, [destinationsList]);

function onPageLoad() {
const search = searchParams.get(DEST);
if (!destinationsList || !search) return;

let currentData = null;

for (const category of destinationsList.categories) {
if (currentData) {
break;
}
const filterItem = category.items.filter(({ type }) => type === search);
if (filterItem.length) {
currentData = filterItem[0];
}
}

setSectionData(currentData);
}

function onSuccess(message = OVERVIEW.DESTINATION_UPDATE_SUCCESS) {
show({
type: NOTIFICATION.SUCCESS,
message,
});
}

function onError({ response }) {
const message = response?.data?.message;
show({
type: NOTIFICATION.ERROR,
message,
});
}

function onSubmit(newDestination) {
const destination = {
...newDestination,
type: sectionData.type,
};

mutate(destination, {
onSuccess: () => onSuccess(OVERVIEW.DESTINATION_CREATED_SUCCESS),
onError,
});
}

function handleBackPress() {
router.back();
}

return (
<>
<OverviewHeader
title={OVERVIEW.MENU.DESTINATIONS}
onBackClick={handleBackPress}
/>
{destinationType && sectionData && (
<NewDestinationContainer>
<ManageDestination
destinationType={destinationType}
selectedDestination={sectionData}
onSubmit={onSubmit}
/>
</NewDestinationContainer>
)}
<Notification />
</>
);
}
7 changes: 7 additions & 0 deletions frontend/webapp/app/overview/destinations/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"use client";
import React from "react";
import { NewDestinationFlow } from "@/containers/overview";

export default function CreateDestinationPage() {
return <NewDestinationFlow />;
}
67 changes: 67 additions & 0 deletions frontend/webapp/app/overview/destinations/manage/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"use client";
import React, { useEffect, useState } from "react";
import { NOTIFICATION, OVERVIEW, QUERIES } from "@/utils/constants";
import { useNotification } from "@/hooks";
import { useSearchParams } from "next/navigation";
import UpdateDestinationFlow from "@/containers/overview/destination/update.destination.flow";
import { getDestinations } from "@/services";
import { useQuery } from "react-query";
import { KeyvalLoader } from "@/design.system";

const DEST = "dest";

export default function ManageDestinationPage() {
const [selectedDestination, setSelectedDestination] = useState<any>(null);
const { show, Notification } = useNotification();

const {
isLoading: destinationLoading,
data: destinationList,
refetch,
} = useQuery([QUERIES.API_DESTINATIONS], getDestinations);

const searchParams = useSearchParams();

useEffect(onPageLoad, [searchParams, destinationList]);

function onPageLoad() {
const search = searchParams.get(DEST);
const currentDestination = destinationList?.filter(
({ id }) => id === search
);
if (currentDestination?.length) {
setSelectedDestination(currentDestination[0]);
}
}

function onSuccess(message = OVERVIEW.DESTINATION_UPDATE_SUCCESS) {
refetch();
show({
type: NOTIFICATION.SUCCESS,
message,
});
}

function onError({ response }) {
const message = response?.data?.message;
show({
type: NOTIFICATION.ERROR,
message,
});
}

if (destinationLoading || !selectedDestination) {
return <KeyvalLoader />;
}

return (
<>
<UpdateDestinationFlow
selectedDestination={selectedDestination}
onSuccess={onSuccess}
onError={onError}
/>
<Notification />
</>
);
}
15 changes: 13 additions & 2 deletions frontend/webapp/app/overview/destinations/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
"use client";
import { DestinationContainer } from "@/containers/overview";
import React from "react";
import { styled } from "styled-components";

const DestinationContainerWrapper = styled.div`
height: 100vh;
overflow-y: hidden;
::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none;
scrollbar-width: none;
`;

export default function DestinationDashboardPage() {
return (
<>
<DestinationContainerWrapper>
<DestinationContainer />
</>
</DestinationContainerWrapper>
);
}
6 changes: 5 additions & 1 deletion frontend/webapp/app/overview/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
// "use client";
import { Menu } from "@/components/side.menu";
import theme from "@/styles/palette";
import { Metadata } from "next";
import React from "react";

const LAYOUT_STYLE = {
Expand All @@ -14,6 +15,9 @@ const CHILDREN_STYLE = {
width: "100%",
height: "93%",
};
export const metadata: Metadata = {
title: "Odigos",
};

export default function Layout({ children }: { children: React.ReactNode }) {
return (
Expand Down
40 changes: 40 additions & 0 deletions frontend/webapp/app/overview/sources/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"use client";
import React from "react";
import { NOTIFICATION, OVERVIEW, QUERIES } from "@/utils/constants";
import { OverviewHeader } from "@/components/overview";
import { useNotification } from "@/hooks";
import { useQuery } from "react-query";
import { getSources } from "@/services";
import { NewSourceFlow } from "@/containers/overview/sources/new.source.flow";
import { useRouter } from "next/navigation";

export default function CreateNewSourcesPage() {
const { show, Notification } = useNotification();
const router = useRouter();
const { data: sources, refetch } = useQuery(
[QUERIES.API_SOURCES],
getSources
);

function onNewSourceSuccess() {
setTimeout(() => {
router.back();
refetch();
}, 1000);
show({
type: NOTIFICATION.SUCCESS,
message: OVERVIEW.SOURCE_CREATED_SUCCESS,
});
}

return (
<>
<OverviewHeader
title={OVERVIEW.MENU.SOURCES}
onBackClick={() => router.back()}
/>
<NewSourceFlow onSuccess={onNewSourceSuccess} sources={sources} />
<Notification />
</>
);
}
103 changes: 103 additions & 0 deletions frontend/webapp/app/overview/sources/manage/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"use client";
import { ManageSourceHeader } from "@/components/overview/sources/manage.source.header/manage.source.header";
import { getSources } from "@/services";
import {
NOTIFICATION,
OVERVIEW,
QUERIES,
ROUTES,
SETUP,
} from "@/utils/constants";
import { useRouter, useSearchParams } from "next/navigation";
import React, { useEffect, useState } from "react";
import { useMutation, useQuery } from "react-query";
import { ManageSourcePageContainer, BackButtonWrapper } from "./styled";
import { LANGUAGES_LOGOS } from "@/assets/images";
import { Back } from "@/assets/icons/overview";
import { KeyvalText } from "@/design.system";
import { ManagedSource } from "@/types/sources";
import { DeleteSource } from "@/components/overview";
import { deleteSource } from "@/services/sources";
import { useNotification } from "@/hooks";

const SOURCE = "source";

export default function ManageSourcePage() {
const [currentSource, setCurrentSource] = useState<ManagedSource | null>(
null
);
const searchParams = useSearchParams();
const router = useRouter();
const { data: sources, refetch } = useQuery(
[QUERIES.API_SOURCES],
getSources
);
const { show, Notification } = useNotification();
const { mutate } = useMutation(() =>
deleteSource(
currentSource?.namespace || "",
currentSource?.kind || "",
currentSource?.name || ""
)
);
useEffect(onPageLoad, [sources]);

useEffect(() => {
console.log({ currentSource });
}, [currentSource]);

function onPageLoad() {
const search = searchParams.get(SOURCE);
const source = sources?.find((item) => item.name === search);
source && setCurrentSource(source);
}
function onError({ response }) {
const message = response?.data?.message;
show({
type: NOTIFICATION.ERROR,
message,
});
}

function onSuccess() {
setTimeout(() => {
router.back();
refetch();
}, 1000);
show({
type: NOTIFICATION.SUCCESS,
message: OVERVIEW.SOURCE_DELETED_SUCCESS,
});
}
function onDelete() {
mutate(undefined, {
onSuccess,
onError,
});
}

return (
<ManageSourcePageContainer>
<BackButtonWrapper onClick={() => router.back()}>
<Back width={14} />
<KeyvalText size={14}>{SETUP.BACK}</KeyvalText>
</BackButtonWrapper>
{currentSource && (
<ManageSourceHeader
name={currentSource?.name}
image_url={
LANGUAGES_LOGOS[currentSource?.languages?.[0].language || ""]
}
/>
)}
<DeleteSource
onDelete={onDelete}
name={currentSource?.name}
image_url={
LANGUAGES_LOGOS[currentSource?.languages?.[0].language || ""]
}
/>
<Notification />
</ManageSourcePageContainer>
);
}
Loading