feat: alert info and lodash to lodash-es

This commit is contained in:
Joel 2025-10-24 11:24:19 +08:00
parent 0af0c94dde
commit 4c1f9b949b
7 changed files with 106 additions and 60 deletions

View File

@ -15,7 +15,7 @@ import Switch from '@/app/components/base/switch'
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card'
import { Resolution } from '@/types/app'
import { noop } from 'lodash'
import { noop } from 'lodash-es'
import cn from '@/utils/classnames'
const ConfigVision: FC = () => {

View File

@ -0,0 +1,59 @@
import {
memo,
} from 'react'
import {
RiCloseLine,
RiInformation2Fill,
} from '@remixicon/react'
import { cva } from 'class-variance-authority'
import cn from '@/utils/classnames'
type Props = {
type?: 'info'
message: string
onHide: () => void
className?: string
}
const bgVariants = cva(
'',
{
variants: {
type: {
info: 'from-components-badge-status-light-normal-halo to-background-gradient-mask-transparent',
},
},
},
)
const Alert: React.FC<Props> = ({
type = 'info',
message,
onHide,
className,
}) => {
return (
<div className={cn('pointer-events-none flex w-full justify-center', className)}>
<div
className='relative flex w-[420px] space-x-1 overflow-hidden rounded-xl border border-components-panel-border bg-components-panel-bg-blur p-3 shadow-lg'
>
<div className={cn('pointer-events-none absolute inset-0 bg-gradient-to-r opacity-[0.4]', bgVariants({ type }))}>
</div>
<div className='flex h-6 w-6 items-center justify-center'>
<RiInformation2Fill className='text-text-accent' />
</div>
<div className='p-1'>
<div className='system-xs-regular text-text-secondary'>
{message}
</div>
</div>
<div
className='pointer-events-auto flex h-6 w-6 cursor-pointer items-center justify-center'
onClick={onHide}
>
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
</div>
</div>
</div>
)
}
export default memo(Alert)

View File

@ -13,7 +13,7 @@ import ActionButton from '@/app/components/base/action-button'
import { FileUploaderInChatInput } from '@/app/components/base/file-uploader'
import type { FileUpload } from '@/app/components/base/features/types'
import cn from '@/utils/classnames'
import { noop } from 'lodash'
import { noop } from 'lodash-es'
type OperationProps = {
readonly?: boolean

View File

@ -15,11 +15,12 @@ import { userInputsFormToPromptVariables } from '@/utils/model-config'
import type { VisionFile, VisionSettings } from '@/types/app'
import { Resolution, TransferMethod } from '@/types/app'
import { useBoolean } from 'ahooks'
import { noop } from 'lodash'
import { noop } from 'lodash-es'
import type { Task } from '../../../share/text-generation/types'
import Res from '@/app/components/share/text-generation/result'
import { AppSourceType } from '@/service/share'
import { TaskStatus } from '@/app/components/share/text-generation/types'
import Alert from '@/app/components/base/alert'
type Props = {
appId: string
@ -144,19 +145,13 @@ const TextGeneration: FC<Props> = ({
<div
className={cn(
'relative flex h-full flex-col',
!isPC && 'h-[calc(100vh_-_36px)] rounded-t-2xl shadow-lg backdrop-blur-sm',
!isPC
? isShowResultPanel
? 'bg-background-default-burn'
: 'border-t-[0.5px] border-divider-regular bg-components-panel-bg'
: 'bg-chatbot-bg',
'bg-chatbot-bg',
)}
>
<div className={cn(
'flex h-0 grow flex-col overflow-y-auto',
isPC && 'px-14 py-8',
!isPC && 'p-0 pb-2',
'flex h-0 grow flex-col overflow-y-auto p-6',
)}>
<Alert className='mb-3 shrink-0' message='This is a sample app. You can try up to 5 messages. To keep using it, click “Create form this sample app” and set it up!' onHide={noop} />
{renderRes()}
</div>
</div>
@ -220,15 +215,7 @@ const TextGeneration: FC<Props> = ({
</div>
{/* Result */}
<div className={cn(
isPC
? 'h-full w-0 grow'
: isShowResultPanel
? 'fixed inset-0 z-50 bg-background-overlay backdrop-blur-sm'
: resultExisted
? 'relative h-16 shrink-0 overflow-hidden bg-background-default-burn pt-2.5'
: '',
)}>
<div className={cn('h-full w-0 grow')}>
{!isPC && (
<div
className={cn(

View File

@ -31,7 +31,7 @@ const TryApp: FC<Props> = ({
<Modal
isShow
onClose={onClose}
className='h-[calc(100vh-32px)] max-w-[calc(100vw-32px)] p-2'
className='h-[calc(100vh-32px)] min-w-[1280px] max-w-[calc(100vw-32px)] overflow-x-auto p-2'
>
{isLoading ? (<div className='flex h-full items-center justify-center'>
<Loading type='area' />

View File

@ -2,19 +2,19 @@
const fs = require('fs')
const path = require('path')
const { camelCase } = require('lodash')
const { camelCase } = require('lodash-es')
// Import the NAMESPACES array from i18next-config.ts
function getNamespacesFromConfig() {
const configPath = path.join(__dirname, 'i18next-config.ts')
const configContent = fs.readFileSync(configPath, 'utf8')
// Extract NAMESPACES array using regex
const namespacesMatch = configContent.match(/const NAMESPACES = \[([\s\S]*?)\]/)
if (!namespacesMatch) {
throw new Error('Could not find NAMESPACES array in i18next-config.ts')
}
// Parse the namespaces
const namespacesStr = namespacesMatch[1]
const namespaces = namespacesStr
@ -22,25 +22,25 @@ function getNamespacesFromConfig() {
.map(line => line.trim())
.filter(line => line.startsWith("'") || line.startsWith('"'))
.map(line => line.slice(1, -1)) // Remove quotes
return namespaces
}
function getNamespacesFromTypes() {
const typesPath = path.join(__dirname, '../types/i18n.d.ts')
if (!fs.existsSync(typesPath)) {
return null
}
const typesContent = fs.readFileSync(typesPath, 'utf8')
// Extract namespaces from Messages type
const messagesMatch = typesContent.match(/export type Messages = \{([\s\S]*?)\}/)
if (!messagesMatch) {
return null
}
// Parse the properties
const propertiesStr = messagesMatch[1]
const properties = propertiesStr
@ -49,66 +49,66 @@ function getNamespacesFromTypes() {
.filter(line => line.includes(':'))
.map(line => line.split(':')[0].trim())
.filter(prop => prop.length > 0)
return properties
}
function main() {
try {
console.log('🔍 Checking i18n types synchronization...')
// Get namespaces from config
const configNamespaces = getNamespacesFromConfig()
console.log(`📦 Found ${configNamespaces.length} namespaces in config`)
// Convert to camelCase for comparison
const configCamelCase = configNamespaces.map(ns => camelCase(ns)).sort()
// Get namespaces from type definitions
const typeNamespaces = getNamespacesFromTypes()
if (!typeNamespaces) {
console.error('❌ Type definitions file not found or invalid')
console.error(' Run: pnpm run gen:i18n-types')
process.exit(1)
}
console.log(`🔧 Found ${typeNamespaces.length} namespaces in types`)
const typeCamelCase = typeNamespaces.sort()
// Compare arrays
const configSet = new Set(configCamelCase)
const typeSet = new Set(typeCamelCase)
// Find missing in types
const missingInTypes = configCamelCase.filter(ns => !typeSet.has(ns))
// Find extra in types
const extraInTypes = typeCamelCase.filter(ns => !configSet.has(ns))
let hasErrors = false
if (missingInTypes.length > 0) {
hasErrors = true
console.error('❌ Missing in type definitions:')
missingInTypes.forEach(ns => console.error(` - ${ns}`))
}
if (extraInTypes.length > 0) {
hasErrors = true
console.error('❌ Extra in type definitions:')
extraInTypes.forEach(ns => console.error(` - ${ns}`))
}
if (hasErrors) {
console.error('\n💡 To fix synchronization issues:')
console.error(' Run: pnpm run gen:i18n-types')
process.exit(1)
}
console.log('✅ i18n types are synchronized')
} catch (error) {
console.error('❌ Error:', error.message)
process.exit(1)
@ -117,4 +117,4 @@ function main() {
if (require.main === module) {
main()
}
}

View File

@ -2,19 +2,19 @@
const fs = require('fs')
const path = require('path')
const { camelCase } = require('lodash')
const { camelCase } = require('lodash-es')
// Import the NAMESPACES array from i18next-config.ts
function getNamespacesFromConfig() {
const configPath = path.join(__dirname, 'i18next-config.ts')
const configContent = fs.readFileSync(configPath, 'utf8')
// Extract NAMESPACES array using regex
const namespacesMatch = configContent.match(/const NAMESPACES = \[([\s\S]*?)\]/)
if (!namespacesMatch) {
throw new Error('Could not find NAMESPACES array in i18next-config.ts')
}
// Parse the namespaces
const namespacesStr = namespacesMatch[1]
const namespaces = namespacesStr
@ -22,7 +22,7 @@ function getNamespacesFromConfig() {
.map(line => line.trim())
.filter(line => line.startsWith("'") || line.startsWith('"'))
.map(line => line.slice(1, -1)) // Remove quotes
return namespaces
}
@ -90,40 +90,40 @@ declare module 'i18next' {
function main() {
const args = process.argv.slice(2)
const checkMode = args.includes('--check')
try {
console.log('📦 Generating i18n type definitions...')
// Get namespaces from config
const namespaces = getNamespacesFromConfig()
console.log(`✅ Found ${namespaces.length} namespaces`)
// Generate type definitions
const typeDefinitions = generateTypeDefinitions(namespaces)
const outputPath = path.join(__dirname, '../types/i18n.d.ts')
if (checkMode) {
// Check mode: compare with existing file
if (!fs.existsSync(outputPath)) {
console.error('❌ Type definitions file does not exist')
process.exit(1)
}
const existingContent = fs.readFileSync(outputPath, 'utf8')
if (existingContent.trim() !== typeDefinitions.trim()) {
console.error('❌ Type definitions are out of sync')
console.error(' Run: pnpm run gen:i18n-types')
process.exit(1)
}
console.log('✅ Type definitions are in sync')
} else {
// Generate mode: write file
fs.writeFileSync(outputPath, typeDefinitions)
console.log(`✅ Generated type definitions: ${outputPath}`)
}
} catch (error) {
console.error('❌ Error:', error.message)
process.exit(1)
@ -132,4 +132,4 @@ function main() {
if (require.main === module) {
main()
}
}