mirror of
https://github.com/Canner/WrenAI.git
synced 2026-10-30 18:22:21 +08:00
feat(wren-ui): UI integrating API - preview data (#63)
* feat(wren-ui): add home preview data API schema * feat(wren-ui): support preview data
This commit is contained in:
@@ -82,6 +82,13 @@ export type DeleteThreadMutationVariables = Types.Exact<{
|
||||
|
||||
export type DeleteThreadMutation = { __typename?: 'Mutation', deleteThread: boolean };
|
||||
|
||||
export type PreviewDataMutationVariables = Types.Exact<{
|
||||
where: Types.PreviewDataInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type PreviewDataMutation = { __typename?: 'Mutation', previewData: any };
|
||||
|
||||
export const CommonErrorFragmentDoc = gql`
|
||||
fragment CommonError on Error {
|
||||
code
|
||||
@@ -509,4 +516,35 @@ export function useDeleteThreadMutation(baseOptions?: Apollo.MutationHookOptions
|
||||
}
|
||||
export type DeleteThreadMutationHookResult = ReturnType<typeof useDeleteThreadMutation>;
|
||||
export type DeleteThreadMutationResult = Apollo.MutationResult<DeleteThreadMutation>;
|
||||
export type DeleteThreadMutationOptions = Apollo.BaseMutationOptions<DeleteThreadMutation, DeleteThreadMutationVariables>;
|
||||
export type DeleteThreadMutationOptions = Apollo.BaseMutationOptions<DeleteThreadMutation, DeleteThreadMutationVariables>;
|
||||
export const PreviewDataDocument = gql`
|
||||
mutation PreviewData($where: PreviewDataInput!) {
|
||||
previewData(where: $where)
|
||||
}
|
||||
`;
|
||||
export type PreviewDataMutationFn = Apollo.MutationFunction<PreviewDataMutation, PreviewDataMutationVariables>;
|
||||
|
||||
/**
|
||||
* __usePreviewDataMutation__
|
||||
*
|
||||
* To run a mutation, you first call `usePreviewDataMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `usePreviewDataMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [previewDataMutation, { data, loading, error }] = usePreviewDataMutation({
|
||||
* variables: {
|
||||
* where: // value for 'where'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function usePreviewDataMutation(baseOptions?: Apollo.MutationHookOptions<PreviewDataMutation, PreviewDataMutationVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useMutation<PreviewDataMutation, PreviewDataMutationVariables>(PreviewDataDocument, options);
|
||||
}
|
||||
export type PreviewDataMutationHookResult = ReturnType<typeof usePreviewDataMutation>;
|
||||
export type PreviewDataMutationResult = Apollo.MutationResult<PreviewDataMutation>;
|
||||
export type PreviewDataMutationOptions = Apollo.BaseMutationOptions<PreviewDataMutation, PreviewDataMutationVariables>;
|
||||
@@ -155,3 +155,9 @@ export const DELETE_THREAD = gql`
|
||||
deleteThread(where: $where)
|
||||
}
|
||||
`;
|
||||
|
||||
export const PREVIEW_DATA = gql`
|
||||
mutation PreviewData($where: PreviewDataInput!) {
|
||||
previewData(where: $where)
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -94,7 +94,7 @@ export const defaultApolloErrorHandler = (error: GraphQLError) => {
|
||||
locations: error.locations,
|
||||
path: error.path,
|
||||
message: error.message,
|
||||
extenstions: {
|
||||
extensions: {
|
||||
code,
|
||||
message: error.message,
|
||||
shortMessage: shortMessages[code],
|
||||
|
||||
@@ -10,6 +10,7 @@ type TableColumn = TableColumnProps<any> & { titleText?: string };
|
||||
interface Props {
|
||||
columns: TableColumn[];
|
||||
data: Array<any[]>;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const getValueByValueType = (value: any) =>
|
||||
@@ -31,7 +32,7 @@ const convertResultData = (data: Array<any>, columns) => {
|
||||
};
|
||||
|
||||
export default function PreviewDataContent(props: Props) {
|
||||
const { columns = [], data = [] } = props;
|
||||
const { columns = [], data = [], loading } = props;
|
||||
const hasColumns = !!columns.length;
|
||||
|
||||
const dynamicWidth = useMemo(() => {
|
||||
@@ -61,6 +62,7 @@ export default function PreviewDataContent(props: Props) {
|
||||
pagination={false}
|
||||
size="small"
|
||||
scroll={{ y: 280, x: dynamicWidth }}
|
||||
loading={loading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,10 +14,18 @@ interface Props {
|
||||
sql: string;
|
||||
}>;
|
||||
fullSql: string;
|
||||
threadResponseId: number;
|
||||
}
|
||||
|
||||
export default function AnswerResult(props: Props) {
|
||||
const { loading, question, description, answerResultSteps, fullSql } = props;
|
||||
const {
|
||||
loading,
|
||||
question,
|
||||
description,
|
||||
answerResultSteps,
|
||||
fullSql,
|
||||
threadResponseId,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Skeleton active loading={loading}>
|
||||
@@ -39,8 +47,9 @@ export default function AnswerResult(props: Props) {
|
||||
key={`${step.summary}-${index}`}
|
||||
sql={step.sql}
|
||||
fullSql={fullSql}
|
||||
stepNumber={index + 1}
|
||||
stepIndex={index}
|
||||
summary={step.summary}
|
||||
threadResponseId={threadResponseId}
|
||||
/>
|
||||
))}
|
||||
</Typography>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Button, Typography } from 'antd';
|
||||
import CopyOutlined from '@ant-design/icons/lib/icons/CopyOutlined';
|
||||
import UpCircleOutlined from '@ant-design/icons/UpCircleOutlined';
|
||||
import PreviewData from '@/components/pages/home/promptThread/PreviewData';
|
||||
import { PreviewDataMutationResult } from '@/apollo/client/graphql/home.generated';
|
||||
|
||||
const CodeBlock = dynamic(() => import('@/components/editor/CodeBlock'), {
|
||||
ssr: false,
|
||||
@@ -17,6 +18,7 @@ export interface Props {
|
||||
onCloseCollapse: () => void;
|
||||
onCopyFullSQL?: () => void;
|
||||
sql: string;
|
||||
previewDataResult: PreviewDataMutationResult;
|
||||
}
|
||||
|
||||
export default function CollapseContent(props: Props) {
|
||||
@@ -27,7 +29,9 @@ export default function CollapseContent(props: Props) {
|
||||
onCloseCollapse,
|
||||
onCopyFullSQL,
|
||||
sql,
|
||||
previewDataResult,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{(isViewSQL || isViewFullSQL) && (
|
||||
@@ -37,7 +41,7 @@ export default function CollapseContent(props: Props) {
|
||||
)}
|
||||
{isPreviewData && (
|
||||
<div className="my-2">
|
||||
<PreviewData sql={sql} />
|
||||
<PreviewData {...previewDataResult} />
|
||||
</div>
|
||||
)}
|
||||
{(isViewSQL || isPreviewData) && (
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,12 +12,14 @@ interface Props {
|
||||
fullSql: string;
|
||||
isLastStep: boolean;
|
||||
sql: string;
|
||||
stepNumber: number;
|
||||
stepIndex: number;
|
||||
summary: string;
|
||||
threadResponseId: number;
|
||||
}
|
||||
|
||||
export default function StepContent(props: Props) {
|
||||
const { fullSql, isLastStep, sql, stepNumber, summary } = props;
|
||||
const { fullSql, isLastStep, sql, stepIndex, summary, threadResponseId } =
|
||||
props;
|
||||
|
||||
const {
|
||||
collapseContentProps,
|
||||
@@ -28,8 +30,12 @@ export default function StepContent(props: Props) {
|
||||
fullSql,
|
||||
isLastStep,
|
||||
sql,
|
||||
threadResponseId,
|
||||
stepIndex,
|
||||
});
|
||||
|
||||
const stepNumber = stepIndex + 1;
|
||||
|
||||
return (
|
||||
<Row className="mb-3 bg-gray-2" wrap={false}>
|
||||
<Col flex="32px" className="p-2">
|
||||
|
||||
@@ -60,6 +60,7 @@ const AnswerResultTemplate = ({
|
||||
loading={status !== AskingTaskStatus.FINISHED}
|
||||
question={question}
|
||||
fullSql={detail?.sql}
|
||||
threadResponseId={id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,10 @@ import { useState } from 'react';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { message } from 'antd';
|
||||
import { COLLAPSE_CONTENT_TYPE } from '@/utils/enum';
|
||||
import {
|
||||
usePreviewDataMutation,
|
||||
PreviewDataMutationResult,
|
||||
} from '@/apollo/client/graphql/home.generated';
|
||||
|
||||
function getButtonProps({
|
||||
isLastStep,
|
||||
@@ -41,19 +45,31 @@ export default function useAnswerStepContent({
|
||||
fullSql,
|
||||
isLastStep,
|
||||
sql,
|
||||
stepIndex,
|
||||
threadResponseId,
|
||||
}: {
|
||||
fullSql: string;
|
||||
isLastStep: boolean;
|
||||
sql: string;
|
||||
stepIndex: number;
|
||||
threadResponseId: number;
|
||||
}) {
|
||||
const [collapseContentType, setCollapseContentType] =
|
||||
useState<COLLAPSE_CONTENT_TYPE>(COLLAPSE_CONTENT_TYPE.NONE);
|
||||
|
||||
const [previewData, previewDataResult] = usePreviewDataMutation({
|
||||
onError: (error) => console.error(error),
|
||||
});
|
||||
|
||||
const onViewSQL = () =>
|
||||
setCollapseContentType(COLLAPSE_CONTENT_TYPE.VIEW_SQL);
|
||||
|
||||
const onPreviewData = () =>
|
||||
const onPreviewData = () => {
|
||||
setCollapseContentType(COLLAPSE_CONTENT_TYPE.PREVIEW_DATA);
|
||||
previewData({
|
||||
variables: { where: { responseId: threadResponseId, stepIndex } },
|
||||
});
|
||||
};
|
||||
|
||||
const onCloseCollapse = () =>
|
||||
setCollapseContentType(COLLAPSE_CONTENT_TYPE.NONE);
|
||||
@@ -90,6 +106,11 @@ export default function useAnswerStepContent({
|
||||
isViewSQL,
|
||||
sql,
|
||||
}),
|
||||
previewDataResult: {
|
||||
error: previewDataResult.error,
|
||||
loading: previewDataResult.loading,
|
||||
previewData: previewDataResult?.data?.previewData,
|
||||
} as unknown as PreviewDataMutationResult,
|
||||
},
|
||||
...buttonProps,
|
||||
};
|
||||
|
||||
@@ -12,7 +12,8 @@ import { COLUMN_TYPE } from './enum';
|
||||
|
||||
export const getColumnTypeIcon = (payload: { type: string }, attrs?: any) => {
|
||||
const { type } = payload;
|
||||
switch (type.toUpperCase()) {
|
||||
const compareString = type.toUpperCase();
|
||||
switch (compareString) {
|
||||
case COLUMN_TYPE.INTEGER:
|
||||
case COLUMN_TYPE.TINYINT:
|
||||
case COLUMN_TYPE.SMALLINT:
|
||||
@@ -49,7 +50,16 @@ export const getColumnTypeIcon = (payload: { type: string }, attrs?: any) => {
|
||||
case COLUMN_TYPE.MONGO_ROW:
|
||||
return <JsonBracesIcon {...attrs} />;
|
||||
|
||||
default:
|
||||
default: {
|
||||
// int* or uint* or float*
|
||||
if (
|
||||
compareString.startsWith('INT') ||
|
||||
compareString.startsWith('UINT') ||
|
||||
compareString.startsWith('FLOAT')
|
||||
) {
|
||||
return <NumericIcon {...attrs} />;
|
||||
}
|
||||
return <ColumnsIcon {...attrs} />;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { GraphQLError } from 'graphql';
|
||||
import { ErrorResponse } from '@apollo/client/link/error';
|
||||
import { ApolloError } from '@apollo/client';
|
||||
import { message } from 'antd';
|
||||
|
||||
abstract class ErrorHandler {
|
||||
@@ -97,3 +98,14 @@ const errorHandler = (error: ErrorResponse) => {
|
||||
};
|
||||
|
||||
export default errorHandler;
|
||||
|
||||
export const parseGraphQLError = (error: ApolloError) => {
|
||||
const graphQLErrors: GraphQLError = error.graphQLErrors?.[0];
|
||||
const extensions = graphQLErrors.extensions;
|
||||
return {
|
||||
message: extensions.message as string,
|
||||
shortMessage: extensions.shortMessage as string,
|
||||
code: extensions.code as string,
|
||||
stacktrace: extensions?.stacktrace as Array<string> | undefined,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user