ui-soxo-bootstrap-core 2.4.25-dev.10 → 2.4.25-dev.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,61 +1,138 @@
1
- import React, { useRef } from "react";
2
- import { useDrag, useDrop } from "react-dnd";
1
+ import React, { useRef } from 'react';
2
+ import { useDrag, useDrop } from 'react-dnd';
3
3
 
4
- const ItemTypes = { PANEL: "panel" };
4
+ export default function DraggableWrapper({ id, index, movePanel, item, dragEnabled, level, parentId, onCrossLevelMove, canAcceptChildren }) {
5
5
 
6
- export default function DraggableWrapper({ id, index, movePanel, title, dragEnabled = true }) {
7
- const ref = useRef(null);
6
+ const autoScrollWindow = (monitor) => {
7
+ const offset = monitor.getClientOffset();
8
+ if (!offset) return;
8
9
 
9
- const [, drop] = useDrop({
10
- accept: ItemTypes.PANEL,
11
- hover(item, monitor) {
12
- if (!dragEnabled) return; // ignore hover if dragging is disabled
13
- if (!ref.current) return;
10
+ const EDGE = 80;
11
+ const SPEED = 20;
14
12
 
15
- const dragIndex = item.index;
16
- const hoverIndex = index;
13
+ const viewportHeight = window.innerHeight;
17
14
 
18
- if (dragIndex === hoverIndex) return;
15
+ // 🔼 scroll UP
16
+ if (offset.y < EDGE) {
17
+ window.scrollBy(0, -SPEED);
18
+ }
19
19
 
20
- const hoverBoundingRect = ref.current.getBoundingClientRect();
21
- const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
22
- const clientOffset = monitor.getClientOffset();
23
- const hoverClientY = clientOffset.y - hoverBoundingRect.top;
20
+ // 🔽 scroll DOWN
21
+ if (offset.y > viewportHeight - EDGE) {
22
+ window.scrollBy(0, SPEED);
23
+ }
24
+ };
24
25
 
25
- if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) return;
26
- if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) return;
26
+ const [{ isDragging }, drag] = useDrag({
27
+ type: 'PANEL',
28
+ item: { id, index, level, parentId },
29
+ canDrag: dragEnabled,
30
+ collect: (monitor) => ({
31
+ isDragging: monitor.isDragging(),
32
+ }),
33
+ });
27
34
 
28
- movePanel(dragIndex, hoverIndex);
29
- item.index = hoverIndex;
30
- },
35
+ const [{ isOver, canDrop }, drop] = useDrop({
36
+ accept: 'PANEL',
37
+ hover: (dragItem, monitor) => {
38
+ // THIS FIXES BOTTOM → TOP
39
+ autoScrollWindow(monitor);
40
+
41
+ if (dragItem.index === index) return;
42
+
43
+ if (
44
+ dragItem.level === level &&
45
+ dragItem.parentId === parentId
46
+ ) {
47
+ movePanel(dragItem.index, index);
48
+ dragItem.index = index; // keep in sync
49
+ }
50
+ },
51
+
52
+ canDrop: (item) => dragEnabled,
53
+ drop: (dragItem, monitor) => {
54
+ if (monitor.didDrop()) return;
55
+
56
+ if (
57
+ dragItem.level !== level ||
58
+ dragItem.parentId !== parentId
59
+ ) {
60
+ onCrossLevelMove?.(dragItem, {
61
+ targetLevel: level,
62
+ targetParentId: parentId,
63
+ targetIndex: index,
64
+ });
65
+ }
66
+ },
67
+ collect: (monitor) => ({
68
+ isOver: monitor.isOver({ shallow: true }),
69
+ canDrop: monitor.canDrop(),
70
+ }),
31
71
  });
32
72
 
33
- const [{ isDragging }, drag] = useDrag({
34
- type: ItemTypes.PANEL,
35
- item: { id, index },
36
- canDrag: dragEnabled, // only allow dragging if dragEnabled
73
+ // Drop zone for making items children of this item
74
+ const [{ isOverChild, canDropChild }, dropChild] = useDrop({
75
+ accept: 'PANEL',
76
+ canDrop: (item) => dragEnabled && item.id !== id && canAcceptChildren,
77
+ drop: (item, monitor) => {
78
+ if (monitor.didDrop()) return;
79
+
80
+ if (onCrossLevelMove && item.id !== id) {
81
+ // Drop as child of this item
82
+ onCrossLevelMove(item, { targetLevel: level + 1, targetParentId: id, targetIndex: 0 });
83
+ }
84
+ },
37
85
  collect: (monitor) => ({
38
- isDragging: monitor.isDragging(),
86
+ isOverChild: monitor.isOver({ shallow: true }),
87
+ canDropChild: monitor.canDrop(),
39
88
  }),
40
89
  });
41
90
 
42
- drag(drop(ref));
91
+ const backgroundColor = isOver && canDrop ? '#bae7ff' : isDragging ? '#e6f7ff' : 'transparent';
92
+ const childZoneBackgroundColor = isOverChild && canDropChild ? '#d4f4dd' : 'transparent';
43
93
 
44
94
  return (
45
- <div
46
- ref={ref}
47
- style={{
48
- display: "flex",
49
- width: "100%",
50
- cursor: dragEnabled ? "grab" : "default", // show cursor only if draggable
51
- opacity: isDragging ? 0.6 : 1,
52
- transition: "transform 0.2s ease, opacity 0.2s ease",
53
- transform: isDragging ? "scale(1.05)" : "scale(1)",
54
- boxShadow: isDragging ? "0px 5px 10px rgba(0,0,0,0.15)" : "none",
55
- padding: "5px 0",
56
- }}
57
- >
58
- {title}
95
+ <div ref={drop} style={{ width: '100%' }}>
96
+ <div
97
+ ref={drag}
98
+ style={{
99
+ opacity: isDragging ? 0.5 : 1,
100
+ cursor: dragEnabled ? 'move' : 'default',
101
+ // padding: '8px',
102
+ backgroundColor,
103
+ transition: 'all 0.2s ease',
104
+ border: isOver && canDrop ? '2px dashed #1890ff' : '2px solid transparent',
105
+ display: 'flex',
106
+ justifyContent: 'space-between',
107
+ alignItems: 'center',
108
+ }}
109
+ >
110
+ <div style={{ flex: 1 }}>
111
+ {dragEnabled && <span style={{ marginRight: 8, color: '#999' }}>⋮⋮</span>}
112
+ <strong>{item.name}</strong>
113
+ {dragEnabled ?( <span style={{ marginLeft: 8, fontSize: 11, color: '#999' }}>(Level {level})</span>):(<span style={{ marginLeft: 8, fontSize: 11, color: '#999' }}>{item.path}</span>)}
114
+ </div>
115
+
116
+ {canAcceptChildren && dragEnabled && (
117
+ <div
118
+ ref={dropChild}
119
+ onClick={(e) => e.stopPropagation()}
120
+ style={{
121
+ padding: '4px 12px',
122
+ marginLeft: 8,
123
+ backgroundColor: childZoneBackgroundColor,
124
+ border: isOverChild && canDropChild ? '2px solid #52c41a' : '1px dashed #d9d9d9',
125
+ borderRadius: 4,
126
+ fontSize: 11,
127
+ color: isOverChild && canDropChild ? '#52c41a' : '#999',
128
+ cursor: 'default',
129
+ transition: 'all 0.2s ease',
130
+ }}
131
+ >
132
+ {isOverChild && canDropChild ? '✓ Drop as child' : '↳ Drop here'}
133
+ </div>
134
+ )}
135
+ </div>
59
136
  </div>
60
137
  );
61
138
  }
@@ -65,4 +65,4 @@ Switch.propTypes = {
65
65
  className: PropTypes.string,
66
66
  /** A custom style object for the switch component. */
67
67
  style: PropTypes.object,
68
- };
68
+ };
@@ -107,13 +107,14 @@ const MenuAdd = ({ model, callback, edit, history, formContent, match, additiona
107
107
  * Submit values
108
108
  */
109
109
  const onSubmit = (values) => {
110
- // console.log(values);
111
110
  setLoading(true);
112
111
 
113
112
  let id = formContent.id;
114
113
 
115
- // Add the step to form content
116
- // values.step = step;
114
+ // ONLY set step if it's NOT already provided
115
+ if (!values.step) {
116
+ values.step = formContent.step || step;
117
+ }
117
118
 
118
119
  if (values.attributes && typeof values === 'object') {
119
120
  values = {
@@ -123,30 +124,19 @@ const MenuAdd = ({ model, callback, edit, history, formContent, match, additiona
123
124
  }
124
125
 
125
126
  if (id) {
126
- // Update of model
127
127
  model.update({ id, values }).then(() => {
128
- // callback();
129
128
  message.success('Menu Updated');
130
-
131
129
  setLoading(false);
132
-
133
130
  callback();
134
131
  });
135
132
  } else {
136
- values.step = step;
137
-
138
- // Append the additional queries to the object
139
133
  additional_queries.forEach(({ field, value }) => {
140
134
  values[field] = value;
141
135
  });
142
136
 
143
- // add new model
144
137
  model.add({ values }).then(() => {
145
- // callback();
146
138
  message.success('Menu Added');
147
-
148
139
  setLoading(false);
149
-
150
140
  callback();
151
141
  });
152
142
  }
@@ -154,7 +144,7 @@ const MenuAdd = ({ model, callback, edit, history, formContent, match, additiona
154
144
 
155
145
  return (
156
146
  <section className="collection-add menu-add">
157
- <Title level={4}>{mode} Menu</Title>
147
+ {/* <Title level={4}>{mode} Menu</Title> */}
158
148
 
159
149
  {loading ? (
160
150
  <Skeleton />
@@ -163,21 +153,21 @@ const MenuAdd = ({ model, callback, edit, history, formContent, match, additiona
163
153
  <div className="form-container">
164
154
  <div className="left-container">
165
155
  {/* Caption */}
166
- <Form.Item name={'caption'} label="Caption" required>
156
+ <Form.Item name={'caption'} label="Caption" rules={[{ required: true, message: 'Caption is required' }]}>
167
157
  <Input placeholder="Enter caption" />
168
158
  </Form.Item>
169
159
  {/* Caption Ends */}
170
160
 
171
161
  {/* Name */}
172
- <Form.Item name={'name'} label="Name" required>
162
+ <Form.Item name={'name'} label="Name" rules={[{ required: true, message: 'Name is required' }]}>
173
163
  <Input placeholder="Enter name" />
174
164
  </Form.Item>
175
165
  {/* Name Ends */}
176
166
 
177
167
  {/* Description */}
178
- <Form.Item name={'description'} label="Description">
179
- <TextArea placeholder="Enter Description" />
180
- </Form.Item>
168
+ {/* <Form.Item name={"description"} label="Description">
169
+ <TextArea placeholder="Enter Description" />
170
+ </Form.Item> */}
181
171
  {/* Description Ends */}
182
172
 
183
173
  {/* Model */}
@@ -229,37 +219,38 @@ const MenuAdd = ({ model, callback, edit, history, formContent, match, additiona
229
219
  {/* Pages Ends */}
230
220
 
231
221
  {/* Path */}
232
- <Form.Item name="path" label="Path" required>
233
- <Input placeholder="Enter path" />
234
- </Form.Item>
222
+ {/* <Form.Item name="path" label="Path" required>
223
+ <Input placeholder="Enter path" />
224
+ </Form.Item> */}
235
225
  {/* Path Ends */}
236
226
 
237
227
  {/* Route */}
238
- <Form.Item name="route" label="Route" required>
228
+ <Form.Item name="route" label="Route" rules={[{ required: true, message: 'Route is required' }]}>
239
229
  <Input placeholder="Enter route" />
240
230
  </Form.Item>
241
231
  {/* Route Ends */}
242
232
 
243
233
  {/* Switch */}
244
- <Form.Item name="is_visible" label="Visible" required>
245
- <Switch defaultChecked={body.is_visible} />
234
+ <Form.Item name="is_visible" label="Visible" valuePropName="checked" rules={[{ required: true, message: 'Visibility is required' }]}>
235
+ <Switch />
246
236
  </Form.Item>
237
+
247
238
  {/* Switch Ends */}
248
239
 
249
240
  {/* Step */}
250
- <Form.Item name={'order'} label="Order" required>
251
- <InputNumber placeholder="Enter order" />
252
- </Form.Item>
241
+ {/* <Form.Item name={"order"} label="Order" required>
242
+ <InputNumber placeholder="Enter order" />
243
+ </Form.Item> */}
253
244
  {/* Step Ends */}
254
245
 
255
246
  {/* Icon Name*/}
256
- <Form.Item name="icon_name" label="Icon Name" required>
247
+ <Form.Item name="icon_name" label="Icon Name" rules={[{ required: true, message: 'Icon name is required' }]}>
257
248
  <Input placeholder="Enter icon name" />
258
249
  </Form.Item>
259
250
  {/* Icon Name Ends */}
260
251
 
261
252
  {/* Step */}
262
- <Form.Item name={'step'} label="Step" required>
253
+ <Form.Item name={'step'} label="Step" rules={[{ required: true, message: 'Step is required' }]}>
263
254
  <InputNumber placeholder="Enter step" />
264
255
  </Form.Item>
265
256
  {/* Step Ends */}