add template-function-datetime (#244)

This commit is contained in:
Song
2025-07-24 03:41:24 +08:00
committed by GitHub
parent c09083ddec
commit 0b38948826
20 changed files with 331 additions and 51 deletions

View File

@@ -11,10 +11,10 @@ import {
import { useToggle } from '../hooks/useToggle';
import { convertTemplateToInsecure } from '../lib/encryption';
import { setupOrConfigureEncryption } from '../lib/setupOrConfigureEncryption';
import { Banner } from './core/Banner';
import { Button } from './core/Button';
import { IconButton } from './core/IconButton';
import { InlineCode } from './core/InlineCode';
import { LoadingIcon } from './core/LoadingIcon';
import { PlainInput } from './core/PlainInput';
import { HStack, VStack } from './core/Stacks';
import { DYNAMIC_FORM_NULL_ARG, DynamicForm } from './DynamicForm';
@@ -178,7 +178,10 @@ function InitializedTemplateFunctionDialog({
{enablePreview && (
<VStack className="w-full" space={1}>
<HStack space={0.5}>
<div className="text-sm text-text-subtle">Rendered Preview</div>
<HStack className="text-sm text-text-subtle" space={1.5}>
Rendered Preview
{rendered.isPending && <LoadingIcon size="xs" />}
</HStack>
<IconButton
size="xs"
iconSize="sm"
@@ -191,26 +194,24 @@ function InitializedTemplateFunctionDialog({
)}
/>
</HStack>
{rendered.error || tagText.error ? (
<Banner color="danger">{`${rendered.error || tagText.error}`}</Banner>
) : (
<InlineCode
className={classNames(
'whitespace-pre select-text cursor-text max-h-[10rem] overflow-y-auto hide-scrollbars',
tooLarge && 'italic text-danger',
)}
>
{dataContainsSecrets && !showSecretsInPreview ? (
<span className="italic text-text-subtle">
------ sensitive values hidden ------
</span>
) : tooLarge ? (
'too large to preview'
) : (
rendered.data || <>&nbsp;</>
)}
</InlineCode>
)}
<InlineCode
className={classNames(
'whitespace-pre-wrap select-text cursor-text max-h-[10rem] overflow-y-auto hide-scrollbars',
tooLarge && 'italic text-danger',
)}
>
{rendered.error || tagText.error ? (
<em className="text-danger">
{`${rendered.error || tagText.error}`.replace(/^Render Error: /, '')}
</em>
) : dataContainsSecrets && !showSecretsInPreview ? (
<span className="italic text-text-subtle">------ sensitive values hidden ------</span>
) : tooLarge ? (
'too large to preview'
) : (
rendered.data || <>&nbsp;</>
)}
</InlineCode>
</VStack>
)}
<div className="flex justify-stretch w-full flex-grow gap-2 [&>*]:flex-1">

View File

@@ -279,7 +279,7 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
const show = () =>
showDialog({
id: 'template-function-' + Math.random(), // Allow multiple at once
size: 'sm',
size: 'md',
title: <InlineCode>{fn.name}()</InlineCode>,
description: fn.description,
render: ({ hide }) => (

View File

@@ -142,7 +142,7 @@ export const Icon = memo(function Icon({
title={title}
className={classNames(
className,
!spin && 'transform-cpu',
!spin && 'transform-gpu',
spin && 'animate-spin',
'flex-shrink-0',
size === 'xl' && 'h-6 w-6',

View File

@@ -9,6 +9,7 @@ type Props = Omit<TooltipProps, 'children'> & {
iconSize?: IconProps['size'];
iconColor?: IconProps['color'];
className?: string;
tabIndex?: number;
};
export function IconTooltip({

View File

@@ -519,7 +519,7 @@ function EncryptionInput({
color="danger"
size={props.size}
className="text-sm"
rightSlot={<IconTooltip content={state.error} icon="alert_triangle" />}
rightSlot={<IconTooltip tabIndex={-1} content={state.error} icon="alert_triangle" />}
onClick={() => {
setupOrConfigureEncryption();
}}

View File

@@ -39,7 +39,7 @@ export function Label({
({tag})
</span>
))}
{help && <IconTooltip content={help} />}
{help && <IconTooltip tabIndex={-1} content={help} />}
</label>
);
}

View File

@@ -1,5 +1,6 @@
import { useQuery } from '@tanstack/react-query';
import { useAtomValue } from 'jotai';
import { minPromiseMillis } from '../lib/minPromiseMillis';
import { invokeCmd } from '../lib/tauri';
import { useActiveEnvironment } from './useActiveEnvironment';
import { activeWorkspaceIdAtom } from './useActiveWorkspace';
@@ -8,10 +9,9 @@ export function useRenderTemplate(template: string) {
const workspaceId = useAtomValue(activeWorkspaceIdAtom) ?? 'n/a';
const environmentId = useActiveEnvironment()?.id ?? null;
return useQuery<string>({
placeholderData: (prev) => prev, // Keep previous data on refetch
refetchOnWindowFocus: false,
queryKey: ['render_template', template, workspaceId, environmentId],
queryFn: () => renderTemplate({ template, workspaceId, environmentId }),
queryFn: () => minPromiseMillis(renderTemplate({ template, workspaceId, environmentId }), 200),
});
}

View File

@@ -4,7 +4,6 @@ import { invokeCmd } from '../lib/tauri';
export function useTemplateTokensToString(tokens: Tokens) {
return useQuery<string>({
placeholderData: (prev) => prev, // Keep previous data on refetch
refetchOnWindowFocus: false,
queryKey: ['template_tokens_to_string', tokens],
queryFn: () => templateTokensToString(tokens),