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

[GEN-1679]: added useSourceCRUD hook #1720

Merged
merged 29 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f97a5a1
Merge pull request #4 from odigos-io/new-ui
BenElferink Oct 27, 2024
afa1268
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 27, 2024
536f32f
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 28, 2024
fa352be
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 28, 2024
a4f03d8
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 28, 2024
b3fa682
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 29, 2024
f0a397f
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 29, 2024
2c13a75
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 29, 2024
3ab5c0c
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 29, 2024
977c57b
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 30, 2024
d95b6fe
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 30, 2024
cde9bdd
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 31, 2024
7ca44f7
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Oct 31, 2024
29d2e0d
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 3, 2024
5647431
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 3, 2024
8d22beb
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 3, 2024
e53746d
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 3, 2024
6fa1955
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 4, 2024
a6b6ec2
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 5, 2024
746f560
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 5, 2024
5c55719
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 5, 2024
834e5ed
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 6, 2024
8f1cd3e
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 7, 2024
f4435c0
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 7, 2024
1cd0a4b
Merge branch 'new-ui' of https://github.com/odigos-io/odigos
BenElferink Nov 10, 2024
56b67f1
feat: added useSourceCRUD hook
BenElferink Nov 10, 2024
0050326
perf: onClose via hook params
BenElferink Nov 10, 2024
d32dbb3
perf: read items from within CRUD hooks
BenElferink Nov 10, 2024
2a8fc10
fix: action for source CRUD error message
BenElferink Nov 10, 2024
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
19 changes: 7 additions & 12 deletions frontend/webapp/components/notification/toast-list.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import styled from 'styled-components';
import { getIdFromSseTarget } from '@/utils';
import { NotificationNote } from '@/reuseable-components';
import { Notification, OVERVIEW_ENTITY_TYPES } from '@/types';
import { DrawerBaseItem, useDrawerStore, useNotificationStore } from '@/store';
import { useActualDestination, useActualSources, useGetActions, useGetInstrumentationRules } from '@/hooks';
import { getIdFromSseTarget } from '@/utils';
import { useActionCRUD, useDestinationCRUD, useInstrumentationRuleCRUD, useSourceCRUD } from '@/hooks';

const Container = styled.div`
position: fixed;
Expand Down Expand Up @@ -35,10 +35,10 @@ export const ToastList: React.FC = () => {
const Toast: React.FC<Notification> = ({ id, type, title, message, crdType, target }) => {
const { markAsDismissed, markAsSeen } = useNotificationStore();

const { actions } = useGetActions();
const { sources } = useActualSources();
const { destinations } = useActualDestination();
const { instrumentationRules } = useGetInstrumentationRules();
const { sources } = useSourceCRUD();
const { actions } = useActionCRUD();
const { destinations } = useDestinationCRUD();
const { instrumentationRules } = useInstrumentationRuleCRUD();
const setSelectedItem = useDrawerStore(({ setSelectedItem }) => setSelectedItem);

const onClick = () => {
Expand All @@ -57,12 +57,7 @@ const Toast: React.FC<Notification> = ({ id, type, title, message, crdType, targ
case 'InstrumentationInstance':
drawerItem['type'] = OVERVIEW_ENTITY_TYPES.SOURCE;
drawerItem['id'] = getIdFromSseTarget(target, OVERVIEW_ENTITY_TYPES.SOURCE);
drawerItem['item'] = sources.find(
(item) =>
item.kind === drawerItem['id']?.['kind'] &&
item.name === drawerItem['id']?.['name'] &&
item.namespace === drawerItem['id']?.['namespace']
);
drawerItem['item'] = sources.find((item) => item.kind === drawerItem['id']?.['kind'] && item.name === drawerItem['id']?.['name'] && item.namespace === drawerItem['id']?.['namespace']);
break;

case OVERVIEW_ENTITY_TYPES.ACTION:
Expand Down
3 changes: 1 addition & 2 deletions frontend/webapp/components/overview/add-entity/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import Image from 'next/image';
import theme from '@/styles/theme';
import { useModalStore } from '@/store';
import { useOnClickOutside } from '@/hooks';
import React, { useState, useRef } from 'react';
import styled, { css } from 'styled-components';
import { useBooleanStore } from '@/store/useBooleanStore';
import { useBooleanStore, useModalStore } from '@/store';
import { DropdownOption, OVERVIEW_ENTITY_TYPES } from '@/types';
import { Button, FadeLoader, Text } from '@/reuseable-components';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,8 @@ import dynamic from 'next/dynamic';
import styled from 'styled-components';
import { ToastList } from '@/components';
import { OverviewActionMenuContainer } from '../overview-actions-menu';
import { buildNodesAndEdges, NodeBaseDataFlow, } from '@/reuseable-components';
import {
useMetrics,
useGetActions,
useActualSources,
useContainerWidth,
useActualDestination,
useNodeDataFlowHandlers,
useGetInstrumentationRules,
} from '@/hooks';

import { buildNodesAndEdges, NodeBaseDataFlow } from '@/reuseable-components';
import { useMetrics, useContainerWidth, useNodeDataFlowHandlers, useSourceCRUD, useDestinationCRUD, useInstrumentationRuleCRUD, useActionCRUD } from '@/hooks';

const AllDrawers = dynamic(() => import('../all-drawers'), {
ssr: false,
Expand All @@ -35,10 +26,10 @@ const NODE_HEIGHT = 80;

export function OverviewDataFlowContainer() {
const { metrics } = useMetrics();
const { actions } = useGetActions();
const { sources } = useActualSources();
const { destinations } = useActualDestination();
const { instrumentationRules } = useGetInstrumentationRules();
const { sources } = useSourceCRUD();
const { actions } = useActionCRUD();
const { destinations } = useDestinationCRUD();
const { instrumentationRules } = useInstrumentationRuleCRUD();
const { containerRef, containerWidth } = useContainerWidth();
const { handleNodeClick } = useNodeDataFlowHandlers({
rules: instrumentationRules,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useState, useCallback } from 'react';
import React, { useState } from 'react';
import type { K8sActualSource } from '@/types';
import { ChooseSourcesBody } from '../choose-sources-body';
import { Modal, NavigationButtons } from '@/reuseable-components';
import { K8sActualSource, PersistNamespaceItemInput } from '@/types';
import { useActualSources, useConnectSourcesMenuState } from '@/hooks';
import { useConnectSourcesMenuState, useSourceCRUD } from '@/hooks';

interface AddSourceModalProps {
isOpen: boolean;
Expand All @@ -12,33 +12,11 @@ interface AddSourceModalProps {
export const AddSourceModal: React.FC<AddSourceModalProps> = ({ isOpen, onClose }) => {
const [sourcesList, setSourcesList] = useState<K8sActualSource[]>([]);
const { stateMenu, stateHandlers } = useConnectSourcesMenuState({ sourcesList });
const { createSourcesForNamespace, persistNamespaceItems } = useActualSources();
const { createSources } = useSourceCRUD({ onSuccess: onClose });

const handleNextClick = useCallback(async () => {
try {
const namespaceItems: PersistNamespaceItemInput[] = Object.entries(stateMenu.futureAppsCheckbox).map(([namespaceName, futureSelected]) => ({
name: namespaceName,
futureSelected,
}));

await persistNamespaceItems(namespaceItems);

await Promise.all(
Object.entries(stateMenu.selectedItems).map(async ([namespaceName, sources]) => {
const formattedSources = sources.map((source) => ({
kind: source.kind,
name: source.name,
selected: true,
}));
await createSourcesForNamespace(namespaceName, formattedSources);
})
);

onClose();
} catch (error) {
console.error('Error during handleNextClick:', error);
}
}, [stateMenu, onClose, createSourcesForNamespace, persistNamespaceItems]);
const handleNextClick = async () => {
await createSources(stateMenu.selectedItems, stateMenu.futureAppsCheckbox);
};

return (
<Modal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React, { useMemo, useState } from 'react';
import { useDrawerStore } from '@/store';
import { useActualSources } from '@/hooks';
import { useSourceCRUD } from '@/hooks';
import { CardDetails } from '@/components';
import OverviewDrawer from '../../overview/overview-drawer';
import { K8sActualSource, PatchSourceRequestInput, WorkloadId } from '@/types';
import { getMainContainerLanguageLogo } from '@/utils/constants/programming-languages';

const SourceDrawer: React.FC = () => {
const { selectedItem, setSelectedItem } = useDrawerStore((store) => store);
const selectedItem = useDrawerStore(({ selectedItem }) => selectedItem);
const [isEditing, setIsEditing] = useState(false);
const [isFormDirty, setIsFormDirty] = useState(false);

const { updateActualSource, deleteSourcesForNamespace } = useActualSources();
const { deleteSources, updateSource } = useSourceCRUD();

const cardData = useMemo(() => {
if (!selectedItem) return [];
Expand Down Expand Up @@ -47,41 +47,15 @@ const SourceDrawer: React.FC = () => {
};

const handleDelete = async () => {
const { namespace, name, kind } = item as K8sActualSource;
const { namespace } = item as K8sActualSource;

try {
await deleteSourcesForNamespace(namespace, [
{
kind,
name,
selected: false,
},
]);
setSelectedItem(null);
} catch (error) {
console.error('Error deleting source:', error);
}
await deleteSources({ [namespace]: [item as K8sActualSource] });
};

const handleSave = async (newTitle: string) => {
const { namespace, name, kind } = item as K8sActualSource;

const sourceId: WorkloadId = {
namespace,
kind,
name,
};

const patchRequest: PatchSourceRequestInput = {
reportedName: newTitle,
};

try {
await updateActualSource(sourceId, patchRequest);
setSelectedItem(null);
} catch (error) {
console.error('Error updating source:', error);
}
await updateSource({ namespace, kind, name }, { reportedName: newTitle });
};

return (
Expand Down
15 changes: 3 additions & 12 deletions frontend/webapp/graphql/mutations/source.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
import { gql } from '@apollo/client';

export const PERSIST_SOURCE = gql`
mutation PersistSources(
$namespace: String!
$sources: [PersistNamespaceSourceInput!]!
) {
mutation PersistSources($namespace: String!, $sources: [PersistNamespaceSourceInput!]!) {
persistK8sSources(namespace: $namespace, sources: $sources)
}
`;

export const UPDATE_K8S_ACTUAL_SOURCE = gql`
mutation UpdateK8sActualSource(
$sourceId: K8sSourceId!
$patchSourceRequest: PatchSourceRequestInput!
) {
updateK8sActualSource(
sourceId: $sourceId
patchSourceRequest: $patchSourceRequest
)
mutation UpdateK8sActualSource($sourceId: K8sSourceId!, $patchSourceRequest: PatchSourceRequestInput!) {
updateK8sActualSource(sourceId: $sourceId, patchSourceRequest: $patchSourceRequest)
}
`;
1 change: 0 additions & 1 deletion frontend/webapp/hooks/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './useActionFormData';
export * from './useActions';
export * from './useActionState';
export * from './useGetActions';
export * from './useActionCRUD';
13 changes: 10 additions & 3 deletions frontend/webapp/hooks/actions/useActionCRUD.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useDrawerStore } from '@/store';
import { useNotify } from '../useNotify';
import { useMutation } from '@apollo/client';
import { useComputePlatform } from '../compute-platform';
import { ACTION, getSseTargetFromId, NOTIFICATION } from '@/utils';
import { ACTION, getSseTargetFromId, NOTIFICATION, safeJsonParse } from '@/utils';
import { CREATE_ACTION, DELETE_ACTION, UPDATE_ACTION } from '@/graphql/mutations';
import { OVERVIEW_ENTITY_TYPES, type ActionInput, type ActionsType, type NotificationType } from '@/types';
import { type ActionItem, OVERVIEW_ENTITY_TYPES, type ActionInput, type ActionsType, type NotificationType } from '@/types';

interface UseActionCrudParams {
onSuccess?: () => void;
Expand All @@ -13,7 +13,7 @@ interface UseActionCrudParams {

export const useActionCRUD = (params?: UseActionCrudParams) => {
const { setSelectedItem: setDrawerItem } = useDrawerStore((store) => store);
const { refetch } = useComputePlatform();
const { data, refetch } = useComputePlatform();
const notify = useNotify();

const notifyUser = (type: NotificationType, title: string, message: string, id?: string) => {
Expand Down Expand Up @@ -64,6 +64,13 @@ export const useActionCRUD = (params?: UseActionCrudParams) => {

return {
loading: cState.loading || uState.loading || dState.loading,
actions:
data?.computePlatform?.actions?.map((item) => {
const parsedSpec = typeof item.spec === 'string' ? safeJsonParse(item.spec, {} as ActionItem) : item.spec;

return { ...item, spec: parsedSpec };
}) || [],

createAction: (action: ActionInput) => createAction({ variables: { action } }),
updateAction: (id: string, action: ActionInput) => updateAction({ variables: { id, action } }),
deleteAction: (id: string, actionType: ActionsType) => deleteAction({ variables: { id, actionType } }),
Expand Down
20 changes: 0 additions & 20 deletions frontend/webapp/hooks/actions/useGetActions.ts

This file was deleted.

27 changes: 23 additions & 4 deletions frontend/webapp/hooks/compute-platform/useComputePlatform.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
import { ComputePlatform } from '@/types';
import { useCallback } from 'react';
import { useQuery } from '@apollo/client';
import { useBooleanStore } from '@/store';
import type { ComputePlatform } from '@/types';
import { GET_COMPUTE_PLATFORM } from '@/graphql';

type UseComputePlatformHook = {
data?: ComputePlatform;
loading: boolean;
error?: Error;
refetch: () => void;
startPolling: () => Promise<void>;
};

export const useComputePlatform = (): UseComputePlatformHook => {
const { data, loading, error, refetch } =
useQuery<ComputePlatform>(GET_COMPUTE_PLATFORM);
const { data, loading, error, refetch } = useQuery<ComputePlatform>(GET_COMPUTE_PLATFORM);
const { togglePolling } = useBooleanStore();

return { data, loading, error, refetch };
const startPolling = useCallback(async () => {
togglePolling(true);

const maxRetries = 5;
const retryInterval = 1000; // Poll every second
let retries = 0;

while (retries < maxRetries) {
await new Promise((resolve) => setTimeout(resolve, retryInterval));
refetch();
retries++;
}

togglePolling(false);
}, [refetch, togglePolling]);

return { data, loading, error, refetch, startPolling };
};
47 changes: 19 additions & 28 deletions frontend/webapp/hooks/compute-platform/useNamespace.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
import { useMutation, useQuery } from '@apollo/client';
import { GET_NAMESPACES, PERSIST_NAMESPACE } from '@/graphql';
import {
ComputePlatform,
K8sActualNamespace,
PersistNamespaceItemInput,
} from '@/types';
import { ComputePlatform, PersistNamespaceItemInput } from '@/types';
import { useNotify } from '../useNotify';
import { NOTIFICATION } from '@/utils';

type UseNamespaceHook = {
data?: K8sActualNamespace;
loading: boolean;
error?: Error;
persistNamespace: (namespace: PersistNamespaceItemInput) => Promise<void>;
};
export const useNamespace = (namespaceName?: string, instrumentationLabeled = null as boolean | null) => {
const notify = useNotify();

const handleError = (title: string, message: string) => {
notify({ type: NOTIFICATION.ERROR, title, message });
};

const handleComplete = (title: string, message: string) => {
notify({ type: NOTIFICATION.SUCCESS, title, message });
};

export const useNamespace = (
namespaceName: string | undefined,
instrumentationLabeled = null as boolean | null
): UseNamespaceHook => {
const { data, loading, error } = useQuery<ComputePlatform>(GET_NAMESPACES, {
skip: !namespaceName,
variables: { namespaceName, instrumentationLabeled },
fetchPolicy: 'cache-first',
variables: { namespaceName, instrumentationLabeled },
});

const [persistNamespaceMutation] = useMutation(PERSIST_NAMESPACE);

const persistNamespace = async (namespace: PersistNamespaceItemInput) => {
try {
await persistNamespaceMutation({
variables: { namespace },
});
} catch (e) {
console.error('Error persisting namespace:', e);
}
};
const [persistNamespaceMutation] = useMutation(PERSIST_NAMESPACE, {
onError: (error) => handleError('', error.message),
onCompleted: (res, req) => {},
});

return {
persistNamespace,
persistNamespace: async (namespace: PersistNamespaceItemInput) => await persistNamespaceMutation({ variables: { namespace } }),
data: data?.computePlatform.k8sActualNamespace,
loading,
error,
Expand Down
Loading
Loading