'use client'; import React, { useEffect, useMemo, useState } from 'react'; import { AppContent } from '@/components/ui/layout/AppContent'; import { useBusterTermsIndividualContextSelector, useBusterTermsIndividual } from '@/context/Terms'; import { Dropdown, Input } from 'antd'; import { useDebounceFn } from 'ahooks'; import { formatDate } from '@/lib'; import { AppMaterialIcons, EditableTitle } from '@/components/ui'; import { useAntToken } from '@/styles/useAntToken'; import { AppCodeEditor } from '@/components/ui/inputs/AppCodeEditor'; import clamp from 'lodash/clamp'; import { MenuProps } from 'antd/lib'; import { ItemContainer } from '@/components/ui/card/ItemContainer'; import { Text } from '@/components/ui'; import { BusterRoutes } from '@/routes'; import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; export const TermIndividualContent: React.FC<{ termId: string; }> = ({ termId }) => { const updateTerm = useBusterTermsIndividualContextSelector((x) => x.updateTerm); const { term: selectedTerm } = useBusterTermsIndividual({ termId }); const loadingSelectedTerm = !selectedTerm?.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 [sqlHeight, setSqlHeight] = useState(300); const onSetTermName = (value: string) => { setTermName(value); updateTerm({ id: termId, name: value }); }; const onSetTermDefinition = (value: string) => { setTermDefinition(value); updateTerm({ id: termId, definition: value }); }; const onSetTermSQL = useDebounceFn( (value: string) => { setTermSQL(value); updateTerm({ id: termId, sql_snippet: value }); }, { wait: 500 } ); useEffect(() => { setTermName(selectedTerm?.name || ''); setTermDefinition(selectedTerm?.definition || ''); setTermSQL(selectedTerm?.sql_snippet || ''); }, [selectedTerm?.name, selectedTerm?.definition]); return ( {loadingSelectedTerm ? ( ) : (
{ onSetTermName(v); }} level={4}> {termName}
Last updated:{' '} {formatDate({ date: selectedTerm?.updated_at!, format: 'lll' })}
{ onSetTermDefinition(e.target.value); }} variant="borderless" />
SQL Snippet
}>
{ setSqlHeight(clamp(v, 300, 800)); }} onChange={(v) => { onSetTermSQL.run(v); }} monacoEditorOptions={{ scrollbar: { alwaysConsumeMouseWheel: false } }} />
)}
); }; const SkeletonLoader: React.FC = () => { return
{/* */}
; }; const MoreDropdown: React.FC<{ termId: string; setEditingTermName: (value: boolean) => void }> = ({ termId, setEditingTermName }) => { const token = useAntToken(); const onDeleteTerm = useBusterTermsIndividualContextSelector((x) => x.onDeleteTerm); const onChangePage = useAppLayoutContextSelector((s) => s.onChangePage); const onDeleteTermsPreflight = async () => { await onDeleteTerm({ ids: [termId] }) .then(() => { onChangePage({ route: BusterRoutes.APP_TERMS }); }) .catch((error) => { // }); }; const dropdownItems: MenuProps['items'] = useMemo( () => [ { key: 'edit', icon: , label: 'Edit term title', onClick: () => { setEditingTermName(true); } }, { key: 'delete', icon: , label: 'Delete term', onClick: onDeleteTermsPreflight } ], [setEditingTermName, onDeleteTermsPreflight] ); const menu = useMemo(() => { return { items: dropdownItems }; }, [dropdownItems]); return (
); };