From 55ffb94fe2a24c43b6e9b80678119d43c60940cf Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Wed, 12 Mar 2025 14:19:40 -0600 Subject: [PATCH] ripped out terms provider --- .../api/buster_rest/terms/queryRequests.ts | 34 ++++++++++++--- .../modal/NewTermModal/NewTermModal.tsx | 5 +-- web/src/context/AppProviders.tsx | 15 +++---- .../BusterTermsIndividualProvider.tsx | 34 --------------- .../BusterTermsIndividualProvider/index.ts | 2 - .../useBusterTermsCreate.tsx | 35 ---------------- .../useBusterTermsIndividual.tsx | 11 ----- .../useBusterTermsUpdate.ts | 9 ---- web/src/context/Terms/BusterTermsProvider.tsx | 10 ----- web/src/context/Terms/index.ts | 9 ---- web/src/context/Terms/interfaces.ts | 18 -------- .../TermIndividualContent.tsx | 42 ++++++++----------- .../TermIndividualContentSider.tsx | 22 +++++----- .../TermListSelectedPopup.tsx | 10 +++-- .../TermsListController/TermsHeader.tsx | 7 ++-- 15 files changed, 75 insertions(+), 188 deletions(-) delete mode 100644 web/src/context/Terms/BusterTermsIndividualProvider/BusterTermsIndividualProvider.tsx delete mode 100644 web/src/context/Terms/BusterTermsIndividualProvider/index.ts delete mode 100644 web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsCreate.tsx delete mode 100644 web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsIndividual.tsx delete mode 100644 web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsUpdate.ts delete mode 100644 web/src/context/Terms/BusterTermsProvider.tsx delete mode 100644 web/src/context/Terms/index.ts delete mode 100644 web/src/context/Terms/interfaces.ts diff --git a/web/src/api/buster_rest/terms/queryRequests.ts b/web/src/api/buster_rest/terms/queryRequests.ts index d322c67ce..034e26616 100644 --- a/web/src/api/buster_rest/terms/queryRequests.ts +++ b/web/src/api/buster_rest/terms/queryRequests.ts @@ -1,9 +1,11 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { createTerm, deleteTerms, getTerm, getTermsList, updateTerm } from './requests'; -import { TermsListParams } from '@/api/request_interfaces/terms'; +import { TermDeleteParams, TermsListParams } from '@/api/request_interfaces/terms'; import { queryKeys } from '@/api/query_keys'; import { BusterTerm } from '@/api/asset_interfaces/terms'; import { useMemo } from 'react'; +import { useMemoizedFn } from '@/hooks'; +import { useBusterNotifications } from '@/context/BusterNotifications'; export const useGetTermsList = (params?: Omit) => { const compiledParams: TermsListParams = useMemo( @@ -17,10 +19,11 @@ export const useGetTermsList = (params?: Omit { +export const useGetTerm = (id: string | undefined) => { return useQuery({ - ...queryKeys.termsGetTerm(id), - queryFn: () => getTerm(id) + ...queryKeys.termsGetTerm(id!), + queryFn: () => getTerm(id!), + enabled: !!id }); }; @@ -50,9 +53,28 @@ export const useUpdateTerm = () => { export const useDeleteTerm = () => { const queryClient = useQueryClient(); + const { openConfirmModal } = useBusterNotifications(); + const mutationFn = useMemoizedFn( + ({ ids, ignoreConfirm = false }: TermDeleteParams & { ignoreConfirm?: boolean }) => { + const method = async () => { + deleteTerms(ids); + }; + + if (ignoreConfirm) { + return method(); + } + + return openConfirmModal({ + title: 'Delete term', + content: 'Are you sure you want to delete this term?', + onOk: method + }); + } + ); + return useMutation({ - mutationFn: deleteTerms, - onSuccess: (data) => { + mutationFn, + onSuccess: () => { const options = queryKeys.termsGetList; queryClient.invalidateQueries({ queryKey: options.queryKey }); } diff --git a/web/src/components/features/modal/NewTermModal/NewTermModal.tsx b/web/src/components/features/modal/NewTermModal/NewTermModal.tsx index c05250ee9..16d7fe0d7 100644 --- a/web/src/components/features/modal/NewTermModal/NewTermModal.tsx +++ b/web/src/components/features/modal/NewTermModal/NewTermModal.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useMemo, useState } from 'react'; -import { useBusterTermsIndividualContextSelector } from '@/context/Terms'; import { Text } from '@/components/ui/typography'; import { AppModal } from '@/components/ui/modal'; import { useMemoizedFn } from '@/hooks'; @@ -8,14 +7,14 @@ import { InputTextArea } from '@/components/ui/inputs/InputTextArea'; import { Input } from '@/components/ui/inputs/Input'; import { SelectMultiple } from '@/components/ui/select/SelectMultiple'; import { SelectItem } from '@/components/ui/select'; +import { useCreateTerm } from '@/api/buster_rest/terms'; export const NewTermModal: React.FC<{ open: boolean; onClose: () => void; }> = React.memo(({ open, onClose }) => { const titleRef = React.useRef(null); - const createTerm = useBusterTermsIndividualContextSelector((x) => x.createTerm); - const isCreatingTerm = useBusterTermsIndividualContextSelector((x) => x.isCreatingTerm); + const { mutateAsync: createTerm, isPending: isCreatingTerm } = useCreateTerm(); const [title, setTitle] = useState(''); const [definition, setDefinition] = useState(''); const [selectedDatasets, setSelectedDatasets] = useState([]); diff --git a/web/src/context/AppProviders.tsx b/web/src/context/AppProviders.tsx index bb829dc8d..395adf4e2 100644 --- a/web/src/context/AppProviders.tsx +++ b/web/src/context/AppProviders.tsx @@ -7,7 +7,6 @@ import { AppLayoutProvider } from './BusterAppLayout'; import { BusterDashboardProvider } from './Dashboards/DashboardProvider'; import { BusterUserConfigProvider } from './Users/UserConfigProvider'; import { BusterSQLProvider } from './SQL/useSQLProvider'; -import { BusterTermsProvider } from './Terms/BusterTermsProvider'; import { BusterSearchProvider } from './Search'; import { BusterAssetsProvider } from './Assets/BusterAssetsProvider'; import { BusterPosthogProvider } from './Posthog/usePosthog'; @@ -39,14 +38,12 @@ export const AppProviders: React.FC< - - - - {children} - - - - + + + {children} + + + diff --git a/web/src/context/Terms/BusterTermsIndividualProvider/BusterTermsIndividualProvider.tsx b/web/src/context/Terms/BusterTermsIndividualProvider/BusterTermsIndividualProvider.tsx deleted file mode 100644 index 08312c011..000000000 --- a/web/src/context/Terms/BusterTermsIndividualProvider/BusterTermsIndividualProvider.tsx +++ /dev/null @@ -1,34 +0,0 @@ -'use client'; - -import React from 'react'; -import { createContext, useContextSelector } from 'use-context-selector'; -import { useBusterTermsCreate } from './useBusterTermsCreate'; -import { useBusterTermsUpdate } from './useBusterTermsUpdate'; - -const useBusterTermsIndividual = () => { - const createTerms = useBusterTermsCreate(); - const updateTerms = useBusterTermsUpdate(); - - return { - ...createTerms, - ...updateTerms - }; -}; - -const BusterTermsIndividualContext = createContext>( - {} as ReturnType -); - -export const BusterTermsIndividualProvider: React.FC<{ children: React.ReactNode }> = ({ - children -}) => { - return ( - - {children} - - ); -}; - -export const useBusterTermsIndividualContextSelector = ( - selector: (state: ReturnType) => T -) => useContextSelector(BusterTermsIndividualContext, selector); diff --git a/web/src/context/Terms/BusterTermsIndividualProvider/index.ts b/web/src/context/Terms/BusterTermsIndividualProvider/index.ts deleted file mode 100644 index 5c8560e6b..000000000 --- a/web/src/context/Terms/BusterTermsIndividualProvider/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './BusterTermsIndividualProvider'; -export * from './useBusterTermsIndividual'; diff --git a/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsCreate.tsx b/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsCreate.tsx deleted file mode 100644 index 744fbce5d..000000000 --- a/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsCreate.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { useBusterNotifications } from '@/context/BusterNotifications'; -import { useMemoizedFn } from '@/hooks'; -import type { TermDeleteParams } from '@/api/request_interfaces/terms'; -import { useCreateTerm, useDeleteTerm } from '@/api/buster_rest/terms'; - -export const useBusterTermsCreate = () => { - const { openConfirmModal } = useBusterNotifications(); - - const { mutateAsync: createTerm, isPending: isCreatingTerm } = useCreateTerm(); - - const { mutate: deleteTermMutation, isPending: isDeletingTerm } = useDeleteTerm(); - - const onDeleteTerm = useMemoizedFn(({ ids }: TermDeleteParams, ignoreConfirm = false) => { - const method = async () => { - deleteTermMutation(ids); - }; - - if (ignoreConfirm) { - return method(); - } - - return openConfirmModal({ - title: 'Delete term', - content: 'Are you sure you want to delete this term?', - onOk: method - }); - }); - - return { - createTerm, - onDeleteTerm, - isCreatingTerm, - isDeletingTerm - }; -}; diff --git a/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsIndividual.tsx b/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsIndividual.tsx deleted file mode 100644 index 3702fcc9d..000000000 --- a/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsIndividual.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { useGetTerm } from '@/api/buster_rest/terms'; - -export const useBusterTermsIndividual = ({ termId }: { termId: string }) => { - const { data: term, refetch: refetchTerm, isFetched: isFetchedTerm } = useGetTerm(termId); - - return { - term, - refetchTerm, - isFetchedTerm - }; -}; diff --git a/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsUpdate.ts b/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsUpdate.ts deleted file mode 100644 index 937654328..000000000 --- a/web/src/context/Terms/BusterTermsIndividualProvider/useBusterTermsUpdate.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { useUpdateTerm } from '@/api/buster_rest/terms'; - -export const useBusterTermsUpdate = () => { - const { mutate: updateTerm } = useUpdateTerm(); - - return { - updateTerm - }; -}; diff --git a/web/src/context/Terms/BusterTermsProvider.tsx b/web/src/context/Terms/BusterTermsProvider.tsx deleted file mode 100644 index ced5105d3..000000000 --- a/web/src/context/Terms/BusterTermsProvider.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { BusterTermsIndividualProvider } from './BusterTermsIndividualProvider'; - -export const BusterTermsProvider: React.FC<{ - children: React.ReactNode; -}> = React.memo(({ children }) => { - return {children}; -}); - -BusterTermsProvider.displayName = 'BusterTermsProvider'; diff --git a/web/src/context/Terms/index.ts b/web/src/context/Terms/index.ts deleted file mode 100644 index d59945cab..000000000 --- a/web/src/context/Terms/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './interfaces'; -export * from './BusterTermsProvider'; - -import { - useBusterTermsIndividualContextSelector, - useBusterTermsIndividual -} from './BusterTermsIndividualProvider'; - -export { useBusterTermsIndividualContextSelector, useBusterTermsIndividual }; diff --git a/web/src/context/Terms/interfaces.ts b/web/src/context/Terms/interfaces.ts deleted file mode 100644 index 3c65e1024..000000000 --- a/web/src/context/Terms/interfaces.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { BusterTerm, BusterTermListItem } from '@/api/asset_interfaces/terms'; - -export type UseTermsContextSelector = (selector: (state: UseTermsHookReturn) => T) => T; - -export interface UseTermsHookReturn { - getTermFromList: (termId: string) => BusterTermListItem | undefined; - createTerm: (params: any) => Promise; - subscribeToTerm: ({ id }: { id: string }) => Promise; - termsList: BusterTermListItem[]; - loadedTermsList: boolean; - getInitialTerms: () => Promise; - onSetOpenNewTermsModal: (value: boolean) => void; - updateTerm: (params: any) => Promise; - deleteTerm: ({ id }: { id: string }, ignoreConfirm?: boolean) => Promise; - openNewTermsModal: boolean; - unsubscribeFromTerm: (termId: string) => void; - terms: Record; -} diff --git a/web/src/controllers/TermIndividualController/TermIndividualContent.tsx b/web/src/controllers/TermIndividualController/TermIndividualContent.tsx index a7be7684a..750d5236b 100644 --- a/web/src/controllers/TermIndividualController/TermIndividualContent.tsx +++ b/web/src/controllers/TermIndividualController/TermIndividualContent.tsx @@ -2,7 +2,6 @@ import React, { useEffect, useMemo, useState } from 'react'; import { AppPageLayoutContent } from '@/components/ui/layouts/AppPageLayoutContent'; -import { useBusterTermsIndividualContextSelector, useBusterTermsIndividual } from '@/context/Terms'; import { Dropdown, DropdownItems } from '@/components/ui/dropdown'; import { Button } from '@/components/ui/buttons'; import { useDebounceFn } from '@/hooks'; @@ -14,27 +13,21 @@ import clamp from 'lodash/clamp'; import { Text } from '@/components/ui/typography'; import { BusterRoutes } from '@/routes'; import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; -import { - Card, - CardHeader, - CardFooter, - CardTitle, - CardDescription, - CardContent -} from '@/components/ui/card/CardBase'; +import { Card, CardHeader, CardContent } from '@/components/ui/card/CardBase'; import { InputTextArea } from '@/components/ui/inputs/InputTextArea'; +import { useDeleteTerm, useGetTerm, useUpdateTerm } from '@/api/buster_rest/terms'; export const TermIndividualContent: React.FC<{ termId: string; }> = ({ termId }) => { - const updateTerm = useBusterTermsIndividualContextSelector((x) => x.updateTerm); - const { term: selectedTerm } = useBusterTermsIndividual({ termId }); - const loadingSelectedTerm = !selectedTerm?.id; + const { mutateAsync: updateTerm } = useUpdateTerm(); + const { data: term } = useGetTerm(termId); + const loadingSelectedTerm = !term?.id; const [editingTermName, setEditingTermName] = useState(false); - const [termName, setTermName] = useState(selectedTerm?.name || ''); - const [termDefinition, setTermDefinition] = useState(selectedTerm?.definition || ''); - const [termSQL, setTermSQL] = useState(selectedTerm?.sql_snippet || ''); + const [termName, setTermName] = useState(term?.name || ''); + const [termDefinition, setTermDefinition] = useState(term?.definition || ''); + const [termSQL, setTermSQL] = useState(term?.sql_snippet || ''); const [sqlHeight, setSqlHeight] = useState(300); const onSetTermName = (value: string) => { @@ -65,10 +58,10 @@ export const TermIndividualContent: React.FC<{ ); useEffect(() => { - setTermName(selectedTerm?.name || ''); - setTermDefinition(selectedTerm?.definition || ''); - setTermSQL(selectedTerm?.sql_snippet || ''); - }, [selectedTerm?.name, selectedTerm?.definition]); + setTermName(term?.name || ''); + setTermDefinition(term?.definition || ''); + setTermSQL(term?.sql_snippet || ''); + }, [term?.name, term?.definition]); return ( @@ -93,7 +86,7 @@ export const TermIndividualContent: React.FC<{ Last updated:{' '} {formatDate({ - date: selectedTerm?.updated_at!, + date: term?.updated_at!, format: 'lll' })} @@ -109,8 +102,8 @@ export const TermIndividualContent: React.FC<{
{ @@ -164,11 +157,11 @@ const MoreDropdown: React.FC<{ termId: string; setEditingTermName: (value: boole termId, setEditingTermName }) => { - const onDeleteTerm = useBusterTermsIndividualContextSelector((x) => x.onDeleteTerm); + const { mutateAsync: deleteTerm, isPending: isPendingDeleteTerm } = useDeleteTerm(); const onChangePage = useAppLayoutContextSelector((s) => s.onChangePage); const onDeleteTermsPreflight = async () => { - await onDeleteTerm({ ids: [termId] }) + await deleteTerm({ ids: [termId] }) .then(() => { onChangePage({ route: BusterRoutes.APP_TERMS @@ -193,6 +186,7 @@ const MoreDropdown: React.FC<{ termId: string; setEditingTermName: (value: boole value: 'delete', icon: , label: 'Delete term', + loading: isPendingDeleteTerm, onClick: onDeleteTermsPreflight } ], diff --git a/web/src/controllers/TermIndividualController/TermIndividualContentSider.tsx b/web/src/controllers/TermIndividualController/TermIndividualContentSider.tsx index eab503fa7..295830d0c 100644 --- a/web/src/controllers/TermIndividualController/TermIndividualContentSider.tsx +++ b/web/src/controllers/TermIndividualController/TermIndividualContentSider.tsx @@ -1,26 +1,26 @@ 'use client'; import React from 'react'; -import { useBusterTermsIndividualContextSelector, useBusterTermsIndividual } from '@/context/Terms'; + import { Avatar } from '@/components/ui/avatar'; import { formatDate } from '@/lib'; import { Text } from '@/components/ui/typography'; import { DatasetList } from './TermDatasetSelect'; +import { useGetTerm, useUpdateTerm } from '@/api/buster_rest/terms'; export const TermIndividualContentSider: React.FC<{ termId: string }> = ({ termId }) => { - const updateTerm = useBusterTermsIndividualContextSelector((x) => x.updateTerm); - const { term: selectedTerm } = useBusterTermsIndividual({ termId }); + const { mutateAsync: updateTerm } = useUpdateTerm(); + const { data: term } = useGetTerm(termId); - const datasets = selectedTerm?.datasets || []; + const datasets = term?.datasets || []; const onChangeDatasets = async (datasets: string[]) => { const add_to_dataset = datasets.filter( - (item) => !selectedTerm?.datasets?.some((dataset) => dataset.id === item) + (item) => !term?.datasets?.some((dataset) => dataset.id === item) ); const remove_from_dataset = - selectedTerm?.datasets - ?.filter((dataset) => !datasets.includes(dataset.id)) - .map((item) => item.id) || []; + term?.datasets?.filter((dataset) => !datasets.includes(dataset.id)).map((item) => item.id) || + []; await updateTerm({ id: termId, @@ -45,12 +45,12 @@ export const TermIndividualContentSider: React.FC<{ termId: string }> = ({ termI
- - {selectedTerm?.created_by.name} + + {term?.created_by.name} ( {formatDate({ - date: selectedTerm?.created_at!, + date: term?.created_at!, format: 'LL' })} ) diff --git a/web/src/controllers/TermsListController/TermListSelectedPopup.tsx b/web/src/controllers/TermsListController/TermListSelectedPopup.tsx index 14b595d2d..b32a519a3 100644 --- a/web/src/controllers/TermsListController/TermListSelectedPopup.tsx +++ b/web/src/controllers/TermsListController/TermListSelectedPopup.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { BusterListSelectedOptionPopupContainer } from '@/components/ui/list'; import { Button } from '@/components/ui/buttons'; import { useMemoizedFn } from '@/hooks'; -import { useBusterTermsIndividualContextSelector } from '@/context/Terms'; +import { useDeleteTerm } from '@/api/buster_rest/terms'; export const TermListSelectedOptionPopup: React.FC<{ selectedRowKeys: string[]; @@ -30,12 +30,16 @@ const DeleteButton: React.FC<{ selectedRowKeys: string[]; onSelectChange: (selectedRowKeys: string[]) => void; }> = ({ selectedRowKeys, onSelectChange }) => { - const onDeleteTerm = useBusterTermsIndividualContextSelector((x) => x.onDeleteTerm); + const { mutateAsync: onDeleteTerm, isPending: isPendingDeleteTerm } = useDeleteTerm(); const onDeleteClick = useMemoizedFn(async () => { await onDeleteTerm({ ids: selectedRowKeys }); onSelectChange([]); }); - return ; + return ( + + ); }; diff --git a/web/src/controllers/TermsListController/TermsHeader.tsx b/web/src/controllers/TermsListController/TermsHeader.tsx index 9ebd7f398..ea8e81096 100644 --- a/web/src/controllers/TermsListController/TermsHeader.tsx +++ b/web/src/controllers/TermsListController/TermsHeader.tsx @@ -7,10 +7,10 @@ import { AppTooltip } from '@/components/ui/tooltip'; import { Plus } from '@/components/ui/icons'; import { useHotkeys } from 'react-hotkeys-hook'; import { useUserConfigContextSelector } from '@/context/Users'; -import { useBusterTermsIndividual } from '@/context/Terms'; import { useMemoizedFn } from '@/hooks'; import { NewTermModal } from '@/components/features/modal/NewTermModal'; import { type BreadcrumbItem, Breadcrumb } from '@/components/ui/breadcrumb'; +import { useGetTerm } from '@/api/buster_rest/terms'; export const TermsHeader: React.FC<{ termId?: string; @@ -18,8 +18,7 @@ export const TermsHeader: React.FC<{ setOpenNewTermsModal?: (open: boolean) => void; }> = React.memo(({ termId, openNewTermsModal, setOpenNewTermsModal }) => { const isAdmin = useUserConfigContextSelector((state) => state.isAdmin); - - const { term: selectedTerm } = useBusterTermsIndividual({ termId: termId || '' }); + const { data: term } = useGetTerm(termId); const onOpenNewTermsModal = useMemoizedFn(() => { setOpenNewTermsModal?.(true); @@ -33,7 +32,7 @@ export const TermsHeader: React.FC<{ return ( <>
- +
{isAdmin && (