ar-design 0.3.2 → 0.3.4
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.
- package/dist/assets/css/components/data-display/dnd/dnd.css +62 -40
- package/dist/assets/css/components/data-display/kanban-board/styles.css +68 -0
- package/dist/assets/css/components/data-display/table/styles.css +30 -0
- package/dist/assets/css/core/variants/borderless.css +10 -10
- package/dist/components/data-display/diagram/index.d.ts +2 -1
- package/dist/components/data-display/diagram/index.js +11 -3
- package/dist/components/data-display/dnd/IProps.d.ts +2 -1
- package/dist/components/data-display/dnd/index.d.ts +1 -1
- package/dist/components/data-display/dnd/index.js +55 -17
- package/dist/components/data-display/kanban-board/IProps.d.ts +5 -0
- package/dist/components/data-display/kanban-board/IProps.js +1 -0
- package/dist/components/data-display/kanban-board/index.d.ts +5 -0
- package/dist/components/data-display/kanban-board/index.js +71 -0
- package/dist/components/data-display/table/Editable.d.ts +9 -0
- package/dist/components/data-display/table/Editable.js +44 -0
- package/dist/components/data-display/table/IProps.d.ts +1 -0
- package/dist/components/data-display/table/index.js +8 -3
- package/dist/components/feedback/popup/index.js +2 -2
- package/dist/components/form/date-picker/Props.d.ts +2 -2
- package/dist/components/form/date-picker/index.js +2 -2
- package/dist/components/form/input-number/index.js +10 -3
- package/dist/components/form/upload/Buttons.js +2 -2
- package/dist/components/form/upload/Dropzone.js +1 -1
- package/dist/components/form/upload/List.js +1 -1
- package/dist/components/form/upload/index.js +2 -2
- package/dist/components/icons/Compiler.d.ts +2 -2
- package/dist/components/icons/Compiler.js +118 -124
- package/dist/components/icons/index.d.ts +1 -2
- package/dist/components/icons/index.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/libs/core/service/Api.d.ts +0 -3
- package/dist/libs/core/service/Api.js +0 -16
- package/dist/libs/core/service/index.d.ts +0 -1
- package/dist/libs/core/service/index.js +1 -1
- package/dist/libs/infrastructure/shared/Utils.d.ts +1 -2
- package/dist/libs/infrastructure/shared/Utils.js +2 -4
- package/dist/libs/types/index.d.ts +13 -2
- package/package.json +1 -1
|
@@ -2,49 +2,71 @@
|
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
gap: 1rem 0;
|
|
5
|
-
}
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
.ar-dnd > div.drag-item {
|
|
20
|
-
opacity: 0.5;
|
|
21
|
-
}
|
|
22
|
-
.ar-dnd > div.over-item {
|
|
23
|
-
position: relative;
|
|
24
|
-
}
|
|
25
|
-
.ar-dnd > div.over-item::after {
|
|
26
|
-
position: absolute;
|
|
27
|
-
content: "";
|
|
28
|
-
background-color: var(--success);
|
|
29
|
-
left: 1rem;
|
|
30
|
-
right: 1rem;
|
|
31
|
-
bottom: 0;
|
|
32
|
-
height: 5px;
|
|
33
|
-
border-radius: var(--border-radius-pill);
|
|
34
|
-
}
|
|
35
|
-
.ar-dnd > div.end-item {
|
|
36
|
-
/* Sırasıyla; Ad, Süre, Hız, Gecikme Süresi, Tekrar Sayısı, Yön, Bitiş Süreci */
|
|
37
|
-
animation: endItem ease-in-out 1s 0s 1 normal both;
|
|
38
|
-
}
|
|
6
|
+
> .item {
|
|
7
|
+
position: relative;
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: row;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 0 0.5rem;
|
|
13
|
+
width: 100%;
|
|
14
|
+
cursor: move;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
transition: transform 0.3s ease, opacity 0.3s ease;
|
|
39
17
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
18
|
+
&.drag-item {
|
|
19
|
+
opacity: 0.5;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&.over-item {
|
|
23
|
+
position: relative;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&.over-item::after {
|
|
27
|
+
position: absolute;
|
|
28
|
+
content: "";
|
|
29
|
+
background-color: var(--success);
|
|
30
|
+
left: 1rem;
|
|
31
|
+
right: 1rem;
|
|
32
|
+
bottom: 0;
|
|
33
|
+
height: 5px;
|
|
34
|
+
border-radius: var(--border-radius-pill);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&.end-item {
|
|
38
|
+
/* Sırasıyla; Ad, Süre, Hız, Gecikme Süresi, Tekrar Sayısı, Yön, Bitiş Süreci */
|
|
39
|
+
animation: endItem ease-in-out 1s 0s 1 normal both;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
> .move {
|
|
43
|
+
display: flex;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
align-items: center;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
> .content {
|
|
49
|
+
flex: 100%;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
> .placeholder {
|
|
54
|
+
position: relative;
|
|
55
|
+
border-bottom: solid 2px var(--blue-500);
|
|
56
|
+
border-radius: var(--border-radius-pill);
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
|
|
58
|
+
&::before {
|
|
59
|
+
position: absolute;
|
|
60
|
+
left: 0;
|
|
61
|
+
top: -3px;
|
|
62
|
+
content: "";
|
|
63
|
+
background-color: var(--gray-100);
|
|
64
|
+
width: 7.5px;
|
|
65
|
+
height: 7.5px;
|
|
66
|
+
border: solid 2px var(--blue-500);
|
|
67
|
+
border-radius: var(--border-radius-pill);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
48
70
|
}
|
|
49
71
|
|
|
50
72
|
@import url("./animations.css");
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
.ar-kanban-board {
|
|
2
|
+
> .columns {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: row;
|
|
5
|
+
gap: 1rem;
|
|
6
|
+
|
|
7
|
+
> .column {
|
|
8
|
+
flex: 1;
|
|
9
|
+
background-color: var(--gray-100);
|
|
10
|
+
max-width: 350px;
|
|
11
|
+
min-width: 220px;
|
|
12
|
+
border-radius: var(--border-radius-sm);
|
|
13
|
+
user-select: none;
|
|
14
|
+
|
|
15
|
+
> .title {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: row;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: 0.5rem;
|
|
20
|
+
padding: 0.5rem 1rem;
|
|
21
|
+
|
|
22
|
+
> span {
|
|
23
|
+
border: solid 1px var(--gray-100);
|
|
24
|
+
border-radius: var(--border-radius-pill);
|
|
25
|
+
color: var(--gray-700);
|
|
26
|
+
font-size: 0.8rem;
|
|
27
|
+
font-family: var(--system);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
> .items {
|
|
32
|
+
padding: 1rem;
|
|
33
|
+
height: calc(100% - 1rem);
|
|
34
|
+
|
|
35
|
+
&:has(> .no-item) {
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
align-items: center;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
> .no-item {
|
|
42
|
+
position: relative;
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
align-items: center;
|
|
47
|
+
|
|
48
|
+
&::after {
|
|
49
|
+
position: absolute;
|
|
50
|
+
left: 50%;
|
|
51
|
+
transform: translateX(-50%);
|
|
52
|
+
bottom: 23px;
|
|
53
|
+
content: "";
|
|
54
|
+
background-color: var(--gray-200);
|
|
55
|
+
width: 70px;
|
|
56
|
+
height: 16px;
|
|
57
|
+
border-radius: 100%;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
> span {
|
|
61
|
+
color: var(--gray-500);
|
|
62
|
+
font-family: var(--system);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
width: 1px;
|
|
8
8
|
border-radius: var(--border-radius-lg);
|
|
9
9
|
box-shadow: 0px 10px 15px -5px rgba(var(--black-rgb), 0.1);
|
|
10
|
+
font-family: var(--system);
|
|
10
11
|
overflow: hidden;
|
|
11
12
|
}
|
|
12
13
|
.ar-table > .header {
|
|
@@ -186,6 +187,35 @@
|
|
|
186
187
|
cursor: no-drop;
|
|
187
188
|
}
|
|
188
189
|
|
|
190
|
+
.ar-table > .content > table > tbody > tr > td {
|
|
191
|
+
> .no-item {
|
|
192
|
+
position: relative;
|
|
193
|
+
display: flex;
|
|
194
|
+
flex-direction: column;
|
|
195
|
+
justify-content: center;
|
|
196
|
+
align-items: center;
|
|
197
|
+
height: 200px;
|
|
198
|
+
border-bottom: solid 1px var(--gray-200);
|
|
199
|
+
|
|
200
|
+
&::after {
|
|
201
|
+
position: absolute;
|
|
202
|
+
left: 50%;
|
|
203
|
+
transform: translateX(-50%);
|
|
204
|
+
bottom: 82px;
|
|
205
|
+
content: "";
|
|
206
|
+
background-color: var(--gray-100);
|
|
207
|
+
width: 70px;
|
|
208
|
+
height: 16px;
|
|
209
|
+
border-radius: 100%;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
> span {
|
|
213
|
+
color: var(--gray-500);
|
|
214
|
+
font-family: var(--system);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
189
219
|
/* For Rows */
|
|
190
220
|
.ar-table > .content > table > tbody > tr > td > .table-cell > .before {
|
|
191
221
|
position: absolute;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* #region BLUE */
|
|
2
2
|
.borderless:not(.disabled) {
|
|
3
3
|
&.blue {
|
|
4
|
-
color: var(--blue-500
|
|
4
|
+
color: var(--blue-500);
|
|
5
5
|
|
|
6
6
|
&.active {
|
|
7
7
|
animation: clicked-blue ease-in-out 750ms 0s 1 normal both;
|
|
@@ -34,7 +34,7 @@ button.borderless:not(.disabled) {
|
|
|
34
34
|
/* #region PURPLE */
|
|
35
35
|
.borderless:not(.disabled) {
|
|
36
36
|
&.purple {
|
|
37
|
-
color: var(--purple-500
|
|
37
|
+
color: var(--purple-500);
|
|
38
38
|
|
|
39
39
|
&.active {
|
|
40
40
|
animation: clicked-purple ease-in-out 750ms 0s 1 normal both;
|
|
@@ -67,7 +67,7 @@ button.borderless:not(.disabled) {
|
|
|
67
67
|
/* #region PINK */
|
|
68
68
|
.borderless:not(.disabled) {
|
|
69
69
|
&.pink {
|
|
70
|
-
color: var(--pink-500
|
|
70
|
+
color: var(--pink-500);
|
|
71
71
|
|
|
72
72
|
&.active {
|
|
73
73
|
animation: clicked-pink ease-in-out 750ms 0s 1 normal both;
|
|
@@ -100,7 +100,7 @@ button.borderless:not(.disabled) {
|
|
|
100
100
|
/* #region RED */
|
|
101
101
|
.borderless:not(.disabled) {
|
|
102
102
|
&.red {
|
|
103
|
-
color: var(--red-500
|
|
103
|
+
color: var(--red-500);
|
|
104
104
|
|
|
105
105
|
&.active {
|
|
106
106
|
animation: clicked-red ease-in-out 750ms 0s 1 normal both;
|
|
@@ -133,7 +133,7 @@ button.borderless:not(.disabled) {
|
|
|
133
133
|
/* #region ORANGE */
|
|
134
134
|
.borderless:not(.disabled) {
|
|
135
135
|
&.orange {
|
|
136
|
-
color: var(--orange-500
|
|
136
|
+
color: var(--orange-500);
|
|
137
137
|
|
|
138
138
|
&.active {
|
|
139
139
|
animation: clicked-orange ease-in-out 750ms 0s 1 normal both;
|
|
@@ -166,7 +166,7 @@ button.borderless:not(.disabled) {
|
|
|
166
166
|
/* #region YELLOW */
|
|
167
167
|
.borderless:not(.disabled) {
|
|
168
168
|
&.yellow {
|
|
169
|
-
color: var(--yellow-500
|
|
169
|
+
color: var(--yellow-500);
|
|
170
170
|
|
|
171
171
|
&.active {
|
|
172
172
|
animation: clicked-yellow ease-in-out 750ms 0s 1 normal both;
|
|
@@ -199,7 +199,7 @@ button.borderless:not(.disabled) {
|
|
|
199
199
|
/* #region GREEN */
|
|
200
200
|
.borderless:not(.disabled) {
|
|
201
201
|
&.green {
|
|
202
|
-
color: var(--green-500
|
|
202
|
+
color: var(--green-500);
|
|
203
203
|
|
|
204
204
|
&.active {
|
|
205
205
|
animation: clicked-green ease-in-out 750ms 0s 1 normal both;
|
|
@@ -232,7 +232,7 @@ button.borderless:not(.disabled) {
|
|
|
232
232
|
/* #region TEAL */
|
|
233
233
|
.borderless:not(.disabled) {
|
|
234
234
|
&.teal {
|
|
235
|
-
color: var(--teal-500
|
|
235
|
+
color: var(--teal-500);
|
|
236
236
|
|
|
237
237
|
&.active {
|
|
238
238
|
animation: clicked-teal ease-in-out 750ms 0s 1 normal both;
|
|
@@ -265,7 +265,7 @@ button.borderless:not(.disabled) {
|
|
|
265
265
|
/* #region CYAN */
|
|
266
266
|
.borderless:not(.disabled) {
|
|
267
267
|
&.cyan {
|
|
268
|
-
color: var(--cyan-500
|
|
268
|
+
color: var(--cyan-500);
|
|
269
269
|
|
|
270
270
|
&.active {
|
|
271
271
|
animation: clicked-cyan ease-in-out 750ms 0s 1 normal both;
|
|
@@ -298,7 +298,7 @@ button.borderless:not(.disabled) {
|
|
|
298
298
|
/* #region GRAY */
|
|
299
299
|
.borderless:not(.disabled) {
|
|
300
300
|
&.gray {
|
|
301
|
-
color: var(--gray-500
|
|
301
|
+
color: var(--gray-500);
|
|
302
302
|
|
|
303
303
|
&.active {
|
|
304
304
|
animation: clicked-gray ease-in-out 750ms 0s 1 normal both;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import "../../../assets/css/components/data-display/diagram/styles.css";
|
|
3
3
|
import IProps from "./IProps";
|
|
4
|
-
|
|
4
|
+
declare const Diagram: React.FC<IProps>;
|
|
5
|
+
export default Diagram;
|
|
@@ -5,7 +5,7 @@ import Button from "../../form/button";
|
|
|
5
5
|
import Tooltip from "../../feedback/tooltip";
|
|
6
6
|
import { ARIcon } from "../../icons";
|
|
7
7
|
const { Box } = Grid;
|
|
8
|
-
|
|
8
|
+
const Diagram = ({ nodes, edges }) => {
|
|
9
9
|
// refs
|
|
10
10
|
const _arDiagram = useRef(null);
|
|
11
11
|
const _content = useRef(null);
|
|
@@ -173,7 +173,14 @@ export default function Diagram({ nodes, edges }) {
|
|
|
173
173
|
from: { id: drawingEdge.id, port: drawingEdge.port },
|
|
174
174
|
to: { id: closest.id, port: closest.port },
|
|
175
175
|
};
|
|
176
|
-
|
|
176
|
+
// Aynı edge daha önce eklenmiş mi kontrol et
|
|
177
|
+
const isDuplicate = _edges.some((edge) => {
|
|
178
|
+
const samePair = (edge.from.id === newEdge.from.id && edge.to.id === newEdge.to.id) ||
|
|
179
|
+
(edge.from.id === newEdge.to.id && edge.to.id === newEdge.from.id);
|
|
180
|
+
return samePair;
|
|
181
|
+
});
|
|
182
|
+
if (!isDuplicate)
|
|
183
|
+
setEdges((prev) => [...prev, newEdge]);
|
|
177
184
|
}
|
|
178
185
|
else {
|
|
179
186
|
// Yakın port yoksa yeni node oluştur
|
|
@@ -255,4 +262,5 @@ export default function Diagram({ nodes, edges }) {
|
|
|
255
262
|
React.createElement(Tooltip, { text: "Zoom In" },
|
|
256
263
|
React.createElement(Button, { variant: "borderless", color: "light", icon: { element: React.createElement(ARIcon, { icon: "Add", fill: "currentColor" }) }, onClick: () => handleZoom("increment") })))),
|
|
257
264
|
React.createElement("div", { style: { zIndex: 555 } }, JSON.stringify(drawingEdge))));
|
|
258
|
-
}
|
|
265
|
+
};
|
|
266
|
+
export default Diagram;
|
|
@@ -23,6 +23,7 @@ interface IProps<T> {
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
renderItem: (item: T, index: number) => React.JSX.Element;
|
|
26
|
+
columnKey?: string;
|
|
26
27
|
/**
|
|
27
28
|
* Sıralama değiştiğinde tetiklenen olay.
|
|
28
29
|
*
|
|
@@ -34,6 +35,6 @@ interface IProps<T> {
|
|
|
34
35
|
* <DnD onChange={(data) => console.log("Yeni sıra:", data)} />
|
|
35
36
|
* ```
|
|
36
37
|
*/
|
|
37
|
-
onChange
|
|
38
|
+
onChange?: (data: T[]) => void;
|
|
38
39
|
}
|
|
39
40
|
export default IProps;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import IProps from "./IProps";
|
|
3
3
|
import "../../../assets/css/components/data-display/dnd/dnd.css";
|
|
4
|
-
declare const DnD: <T>({ data, renderItem, onChange }: IProps<T>) => React.JSX.Element;
|
|
4
|
+
declare const DnD: <T>({ data, renderItem, columnKey, onChange }: IProps<T>) => React.JSX.Element;
|
|
5
5
|
export default DnD;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import React, { useEffect, useRef } from "react";
|
|
3
3
|
import "../../../assets/css/components/data-display/dnd/dnd.css";
|
|
4
4
|
import { ARIcon } from "../../icons";
|
|
5
|
-
|
|
5
|
+
let _fromColumn = undefined;
|
|
6
|
+
const DnD = function ({ data, renderItem, columnKey, onChange }) {
|
|
6
7
|
// refs
|
|
7
8
|
const _arDnD = useRef(null);
|
|
8
9
|
const _dragItem = useRef();
|
|
@@ -17,14 +18,21 @@ const DnD = function ({ data, renderItem, onChange }) {
|
|
|
17
18
|
const dragItem = event.currentTarget;
|
|
18
19
|
_dragItem.current = dragItem;
|
|
19
20
|
dragItem.classList.add("drag-item");
|
|
20
|
-
|
|
21
|
+
const index = [..._arDnD.current.children].indexOf(dragItem);
|
|
22
|
+
const draggedData = data[index];
|
|
23
|
+
if (event.dataTransfer) {
|
|
24
|
+
event.dataTransfer.setData("item", JSON.stringify(draggedData));
|
|
25
|
+
event.dataTransfer.setData("fromColumn", columnKey ?? "");
|
|
26
|
+
_fromColumn = columnKey ?? undefined;
|
|
27
|
+
}
|
|
28
|
+
// Korumaya başla.
|
|
21
29
|
if (_arDnD.current) {
|
|
22
30
|
_arDnD.current.childNodes.forEach((item) => {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
item.appendChild(
|
|
31
|
+
const placeholder = document.createElement("div");
|
|
32
|
+
placeholder.setAttribute("data-id", "placeholder");
|
|
33
|
+
placeholder.style.position = "absolute";
|
|
34
|
+
placeholder.style.inset = "0";
|
|
35
|
+
item.appendChild(placeholder);
|
|
28
36
|
});
|
|
29
37
|
}
|
|
30
38
|
};
|
|
@@ -32,25 +40,44 @@ const DnD = function ({ data, renderItem, onChange }) {
|
|
|
32
40
|
event.preventDefault();
|
|
33
41
|
const overItem = event.currentTarget;
|
|
34
42
|
const rect = overItem.getBoundingClientRect();
|
|
43
|
+
// Otomatik scroll.
|
|
35
44
|
if (rect.top < 250)
|
|
36
45
|
window.scrollBy(0, -20);
|
|
37
46
|
if (rect.bottom > window.innerHeight - 150)
|
|
38
47
|
window.scrollBy(0, 20);
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
// Sadece aynı kolondaysa drag-drop yap.
|
|
49
|
+
if (columnKey && _fromColumn !== columnKey) {
|
|
50
|
+
// Placeholder'ı temizle
|
|
51
|
+
const nodes = document.querySelectorAll("[data-id='placeholder']");
|
|
52
|
+
nodes.forEach((node) => node.remove());
|
|
53
|
+
// Placeholder element oluştur.
|
|
54
|
+
const placeholder = document.createElement("div");
|
|
55
|
+
placeholder.setAttribute("data-id", "placeholder");
|
|
56
|
+
placeholder.classList.add("placeholder");
|
|
57
|
+
// Fare pozisyonuna göre yerleştir.
|
|
58
|
+
const isBelow = event.clientY > rect.top + rect.height / 2;
|
|
59
|
+
if (isBelow) {
|
|
60
|
+
overItem.parentNode?.insertBefore(placeholder, overItem.nextSibling);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
overItem.parentNode?.insertBefore(placeholder, overItem);
|
|
64
|
+
}
|
|
65
|
+
return; // taşıma yapma ama placeholder gösterilsin.
|
|
66
|
+
}
|
|
67
|
+
// Gerçek taşıma işlemi.
|
|
41
68
|
if (_dragItem.current !== overItem) {
|
|
42
69
|
if (_arDnD.current && _dragItem.current) {
|
|
43
70
|
const dragItemIndex = [..._arDnD.current.children].indexOf(_dragItem.current);
|
|
44
71
|
const dropItemIndex = [..._arDnD.current.children].indexOf(overItem);
|
|
45
|
-
if (dragItemIndex
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
72
|
+
if (dragItemIndex === -1 || dropItemIndex === -1)
|
|
73
|
+
return;
|
|
74
|
+
_arDnD.current.insertBefore(_dragItem.current, dragItemIndex < dropItemIndex ? overItem.nextSibling : overItem);
|
|
75
|
+
const movedItem = data.splice(dragItemIndex, 1)[0];
|
|
76
|
+
if (movedItem) {
|
|
77
|
+
data.splice(dropItemIndex, 0, movedItem);
|
|
78
|
+
onChange?.(data);
|
|
50
79
|
}
|
|
51
|
-
data.splice(dropItemIndex, 0, data.splice(dragItemIndex, 1)[0]);
|
|
52
80
|
}
|
|
53
|
-
onChange(data);
|
|
54
81
|
}
|
|
55
82
|
};
|
|
56
83
|
_item.ondragend = (event) => {
|
|
@@ -65,8 +92,19 @@ const DnD = function ({ data, renderItem, onChange }) {
|
|
|
65
92
|
};
|
|
66
93
|
});
|
|
67
94
|
_arDnD.current.ondragover = (event) => event.preventDefault();
|
|
95
|
+
return () => {
|
|
96
|
+
if (!_arDnD.current)
|
|
97
|
+
return;
|
|
98
|
+
_arDnD.current.childNodes.forEach((item) => {
|
|
99
|
+
const _item = item;
|
|
100
|
+
_item.ondragstart = null;
|
|
101
|
+
_item.ondragover = null;
|
|
102
|
+
_item.ondragend = null;
|
|
103
|
+
});
|
|
104
|
+
_arDnD.current.ondragover = null;
|
|
105
|
+
};
|
|
68
106
|
}, [data]);
|
|
69
|
-
return (React.createElement("div", { ref: _arDnD, className: "ar-dnd" }, data.map((item, index) => (React.createElement("div", { key: index, draggable: true },
|
|
107
|
+
return (React.createElement("div", { ref: _arDnD, className: "ar-dnd" }, data.map((item, index) => (React.createElement("div", { key: index, className: "item", draggable: true },
|
|
70
108
|
React.createElement("div", { className: "move" },
|
|
71
109
|
React.createElement(ARIcon, { icon: "GripVertical", fill: "var(--blue-500)", size: 18 })),
|
|
72
110
|
React.createElement("div", { className: "content" }, renderItem(item, index)))))));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useRef, useState } from "react";
|
|
3
|
+
import Typography from "../typography";
|
|
4
|
+
import "../../../assets/css/components/data-display/kanban-board/styles.css";
|
|
5
|
+
import DnD from "../dnd";
|
|
6
|
+
import { ARIcon } from "../../icons";
|
|
7
|
+
const { Title } = Typography;
|
|
8
|
+
const KanbanBoard = function ({ columns }) {
|
|
9
|
+
// refs
|
|
10
|
+
const _hoverItemIndex = useRef(null);
|
|
11
|
+
// states
|
|
12
|
+
const [boardData, setBoardData] = useState(columns);
|
|
13
|
+
const handleDrop = (toColumn) => (event) => {
|
|
14
|
+
event.preventDefault();
|
|
15
|
+
const item = JSON.parse(event.dataTransfer.getData("item"));
|
|
16
|
+
const fromColumn = event.dataTransfer.getData("fromColumn");
|
|
17
|
+
if (!item || fromColumn === toColumn)
|
|
18
|
+
return;
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
const updatedColumns = boardData.map((col) => {
|
|
21
|
+
if (col.key === fromColumn) {
|
|
22
|
+
return {
|
|
23
|
+
...col,
|
|
24
|
+
items: col.items.filter((i) => i.id !== item.id),
|
|
25
|
+
updatedAt: now,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (col.key === toColumn) {
|
|
29
|
+
const newItems = [...col.items];
|
|
30
|
+
const safeIndex = Math.min(_hoverItemIndex.current ?? Infinity, newItems.length); // son elemandan fazla olmasın.
|
|
31
|
+
newItems.splice(safeIndex, 0, item);
|
|
32
|
+
return {
|
|
33
|
+
...col,
|
|
34
|
+
items: newItems,
|
|
35
|
+
updatedAt: now,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return col;
|
|
39
|
+
});
|
|
40
|
+
setBoardData(updatedColumns);
|
|
41
|
+
// Temizlik
|
|
42
|
+
event.dataTransfer.clearData("item");
|
|
43
|
+
event.dataTransfer.clearData("fromColumn");
|
|
44
|
+
_hoverItemIndex.current = null;
|
|
45
|
+
const nodes = document.querySelectorAll("[data-id='placeholder']");
|
|
46
|
+
nodes.forEach((node) => node.remove());
|
|
47
|
+
};
|
|
48
|
+
// methods
|
|
49
|
+
const renderColumns = (_boardData) => {
|
|
50
|
+
return _boardData.map((board, cIndex) => {
|
|
51
|
+
return (React.createElement("div", { key: cIndex, className: "column", onDragOver: (event) => event.preventDefault(), onDrop: handleDrop(board.key) },
|
|
52
|
+
React.createElement("div", { className: "title" },
|
|
53
|
+
React.createElement(Title, { Level: "h5" }, board.title),
|
|
54
|
+
board.items.length > 0 && React.createElement("span", null, board.items.length)),
|
|
55
|
+
React.createElement("div", { className: "items" }, board.items.length === 0 ? (React.createElement("div", { className: "no-item" },
|
|
56
|
+
React.createElement(ARIcon, { icon: "Inbox-Fill", fill: "var(--gray-300)", size: 64, style: { position: "relative", zIndex: 1 } }),
|
|
57
|
+
React.createElement("span", null, "No Data"))) : (React.createElement(DnD, { key: `${board.key}-${board.items.map((i) => i.updatedAt).join("_")}`, data: board.items, renderItem: (item, index) => {
|
|
58
|
+
return (React.createElement("div", { key: index, className: "item", onDragOver: (event) => {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
61
|
+
const mouseY = event.clientY;
|
|
62
|
+
const isBelow = mouseY > rect.top + rect.height / 2;
|
|
63
|
+
_hoverItemIndex.current = isBelow ? index + 1 : index;
|
|
64
|
+
} }, board.renderItem(item, index)));
|
|
65
|
+
}, columnKey: board.key })))));
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
return (React.createElement("div", { className: "ar-kanban-board" },
|
|
69
|
+
React.createElement("div", { className: "columns" }, renderColumns(boardData))));
|
|
70
|
+
};
|
|
71
|
+
export default KanbanBoard;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TableColumnType } from "../../../libs/types";
|
|
3
|
+
interface IProps<T> {
|
|
4
|
+
c: TableColumnType<T>;
|
|
5
|
+
item: T;
|
|
6
|
+
onEditable: (item: T) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const Editable: <T>({ c, item, onEditable }: IProps<T>) => React.JSX.Element | null;
|
|
9
|
+
export default Editable;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import Input from "../../form/input";
|
|
4
|
+
import DatePicker from "../../form/date-picker";
|
|
5
|
+
import Select from "../../form/select";
|
|
6
|
+
const Editable = function ({ c, item, onEditable }) {
|
|
7
|
+
const key = c.key;
|
|
8
|
+
const itemValue = item[c.key];
|
|
9
|
+
const selectItem = c.editable?.options?.find((x) => x.value === itemValue);
|
|
10
|
+
const selectItems = Array.isArray(itemValue)
|
|
11
|
+
? c.editable?.options?.filter((x) => itemValue.includes(x.value))
|
|
12
|
+
: [];
|
|
13
|
+
// states
|
|
14
|
+
const [value, setValue] = useState(itemValue);
|
|
15
|
+
const [selectionItem, setSelectionItem] = useState(selectItem);
|
|
16
|
+
const [selectionItems, setSelectionItems] = useState(selectItems);
|
|
17
|
+
switch (c.editable?.type) {
|
|
18
|
+
case "string":
|
|
19
|
+
case "number":
|
|
20
|
+
return (React.createElement(Input, { variant: "borderless", value: value, onChange: (event) => {
|
|
21
|
+
const { value } = event.target;
|
|
22
|
+
setValue(value);
|
|
23
|
+
onEditable({ ...item, [key]: c.editable?.type === "number" ? Number(value) : value });
|
|
24
|
+
} }));
|
|
25
|
+
case "date-picker":
|
|
26
|
+
return (React.createElement(DatePicker, { variant: "borderless", value: value, onChange: (value) => {
|
|
27
|
+
setValue(value);
|
|
28
|
+
onEditable({ ...item, [key]: value });
|
|
29
|
+
} }));
|
|
30
|
+
case "single-select":
|
|
31
|
+
return (React.createElement(Select, { variant: "borderless", value: selectionItem, options: c.editable.options, onChange: (option) => {
|
|
32
|
+
setSelectionItem(option);
|
|
33
|
+
onEditable({ ...item, [key]: option?.value });
|
|
34
|
+
} }));
|
|
35
|
+
case "multiple-select":
|
|
36
|
+
return (React.createElement(Select, { variant: "borderless", value: selectionItems, options: c.editable.options, onChange: (options) => {
|
|
37
|
+
setSelectionItems(options);
|
|
38
|
+
onEditable({ ...item, [key]: options.map((option) => option.value) });
|
|
39
|
+
}, multiple: true }));
|
|
40
|
+
default:
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
export default Editable;
|
|
@@ -142,6 +142,7 @@ interface IProps<T> extends IChildren {
|
|
|
142
142
|
* @param operator - Kullanılan filtre operatörü.
|
|
143
143
|
*/
|
|
144
144
|
searchedParams?: (params: SearchedParam | null, query: string, operator: FilterOperator) => void;
|
|
145
|
+
onEditable?: (item: T) => void;
|
|
145
146
|
/**
|
|
146
147
|
* Sayfalama ayarları.
|
|
147
148
|
*/
|