From c004f00e0be3f647f4a2623c1803e8e9224a1735 Mon Sep 17 00:00:00 2001 From: unni Date: Sat, 23 Aug 2025 11:49:17 +0530 Subject: [PATCH 1/4] feat: Added ui feedback when adding type in typesync --- packages/typesync-studio/src/routes/index.tsx | 67 +++++++++++++++++-- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/packages/typesync-studio/src/routes/index.tsx b/packages/typesync-studio/src/routes/index.tsx index e3eee174..d2e2ad81 100644 --- a/packages/typesync-studio/src/routes/index.tsx +++ b/packages/typesync-studio/src/routes/index.tsx @@ -16,7 +16,7 @@ import { import { createFormHook, useStore } from '@tanstack/react-form'; import { createFileRoute } from '@tanstack/react-router'; import { Array as EffectArray, String as EffectString, Option, pipe, Schema } from 'effect'; -import { useState } from 'react'; +import { useState, useEffect, useRef } from 'react'; import { Arrow } from '@/Components/Arrow.tsx'; import { Checkbox } from '@/Components/Form/Checkbox.tsx'; @@ -113,6 +113,13 @@ function SchemaBuilderComponent() { }); }, }); + + + // Create a ref to store DOM references for each type + const typeRefs = useRef>(new Map()); + // State to track the index of the newly added type + const [newTypeIndex, setNewTypeIndex] = useState(null); + const appTypes = useStore(createSchemaForm.store, (state) => pipe( state.values.types, @@ -379,6 +386,18 @@ function SchemaBuilderComponent() { return propRelationSchemaTypes; }; + // Effect to scroll to the newly added type + useEffect(() => { + if (newTypeIndex !== null) { + const element = typeRefs.current.get(newTypeIndex); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + // Reset newTypeIndex after scrolling + setNewTypeIndex(null); + } + }, [newTypeIndex]); + return (
{ @@ -448,12 +472,15 @@ function SchemaBuilderComponent() { knowledgeGraphId: mapped.knowledgeGraphId, properties: mapped.properties, } as never); + newIndex = 0; return; } field.pushValue(mapped as never); + newIndex =idx; }); // push selected type field.pushValue(selectedMappedToType as never); + newIndex = field.state.value.length - 1; }, }); return; @@ -471,11 +498,20 @@ function SchemaBuilderComponent() { knowledgeGraphId: mapped.knowledgeGraphId, properties: mapped.properties, } as never); + newIndex = field.state.value.length - 1; }); // push selected type field.pushValue(selectedMappedToType as never); + newIndex = field.state.value.length - 1; }, }); + + setNewTypeIndex(newIndex); + toastManager.add({ + title:'Type added to schema', + description: selected.name, + type: 'success', + }) return; }} /> @@ -495,6 +531,13 @@ function SchemaBuilderComponent() { return (
{ + if (el) { + typeRefs.current.set(idx, el); + } else { + typeRefs.current.delete(idx); + } + }} className="border-l-2 border-indigo-600 dark:border-indigo-400 pl-2 py-2 flex flex-col gap-y-4" >
@@ -860,12 +903,23 @@ function SchemaBuilderComponent() {
-
@@ -874,7 +928,12 @@ function SchemaBuilderComponent() {
From 0284a1bf0d3fec30d2438c6d34b16d5c6e64172d Mon Sep 17 00:00:00 2001 From: unniznd Date: Tue, 26 Aug 2025 23:31:22 +0530 Subject: [PATCH 2/4] fix: removed useEffect for scroll --- packages/typesync-studio/src/routes/index.tsx | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/typesync-studio/src/routes/index.tsx b/packages/typesync-studio/src/routes/index.tsx index d2e2ad81..7eeac8b5 100644 --- a/packages/typesync-studio/src/routes/index.tsx +++ b/packages/typesync-studio/src/routes/index.tsx @@ -16,7 +16,7 @@ import { import { createFormHook, useStore } from '@tanstack/react-form'; import { createFileRoute } from '@tanstack/react-router'; import { Array as EffectArray, String as EffectString, Option, pipe, Schema } from 'effect'; -import { useState, useEffect, useRef } from 'react'; +import { useState, useRef } from 'react'; import { Arrow } from '@/Components/Arrow.tsx'; import { Checkbox } from '@/Components/Form/Checkbox.tsx'; @@ -386,18 +386,6 @@ function SchemaBuilderComponent() { return propRelationSchemaTypes; }; - // Effect to scroll to the newly added type - useEffect(() => { - if (newTypeIndex !== null) { - const element = typeRefs.current.get(newTypeIndex); - if (element) { - element.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - // Reset newTypeIndex after scrolling - setNewTypeIndex(null); - } - }, [newTypeIndex]); - return ( { + const element = typeRefs.current.get(newIndex); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }, 0); setNewTypeIndex(newIndex); toastManager.add({ title:'Type added to schema', From 1e0a4ca1214d99679f2dc627852a7b3d9da0db89 Mon Sep 17 00:00:00 2001 From: unniznd Date: Wed, 27 Aug 2025 21:43:07 +0530 Subject: [PATCH 3/4] fix: clean up code formatting and improve readability in SchemaBuilderComponent --- packages/typesync-studio/src/routes/index.tsx | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/typesync-studio/src/routes/index.tsx b/packages/typesync-studio/src/routes/index.tsx index 7eeac8b5..41113733 100644 --- a/packages/typesync-studio/src/routes/index.tsx +++ b/packages/typesync-studio/src/routes/index.tsx @@ -16,7 +16,7 @@ import { import { createFormHook, useStore } from '@tanstack/react-form'; import { createFileRoute } from '@tanstack/react-router'; import { Array as EffectArray, String as EffectString, Option, pipe, Schema } from 'effect'; -import { useState, useRef } from 'react'; +import { useRef, useState } from 'react'; import { Arrow } from '@/Components/Arrow.tsx'; import { Checkbox } from '@/Components/Form/Checkbox.tsx'; @@ -114,11 +114,10 @@ function SchemaBuilderComponent() { }, }); - // Create a ref to store DOM references for each type const typeRefs = useRef>(new Map()); // State to track the index of the newly added type - const [newTypeIndex, setNewTypeIndex] = useState(null); + const [_newTypeIndex, setNewTypeIndex] = useState(null); const appTypes = useStore(createSchemaForm.store, (state) => pipe( @@ -464,7 +463,7 @@ function SchemaBuilderComponent() { return; } field.pushValue(mapped as never); - newIndex =idx; + newIndex = idx; }); // push selected type field.pushValue(selectedMappedToType as never); @@ -501,10 +500,10 @@ function SchemaBuilderComponent() { }, 0); setNewTypeIndex(newIndex); toastManager.add({ - title:'Type added to schema', + title: 'Type added to schema', description: selected.name, - type: 'success', - }) + type: 'success', + }); return; }} /> @@ -898,9 +897,11 @@ function SchemaBuilderComponent() { toast={t} className={classnames( 'pointer-events-auto w-full max-w-md rounded-lg shadow-lg outline-1 transition data-closed:opacity-0 data-enter:transform data-enter:duration-300 data-enter:ease-out data-closed:data-enter:translate-y-2 data-leave:duration-100 data-leave:ease-in data-closed:data-enter:sm:translate-x-2 data-closed:data-enter:sm:translate-y-0 p-4', - t.type === 'success' ? 'bg-green-50 dark:bg-green-900 outline-green-500/20' : - t.type === 'error' ? 'bg-red-50 dark:bg-red-900 outline-red-500/20' : - 'bg-white dark:bg-gray-800 outline-black/5 dark:outline-white/10' + t.type === 'success' + ? 'bg-green-50 dark:bg-green-900 outline-green-500/20' + : t.type === 'error' + ? 'bg-red-50 dark:bg-red-900 outline-red-500/20' + : 'bg-white dark:bg-gray-800 outline-black/5 dark:outline-white/10', )} >
@@ -923,9 +924,11 @@ function SchemaBuilderComponent() { aria-label="Close" className={classnames( 'inline-flex rounded-md focus:outline-2 focus:outline-offset-2', - t.type === 'success' ? 'text-green-400 hover:text-green-500 focus:outline-green-600 dark:focus:outline-green-500' : - t.type === 'error' ? 'text-red-400 hover:text-red-500 focus:outline-red-600 dark:focus:outline-red-500' : - 'text-gray-400 hover:text-gray-500 focus:outline-gray-600 dark:hover:text-white dark:focus:outline-gray-500' + t.type === 'success' + ? 'text-green-400 hover:text-green-500 focus:outline-green-600 dark:focus:outline-green-500' + : t.type === 'error' + ? 'text-red-400 hover:text-red-500 focus:outline-red-600 dark:focus:outline-red-500' + : 'text-gray-400 hover:text-gray-500 focus:outline-gray-600 dark:hover:text-white dark:focus:outline-gray-500', )} >