NestJS backend rewrite; migrate client to FluentUI V9

This commit is contained in:
2025-09-18 15:48:08 +09:00
parent 32ff36a12c
commit 34529cea68
62 changed files with 5642 additions and 3679 deletions

View File

@ -1,10 +1,10 @@
import { ActionIcon, Button, Flex, Group, Stack, Text, TextInput } from "@mantine/core"
import { useEffect, useState } from "react"
import createReport, { listCommands } from 'docx-templates'
import { Dropzone, IMAGE_MIME_TYPE } from '@mantine/dropzone'
import { IconFileTypeDocx, IconPlus, IconUpload, IconX } from "@tabler/icons-react"
import { CommandSummary } from "docx-templates/lib/types"
import { Control, Controller, FieldValues, SubmitHandler, useFieldArray, useForm, UseFormRegister } from "react-hook-form"
import { Button, Field, Input, Text } from "@fluentui/react-components"
const xslTemplate = `<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
@ -1024,11 +1024,11 @@ const FormLoop = ({
})
return (
<Stack align="center">
<Stack w='100%' key={command.code}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }} key={command.code}>
{
fields.map((field, index) => (
<Flex w='100%' justify='space-between' align='flex-end' key={field.id}>
<div style={{ display: 'flex', width: '100%', justifyContent: 'space-between', alignItems: 'flex-end' }} key={field.id}>
{command.children &&
command.children.map(c =>
renderCommand(
@ -1040,27 +1040,25 @@ const FormLoop = ({
`${command.code}.${index}.${c.code}`
)
)}
<Button variant='subtle' onClick={() => {
<Button appearance='subtle' onClick={() => {
remove(index)
}}>
<IconX />
</Button>
</Flex>
</div>
))
}
</Stack>
</div>
<ActionIcon onClick={() => {
<Button icon={<IconPlus />} onClick={() => {
if (command.children) {
append(command.children.map(c => c.code).reduce((acc, key) => {
acc[key] = '';
return acc;
}, {} as Record<string, string>))
}
}}>
<IconPlus />
</ActionIcon>
</Stack>
}} />
</div>
)
}
@ -1074,18 +1072,17 @@ const renderCommand = (
) => {
if (command.type === 'INS') {
return (
<TextInput
label={label}
key={key}
{...register(name)}
/>
<Field label={label}
key={key}>
<Input {...register(name)} />
</Field>
)
}
if (command.type === 'IMAGE') {
return (
<Stack gap={0}>
<Text size='sm' fw={500}>{command.code}</Text>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<Text size={200} weight="semibold">{command.code}</Text>
<Controller
key={key}
name={name}
@ -1108,7 +1105,7 @@ const renderCommand = (
}}
maxFiles={1}
>
<Group justify="center" gap="xl" mih={220} style={{ pointerEvents: 'none' }}>
<div style={{ display: 'flex', justifyContent: 'center', gap: '2rem', minHeight: '220px', pointerEvents: 'none' }}>
<Dropzone.Accept>
<IconUpload size={52} color="var(--mantine-color-blue-6)" stroke={1.5} />
</Dropzone.Accept>
@ -1120,15 +1117,15 @@ const renderCommand = (
</Dropzone.Idle>
<div>
<Text size="xl" inline>
<Text size={300}>
Перетащите файлы сюда или нажмите, чтобы выбрать их
</Text>
</div>
</Group>
</div>
</Dropzone>
)}
/>
</Stack>
</div>
)
}
}
@ -1240,21 +1237,21 @@ const TemplateForm = ({
if (commandList) {
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Stack>
<div style={{ display: 'flex', flexDirection: 'column' }}>
{commandList.map(command => {
if (command.type === 'FOR') {
return (
<Stack gap={0} key={command.code}>
<Text size='sm' fw={500}>{command.code}</Text>
<div style={{ display: 'flex', flexDirection: 'column' }} key={command.code}>
<Text size={200} weight='semibold'>{command.code}</Text>
<FormLoop control={control} register={register} command={command} />
</Stack>
</div>
)
} else {
return renderCommand(control, register, command, command.code, command.code, command.code)
}
})}
<Button ml='auto' w='fit-content' type='submit'>Сохранить</Button>
</Stack>
<Button style={{ marginLeft: 'auto', width: 'fit-content' }} type='submit'>Сохранить</Button>
</div>
</form>
)
}
@ -1262,13 +1259,13 @@ const TemplateForm = ({
const PrintReport = () => {
return (
<Stack p='sm' gap='sm' w='100%'>
<div style={{ display: 'flex', flexDirection: 'column', padding: '1rem', gap: '1rem', width: '100%' }}>
<TemplateForm templateUrl="/template_table.docx" />
<Flex gap='sm'>
<div style={{ display: 'flex', gap: '1rem' }}>
<Button onClick={handleGenerateExcel}>Сохранить в Excel</Button>
</Flex>
</Stack>
</div>
</div>
)
}