@@ -21,6 +21,8 @@ import WidgetItem from "@/components/widgets/widget-item.tsx";
2121import "react-grid-layout/css/styles.css" ;
2222import "react-resizable/css/styles.css" ;
2323import { usePage } from "@inertiajs/react" ;
24+ import { WidgetsLayouts } from "@/lib/widgets-service.ts" ;
25+
2426
2527interface WidgetLayoutProps extends SharedData {
2628 title : string
@@ -33,15 +35,35 @@ interface WidgetLayoutProps extends SharedData {
3335
3436const WidgetLayout = ( ) => {
3537 const ResponsiveGridLayout = useMemo ( ( ) => WidthProvider ( Responsive ) , [ ] ) ;
36- const [ layout , setLayout ] = useState < WidgetLayoutItem [ ] > ( [ ] ) ;
38+ const [ layout , setLayout ] = useState < WidgetsLayouts > ( {
39+ lg : [ ] ,
40+ md : [ ] ,
41+ sm : [ ] ,
42+ xs : [ ] ,
43+ xxs : [ ] ,
44+ } ) ;
3745 const [ widgets , setWidgets ] = useState < Widget [ ] > ( [ ] )
3846 const [ popUpDisabled , setPopUpDisabled ] = useState ( false )
3947 const [ keyRender , setKeyRender ] = useState ( 0 ) ;
4048 const [ loading , setIsLoading ] = useState ( true )
4149 const [ isDraggable , setIsDraggable ] = useState ( false )
50+ const [ gridRef , setGridRef ] = useState < HTMLDivElement | null > ( null ) ;
4251
4352 const page = usePage < WidgetLayoutProps > ( )
4453
54+ // Get the current breakpoint
55+ const getCurrentBreakpoint = useCallback ( ( ) => {
56+ if ( ! gridRef ) return 'lg' ; // fallback
57+
58+ const width = gridRef . clientWidth ;
59+
60+ if ( width >= 1200 ) return 'lg' ;
61+ if ( width >= 996 ) return 'md' ;
62+ if ( width >= 768 ) return 'sm' ;
63+ if ( width >= 480 ) return 'xs' ;
64+ return 'xxs' ;
65+ } , [ gridRef ] ) ;
66+
4567 useEffect ( ( ) => {
4668 async function loadWidgets ( ) {
4769 try {
@@ -70,67 +92,69 @@ const WidgetLayout = () => {
7092 } , [ layout , isDraggable ] )
7193
7294 const handleLayoutChange = ( currentLayout : WidgetLayoutItem [ ] ) => {
95+ const currentBreakpoint = getCurrentBreakpoint ( ) ;
7396
74- const mergeCoordinates = ( layout : WidgetLayoutItem [ ] , currentLayout : WidgetLayoutItem [ ] ) => {
75- // Создаем копию первого массива, чтобы не изменять оригинал
76- const result = JSON . parse ( JSON . stringify ( layout ) ) ;
97+ setLayout ( prev => {
98+ const updatedLayout = { ... prev } ;
99+ const currentLayoutMap = new Map ( currentLayout . map ( item => [ item . i , item ] ) ) ;
77100
78- // Создаем карту для быстрого поиска элементов по полю 'i'
79- const secondMap = new Map ( ) ;
80- currentLayout . forEach ( item => secondMap . set ( item . i , item ) ) ;
81-
82- // Обновляем координаты в первом массиве
83- result . forEach ( ( item : WidgetLayoutItem ) => {
84- const secondItem = secondMap . get ( item . i ) ;
85- if ( secondItem ) {
86- item . x = secondItem . x ;
87- item . y = secondItem . y ;
88- }
89- } ) ;
101+ updatedLayout [ currentBreakpoint as keyof WidgetsLayouts ] =
102+ updatedLayout [ currentBreakpoint as keyof WidgetsLayouts ] . map ( item => {
103+ const currentItem = currentLayoutMap . get ( item . i ) ;
104+ return currentItem ? { ...item , x : currentItem . x , y : currentItem . y , w : currentItem . w , h : currentItem . h } : item ;
105+ } ) ;
90106
91- return result ;
92- }
93- setLayout ( mergeCoordinates ( layout , currentLayout ) )
107+ return updatedLayout ;
108+ } ) ;
94109 } ;
95110
96111 const addWidgets = useCallback ( ( id : string ) => {
97112 setPopUpDisabled ( true ) ;
98113 const updatedWidgets = widgets . map ( widget =>
99- widget . id === id
100- ? { ...widget , added : ! widget . added }
101- : widget
114+ widget . id === id ? { ...widget , added : ! widget . added } : widget
102115 ) ;
103116
104- const layoutItem = layout . find ( e => e . id === id ) ;
105- let newLayout : WidgetLayoutItem [ ] ;
117+ const currentLayout = layout . lg ;
118+ const layoutItem = currentLayout . find ( e => e . i === id ) ;
119+ let newLayout : WidgetsLayouts = { ...layout } ;
106120
107121 if ( layoutItem ) {
108- newLayout = layout . filter ( e => e . id !== id ) ;
122+ // Delete the layoutItem from all breakpoints
123+ for ( const breakpoint in newLayout ) {
124+ newLayout [ breakpoint as keyof WidgetsLayouts ] =
125+ newLayout [ breakpoint as keyof WidgetsLayouts ] . filter ( e => e . i !== id ) ;
126+ }
109127 } else {
110128 const widget = widgets . find ( e => e . id === id ) ;
111129 const w = widget ?. size ? widget . size . w : 1 ;
112130 const h = widget ?. size ? widget . size . h : 1 ;
113131
114- let x = layout . length === 0
115- ? 0
116- : ( ( layout [ layout . length - 1 ] . x + layout [ layout . length - 1 ] . w ) > 8 ||
117- ( layout [ layout . length - 1 ] . x + layout [ layout . length - 1 ] . w + w ) > 8
132+ let x = currentLayout . length === 0 ? 0 :
133+ ( ( currentLayout [ currentLayout . length - 1 ] . x + currentLayout [ currentLayout . length - 1 ] . w ) > 8 ||
134+ ( currentLayout [ currentLayout . length - 1 ] . x + currentLayout [ currentLayout . length - 1 ] . w + w ) > 8
118135 ? 0
119- : ( layout [ layout . length - 1 ] . x + layout [ layout . length - 1 ] . w ) ) ;
136+ : ( currentLayout [ currentLayout . length - 1 ] . x + currentLayout [ currentLayout . length - 1 ] . w ) ) ;
120137
121138 const y = 0 ;
122139
123- newLayout = [
124- ...layout ,
125- {
126- x : x ,
127- y : y ,
128- w : w ,
129- h : h ,
130- i : String ( layout . length + 1 ) ,
131- id : widget ?. id as string ,
140+ const newItem = {
141+ x,
142+ y,
143+ w,
144+ h,
145+ i : id ,
146+ id : widget ?. id as string ,
147+ } ;
148+
149+ // Add the newItem to all breakpoints
150+ for ( const breakpoint in newLayout ) {
151+ if ( ! newLayout [ breakpoint as keyof WidgetsLayouts ] . some ( item => item . i === id ) ) {
152+ newLayout [ breakpoint as keyof WidgetsLayouts ] = [
153+ ...newLayout [ breakpoint as keyof WidgetsLayouts ] ,
154+ { ...newItem }
155+ ] ;
132156 }
133- ] ;
157+ }
134158 }
135159
136160 setWidgets ( updatedWidgets ) ;
@@ -140,12 +164,11 @@ const WidgetLayout = () => {
140164 addWidgetsDB ( updatedWidgets , newLayout ) . then ( ( ) => {
141165 setTimeout ( ( ) => {
142166 setPopUpDisabled ( false ) ;
143- } , 300 )
144- } )
145-
167+ } , 300 ) ;
168+ } ) ;
146169 } , [ layout , widgets ] ) ;
147170
148- const addWidgetsDB = useCallback ( async ( updatedWidgets : Widget [ ] , newLayout : WidgetLayoutItem [ ] ) => {
171+ const addWidgetsDB = useCallback ( async ( updatedWidgets : Widget [ ] , newLayout : WidgetsLayouts ) => {
149172 try {
150173 const storeWidgets = updatedWidgets . filter ( widget => widget . added === true )
151174 await axios . post ( `${ window . routePrefix } /widgets-get-all-db` , {
@@ -161,6 +184,7 @@ const WidgetLayout = () => {
161184 console . log ( e ) ;
162185 }
163186 } , [ widgets ] )
187+
164188 return (
165189 < div
166190 className = { `flex h-full flex-1 flex-col gap-4 rounded-xl p-4 ` } >
@@ -212,28 +236,32 @@ const WidgetLayout = () => {
212236 </ DialogStackTitle >
213237 < div className = "overflow-auto h-[calc(100%-64px)] pr-4 pt-4" >
214238 < AddWidgets initWidgets = { widgets } onAddWidgets = { addWidgets }
215- disabled = { popUpDisabled } searchPlaceholder = { page . props . searchPlaceholder } actionsTitles = { page . props . actionsTitles } />
239+ disabled = { popUpDisabled }
240+ searchPlaceholder = { page . props . searchPlaceholder }
241+ actionsTitles = { page . props . actionsTitles } />
216242 </ div >
217243 </ div >
218244 </ DialogStackContent >
219245 </ DialogStackBody >
220246 </ DialogStack >
221247 </ div >
222248 </ div >
223- < div >
224- { layout . length > 0 ? (
249+ < div ref = { setGridRef } >
250+ { layout . lg . length > 0 ? (
225251 < ResponsiveGridLayout
226- layouts = { { lg : layout } }
227- breakpoints = { { lg : 1024 , md : 768 , sm : 475 , xs : 320 , xxs : 0 } }
228- cols = { { lg : 8 , md : 6 , sm : 4 , xs : 2 , xxs : 2 } }
252+ //@ts -ignore
253+ layouts = { layout }
254+ breakpoints = { { lg : 1200 , md : 996 , sm : 768 , xs : 480 , xxs : 0 } }
255+ cols = { { lg : 8 , md : 6 , sm : 4 , xs : 2 , xxs : 1 } }
229256 rowHeight = { 131 }
230- onLayoutChange = { handleLayoutChange }
257+ //@ts -ignore
258+ onDragStop = { handleLayoutChange }
231259 isResizable = { false }
232260 isDraggable = { isDraggable }
233261 key = { keyRender }
234- className = "overflow-hidden"
262+ className = "overflow-hidden max-w-[1440px] "
235263 >
236- { layout . map ( ( widget ) => (
264+ { layout . lg . map ( ( widget ) => (
237265 < div key = { widget . i } >
238266 < WidgetItem draggable = { isDraggable } widgets = { widgets } ID = { widget . id } />
239267 </ div >
0 commit comments