diff --git a/package-lock.json b/package-lock.json index dd8107bf..08fd8aba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,7 +64,7 @@ "rollup-plugin-ignore": "^1.0.10", "rollup-plugin-polyfill-node": "^0.12.0", "typescript": "^5.1.6", - "vite": "^4.5.6", + "vite": "^4.5.5", "vite-plugin-node-polyfills": "^0.9.0", "vite-plugin-node-stdlib-browser": "^0.2.1", "vitest": "^1.6.0" @@ -9233,9 +9233,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001696", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", + "integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==", "funding": [ { "type": "opencollective", @@ -9249,7 +9249,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/ccount": { "version": "2.0.1", @@ -21472,11 +21473,10 @@ } }, "node_modules/vite": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.6.tgz", - "integrity": "sha512-ElBNuVvJKslxcfY2gMmae5IjaKGqCYGicCNZ+8R56sAznobeE3pI9ctzI17cBS/6OJh5YuQNMSN4BP4dRjugBg==", + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", + "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", diff --git a/package.json b/package.json index 979d3c72..9cca6a2a 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "rollup-plugin-ignore": "^1.0.10", "rollup-plugin-polyfill-node": "^0.12.0", "typescript": "^5.1.6", - "vite": "^4.5.6", + "vite": "^4.5.5", "vite-plugin-node-polyfills": "^0.9.0", "vite-plugin-node-stdlib-browser": "^0.2.1", "vitest": "^1.6.0" diff --git a/src/App.tsx b/src/App.tsx index 22d5a39e..c51451b9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -157,7 +157,7 @@ const App = () => { marginBottom: "10px", }} > -
+
diff --git a/src/components/FullScreenModal.tsx b/src/components/FullScreenModal.tsx index b3ee580a..821875a9 100644 --- a/src/components/FullScreenModal.tsx +++ b/src/components/FullScreenModal.tsx @@ -31,7 +31,7 @@ const FullScreenModal: React.FC = () => { }, [textColor, backgroundColor]); return ( -
+
setOpen(true)} diff --git a/src/components/SampleDropdown.tsx b/src/components/SampleDropdown.tsx index 00deb7da..3e7ff70a 100644 --- a/src/components/SampleDropdown.tsx +++ b/src/components/SampleDropdown.tsx @@ -1,42 +1,57 @@ -import { Button, Dropdown, Space, message } from "antd"; +import { Button, Dropdown, Space, message, MenuProps } from "antd"; import { DownOutlined } from "@ant-design/icons"; - +import { memo, useCallback, useMemo, useState } from "react"; import useAppStore from "../store/store"; +import { shallow } from "zustand/shallow"; -function SampleDropdown({ setLoading }: { setLoading: any }) { - const samples = useAppStore((state) => state.samples); - const loadSample = useAppStore((state) => state.loadSample); +function SampleDropdown({ + setLoading, +}: { + setLoading: React.Dispatch>; +}): JSX.Element { + const { samples, loadSample } = useAppStore( + (state) => ({ + samples: state.samples, + loadSample: state.loadSample as (key: string) => Promise, + }), + shallow + ); - const items = samples.map((s) => ({ - label: s.NAME, - key: s.NAME, - })); + const [selectedSample, setSelectedSample] = useState(null); - const handleMenuClick = async (e: any) => { - if (e.key) { - setLoading(true); - try { - await loadSample(e.key); - message.info(`Loaded ${e.key} sample`); - } catch (error) { - message.error("Failed to load sample"); - } finally { - setLoading(false); - } - } - }; + const items: MenuProps["items"] = useMemo( + () => + samples.map((s) => ({ + label: s.NAME, + key: s.NAME, + })), + [samples] + ); - const menuProps = { - items, - onClick: handleMenuClick, - }; + const handleMenuClick = useCallback( + async (e: any) => { + if (e.key) { + setLoading(true); + try { + await loadSample(e.key); + message.info(`Loaded ${e.key} sample`); + setSelectedSample(e.key); + } catch (error) { + message.error("Failed to load sample"); + } finally { + setLoading(false); + } + } + }, + [loadSample, setLoading] + ); return ( - +
@@ -44,4 +59,4 @@ function SampleDropdown({ setLoading }: { setLoading: any }) { ); } -export default SampleDropdown; +export default memo(SampleDropdown); diff --git a/src/store/store.ts b/src/store/store.ts index 3fb5aaac..09d32d8a 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -44,6 +44,8 @@ export interface DecompressedData { agreementHtml: string; } +const rebuildDeBounce = debounce(rebuild, 500); + async function rebuild(template: string, model: string, dataString: string) { const modelManager = new ModelManager({ strict: true }); modelManager.addCTOModel(model, undefined, true); @@ -67,8 +69,6 @@ async function rebuild(template: string, model: string, dataString: string) { ); } -const rebuildDeBounce = debounce(rebuild, 500); - const useAppStore = create()( immer( devtools((set, get) => ({ @@ -120,45 +120,42 @@ const useAppStore = create()( } }, rebuild: async () => { + const { templateMarkdown, modelCto, data } = get(); try { - const result = await rebuildDeBounce( - get().templateMarkdown, - get().modelCto, - get().data - ); + const result = await rebuildDeBounce(templateMarkdown, modelCto, data); set(() => ({ agreementHtml: result, error: undefined })); } catch (error: any) { set(() => ({ error: formatError(error) })); } }, setTemplateMarkdown: async (template: string) => { + const { modelCto, data } = get(); try { - const result = await rebuildDeBounce( - template, - get().modelCto, - get().data - ); - set(() => ({ agreementHtml: result, error: undefined })); + const result = await rebuildDeBounce(template, modelCto, data); + set(() => ({ + templateMarkdown: template, + agreementHtml: result, + error: undefined, + })); } catch (error: any) { set(() => ({ error: formatError(error) })); } - set(() => ({ templateMarkdown: template })); }, setEditorValue: (value: string) => { set(() => ({ editorValue: value })); }, setModelCto: async (model: string) => { + const { templateMarkdown, data } = get(); try { - const result = await rebuildDeBounce( - get().templateMarkdown, - model, - get().data - ); - set(() => ({ agreementHtml: result, error: undefined })); + const result = await rebuildDeBounce(templateMarkdown, model, data); + set(() => ({ + modelCto: model, + agreementHtml: result, + error: undefined, + })); } catch (error: any) { set(() => ({ error: formatError(error) })); } - set(() => ({ modelCto: model })); }, setEditorModelCto: (value: string) => { set(() => ({ editorModelCto: value })); diff --git a/src/styles/components/ToggleDarkMode.ts b/src/styles/components/ToggleDarkMode.ts index fa79f368..9aaa7401 100644 --- a/src/styles/components/ToggleDarkMode.ts +++ b/src/styles/components/ToggleDarkMode.ts @@ -2,7 +2,7 @@ import styled from "styled-components"; export const ToggleDarkModeContainer = styled.div` .dark-mode-toggle { - overflow: visible !important; + overflow: hidden !important; display: flex; padding-left: 10px !important; }