react-editable-photo-grid 2.3.7 → 3.0.1

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/src/utils.tsx CHANGED
@@ -1,462 +1,462 @@
1
- import { PhotoItem, PhotoRows, PhotoIdAndRowKey, PhotoGridProps } from './types';
2
- import React from 'react';
3
-
4
- /**
5
- * Returns true if a photo has details
6
- * @param photo
7
- */
8
- export const photoHasDetails = (photo: PhotoItem): boolean => {
9
- if (
10
- (photo.name != undefined && photo.name !== '')
11
- || (photo.description != undefined && photo.description !== '')
12
- ) {
13
- return true;
14
- }
15
-
16
- return false;
17
- }
18
-
19
- /**
20
- * Sorts photos into rows
21
- * @param photos
22
- */
23
- export const sortPhotosIntoRows = (photos: PhotoItem[]): PhotoRows => {
24
- let rows = {} as PhotoRows;
25
-
26
- for (const photo of photos) {
27
- const rowKey = photo.row;
28
- if (!rows[rowKey]) {
29
- rows[rowKey] = [];
30
- }
31
- rows[rowKey].push(photo);
32
- }
33
-
34
- return rows;
35
- }
36
-
37
- /**
38
- * Return the photo property to be used for the src
39
- * @param photo
40
- * @param property
41
- */
42
- export const getImageSrcProperty = (photo: PhotoItem, property: string): string => {
43
- switch (property) {
44
- case 'id':
45
- return photo.id;
46
- case 'thumbnail_path':
47
- return photo.thumbnail_path;
48
- case 'image_path':
49
- return photo.image_path;
50
- }
51
-
52
- return photo.image_path;
53
- }
54
-
55
- /**
56
- * Sorts the photos in a row by column number
57
- * @param row
58
- */
59
- export const sortRow = (row: PhotoItem[]) => {
60
- return row.sort((a, b) => Math.floor(a.column) - Math.floor(b.column))
61
- }
62
-
63
- /**
64
- * Get a photo from a row via id
65
- * @param row
66
- * @param id
67
- */
68
- const getPhotoForId = (row: PhotoItem[], id: string): PhotoItem => {
69
- const photoResult = row.find(photo => photo.id === id);
70
-
71
- if (photoResult === undefined) {
72
- throw new TypeError('No photo was found in this row for that id');
73
- }
74
-
75
- return photoResult;
76
- }
77
-
78
- /**
79
- * Get a photo from a row by column number
80
- * @param row
81
- * @param column
82
- */
83
- const getPhotoForColumn = (row: PhotoItem[], column: number): PhotoItem => {
84
- const photoResult = row.find(photo => photo.column === column);
85
-
86
- if (photoResult === undefined) {
87
- throw new TypeError('No photo was found in this row for that column');
88
- }
89
-
90
- return photoResult;
91
- }
92
-
93
- /**
94
- * Deletes a photo from a row by column number
95
- * @param row
96
- * @param column
97
- */
98
- const deletePhotoFromRowByColumn = (row: PhotoItem[], column: number): PhotoItem[] => {
99
- return row.filter((photo: PhotoItem) => photo.column !== column);
100
- }
101
-
102
- /**
103
- * Adds a photo to a row
104
- * @param row
105
- * @param photo
106
- * @param column
107
- */
108
- const addPhotoToRow = (row: PhotoItem[] = [], photo: PhotoItem, column: number): PhotoItem[] => {
109
- photo.column = column;
110
- row.push(photo);
111
- return row;
112
- }
113
-
114
- /**
115
- * Swaps two photos around in the row
116
- * @param row
117
- * @param firstPhoto
118
- * @param secondPhoto
119
- */
120
- const swapPhotosAround = (
121
- row: PhotoItem[],
122
- firstPhoto: PhotoItem,
123
- secondPhoto: PhotoItem): PhotoItem[] => {
124
- const firstColumn = firstPhoto.column,
125
- secondColumn = secondPhoto.column;
126
-
127
- row = deletePhotoFromRowByColumn(row, firstColumn);
128
- row = deletePhotoFromRowByColumn(row, secondColumn);
129
- row = addPhotoToRow(row, firstPhoto, secondColumn);
130
- row = addPhotoToRow(row, secondPhoto, firstColumn);
131
-
132
- return row;
133
- }
134
-
135
- /**
136
- * Casts a the rowKey to a number if necessary
137
- * @param rowKey
138
- */
139
- export const castRowKey = (rowKey: string | number): number => {
140
- if (typeof rowKey == 'string') {
141
- rowKey = parseInt(rowKey);
142
- }
143
-
144
- return rowKey;
145
- }
146
-
147
- /**
148
- * Extract the row key and photo id from the clicked element
149
- * @param e
150
- */
151
- const getPhotoIdAndRowKey = (e: React.MouseEvent<HTMLButtonElement>): PhotoIdAndRowKey => {
152
- const button = e.currentTarget as HTMLButtonElement,
153
- id = button.dataset.id,
154
- rowKey = button.dataset.row;
155
-
156
- if (!id || !rowKey) {
157
- throw new TypeError('id or row key missing from photo control');
158
- }
159
-
160
- return {
161
- id: id,
162
- rowKey: parseInt(rowKey)
163
- }
164
- }
165
-
166
- /**
167
- * Moves a photo one column to the left
168
- * @param e
169
- * @param props
170
- */
171
- export const movePhotoLeft = (
172
- e: React.MouseEvent<HTMLButtonElement>,
173
- props: PhotoGridProps
174
- ) => {
175
- e.preventDefault();
176
-
177
- const { id, rowKey } = getPhotoIdAndRowKey(e);
178
-
179
- let rowsCopy = { ...props.rows },
180
- thisRow = sortRow(rowsCopy[rowKey]);
181
-
182
- const thisPhoto = getPhotoForId(thisRow, id);
183
-
184
- if (thisPhoto.column === 1) {
185
- return;
186
- }
187
-
188
- const beforePhoto = getPhotoForColumn(thisRow, thisPhoto.column - 1);
189
- thisRow = swapPhotosAround(thisRow, beforePhoto, thisPhoto);
190
-
191
- delete rowsCopy[rowKey];
192
- rowsCopy[rowKey] = thisRow;
193
-
194
- props.updateRows(rowsCopy);
195
- props.increaseChanges();
196
- }
197
-
198
- /**
199
- * Move a photo one column to the right
200
- * @param e
201
- * @param props
202
- */
203
- export const movePhotoRight = (
204
- e: React.MouseEvent<HTMLButtonElement>,
205
- props: PhotoGridProps
206
- ) => {
207
- e.preventDefault();
208
-
209
- const { id, rowKey } = getPhotoIdAndRowKey(e);
210
-
211
- let rowsCopy = { ...props.rows },
212
- thisRow = sortRow(rowsCopy[rowKey]);
213
-
214
- const thisPhoto = getPhotoForId(thisRow, id);
215
-
216
- if (thisPhoto.column === thisRow.length) {
217
- return;
218
- }
219
-
220
- const afterPhoto = getPhotoForColumn(thisRow, thisPhoto.column + 1);
221
- thisRow = swapPhotosAround(thisRow, thisPhoto, afterPhoto);
222
-
223
- delete rowsCopy[rowKey];
224
- rowsCopy[rowKey] = thisRow;
225
-
226
- props.updateRows(rowsCopy);
227
- props.increaseChanges();
228
- }
229
-
230
- /**
231
- * All photos in the row move back a column (to the left)
232
- * @param row
233
- * @param start
234
- * @param end
235
- */
236
- const shufflePhotosBackOneColumn = (row: PhotoItem[], start: number, end: number): PhotoItem[] => {
237
- for (let x = start; x <= end; x++) {
238
- const selectedPhoto = getPhotoForColumn(row, x);
239
- row = deletePhotoFromRowByColumn(row, x);
240
- row = addPhotoToRow(row, selectedPhoto, selectedPhoto.column - 1);
241
- }
242
-
243
- return row;
244
- }
245
-
246
- /**
247
- * All the photos in the the row move forward a column (to the right)
248
- * @param row
249
- * @param start
250
- */
251
- const shufflePhotosForwardOneColumn = (row: PhotoItem[], start: number): PhotoItem[] => {
252
- for (let x = start; x > 0; x--) {
253
- const selectedPhoto = getPhotoForColumn(row, x);
254
- row = deletePhotoFromRowByColumn(row, x);
255
- row = addPhotoToRow(row, selectedPhoto, selectedPhoto.column + 1);
256
- }
257
-
258
- return row;
259
- }
260
-
261
- /**
262
- * Deletes a row index from the data if it's empty
263
- */
264
- const deleteRowIfEmpty = (rows: PhotoRows, rowIndex: number) => {
265
- if (rows[rowIndex] == undefined) {
266
- Object.entries(rows).map(([index, photos]: [string, PhotoItem[]]) => {
267
- const thisRowIndex = parseInt(index);
268
- if (thisRowIndex > rowIndex) {
269
- delete rows[thisRowIndex];
270
- rows[thisRowIndex - 1] = photos;
271
- }
272
- })
273
- }
274
-
275
- return rows;
276
- }
277
-
278
- /**
279
- * Moves a photo to the end of the previous row
280
- * @param e
281
- * @param props
282
- */
283
- export const movePhotoUp = (
284
- e: React.MouseEvent<HTMLButtonElement>,
285
- props: PhotoGridProps
286
- ): void => {
287
- e.preventDefault();
288
- const { id, rowKey } = getPhotoIdAndRowKey(e);
289
-
290
- let rowsCopy = { ...props.rows },
291
- thisRow = sortRow(rowsCopy[rowKey]),
292
- previousRowKey = rowKey - 1,
293
- previousRow: PhotoItem[] = [];
294
-
295
- if (rowsCopy[previousRowKey] != undefined) {
296
- previousRow = sortRow(rowsCopy[previousRowKey]);
297
- }
298
-
299
- const thisPhoto = getPhotoForId(thisRow, id);
300
-
301
- let start = thisPhoto.column + 1,
302
- end = thisRow.length;
303
-
304
- thisRow = deletePhotoFromRowByColumn(thisRow, thisPhoto.column);
305
- delete rowsCopy[rowKey];
306
-
307
- if (thisRow.length) {
308
- shufflePhotosBackOneColumn(thisRow, start, end);
309
- rowsCopy[rowKey] = thisRow;
310
- }
311
-
312
- previousRow = addPhotoToRow(previousRow, thisPhoto, previousRow.length + 1);
313
- delete rowsCopy[previousRowKey];
314
- rowsCopy[previousRowKey] = previousRow;
315
-
316
- rowsCopy = deleteRowIfEmpty(rowsCopy, rowKey);
317
-
318
- props.updateRows(rowsCopy);
319
- props.increaseChanges();
320
- }
321
-
322
- /**
323
- * Moves a photo to the beginning of the next row
324
- * @param e
325
- * @param props
326
- */
327
- export const movePhotoDown = (
328
- e: React.MouseEvent<HTMLButtonElement>,
329
- props: PhotoGridProps
330
- ) => {
331
- e.preventDefault();
332
- const { id, rowKey } = getPhotoIdAndRowKey(e);
333
-
334
- let rowsCopy = { ...props.rows },
335
- thisRow = sortRow(rowsCopy[rowKey]),
336
- nextRowKey = rowKey + 1;
337
-
338
- const thisPhoto = getPhotoForId(thisRow, id);
339
-
340
- let start = thisPhoto.column + 1,
341
- end = thisRow.length;
342
-
343
- thisRow = deletePhotoFromRowByColumn(thisRow, thisPhoto.column);
344
-
345
- delete rowsCopy[rowKey];
346
-
347
- if (thisRow.length) {
348
- thisRow = shufflePhotosBackOneColumn(thisRow, start, end);
349
- }
350
-
351
- let nextRow = null;
352
-
353
- if (rowsCopy[nextRowKey] == undefined) {
354
- thisPhoto.column = 1;
355
- nextRow = [thisPhoto];
356
- } else {
357
- nextRow = sortRow(rowsCopy[nextRowKey]);
358
- nextRow = shufflePhotosForwardOneColumn(nextRow, nextRow.length);
359
- nextRow = addPhotoToRow(nextRow, thisPhoto, 1);
360
- delete rowsCopy[nextRowKey];
361
- }
362
-
363
- rowsCopy[nextRowKey] = nextRow;
364
-
365
- if (thisRow.length) {
366
- rowsCopy[rowKey] = thisRow;
367
- }
368
-
369
- rowsCopy = deleteRowIfEmpty(rowsCopy, rowKey);
370
-
371
- props.updateRows(rowsCopy);
372
- props.increaseChanges();
373
- }
374
-
375
- /**
376
- * Swaps the row order
377
- * @param e
378
- * @param props
379
- */
380
- const swapRows = (
381
- rows: PhotoRows,
382
- firstRow: PhotoItem[],
383
- firstRowKey: number,
384
- secondRow: PhotoItem[],
385
- secondRowKey: number
386
- ): PhotoRows => {
387
- delete rows[secondRowKey];
388
- delete rows[firstRowKey];
389
- rows[secondRowKey] = firstRow;
390
- rows[firstRowKey] = secondRow;
391
-
392
- return rows;
393
- }
394
-
395
- /**
396
- * Moves a row up
397
- * @param e
398
- * @param props
399
- */
400
- export const moveRowUp = (
401
- e: React.MouseEvent<HTMLButtonElement>,
402
- props: PhotoGridProps
403
- ) => {
404
- e.preventDefault();
405
- const target = e.currentTarget as HTMLButtonElement;
406
- let rowKey = target.dataset.row;
407
-
408
- if (!rowKey) {
409
- throw new TypeError('row missing from row control');
410
- }
411
-
412
- const rowIndex: number = parseInt(rowKey),
413
- previousRowKey = rowIndex - 1;
414
-
415
- let rowsCopy = { ...props.rows },
416
- thisRow = sortRow(rowsCopy[rowIndex]);
417
-
418
- if (rowsCopy[previousRowKey] == undefined) {
419
- delete rowsCopy[rowIndex];
420
- rowsCopy[previousRowKey] = thisRow;
421
- } else {
422
- let previousRow = sortRow(rowsCopy[previousRowKey]);
423
- rowsCopy = swapRows(rowsCopy, thisRow, rowIndex, previousRow, previousRowKey);
424
- }
425
-
426
- props.updateRows(rowsCopy);
427
- props.increaseChanges();
428
- }
429
-
430
- /**
431
- * Moves a row down
432
- * @param e
433
- * @param props
434
- */
435
- export const moveRowDown = (
436
- e: React.MouseEvent<HTMLButtonElement>,
437
- props: PhotoGridProps
438
- ) => {
439
- e.preventDefault();
440
- const target = e.currentTarget as HTMLButtonElement;
441
- let rowKey = target.dataset.row;
442
-
443
- if (!rowKey) {
444
- throw new TypeError('row missing from row control');
445
- }
446
-
447
- const rowIndex: number = parseInt(rowKey),
448
- nextRowKey = rowIndex + 1;
449
-
450
- let rowsCopy = { ...props.rows },
451
- thisRow = sortRow(rowsCopy[rowIndex]);
452
-
453
- if (!rowsCopy[nextRowKey]) {
454
- throw new TypeError('There is no next row!');
455
- } else {
456
- const nextRow = sortRow(rowsCopy[nextRowKey]);
457
- rowsCopy = swapRows(rowsCopy, thisRow, rowIndex, nextRow, nextRowKey);
458
- }
459
-
460
- props.updateRows(rowsCopy);
461
- props.increaseChanges();
1
+ import { PhotoItem, PhotoRows, PhotoIdAndRowKey, PhotoGridProps } from './types';
2
+ import React from 'react';
3
+
4
+ /**
5
+ * Returns true if a photo has details
6
+ * @param photo
7
+ */
8
+ export const photoHasDetails = (photo: PhotoItem): boolean => {
9
+ if (
10
+ (photo.name != undefined && photo.name !== '')
11
+ || (photo.description != undefined && photo.description !== '')
12
+ ) {
13
+ return true;
14
+ }
15
+
16
+ return false;
17
+ }
18
+
19
+ /**
20
+ * Sorts photos into rows
21
+ * @param photos
22
+ */
23
+ export const sortPhotosIntoRows = (photos: PhotoItem[]): PhotoRows => {
24
+ let rows = {} as PhotoRows;
25
+
26
+ for (const photo of photos) {
27
+ const rowKey = photo.row;
28
+ if (!rows[rowKey]) {
29
+ rows[rowKey] = [];
30
+ }
31
+ rows[rowKey].push(photo);
32
+ }
33
+
34
+ return rows;
35
+ }
36
+
37
+ /**
38
+ * Return the photo property to be used for the src
39
+ * @param photo
40
+ * @param property
41
+ */
42
+ export const getImageSrcProperty = (photo: PhotoItem, property: string): string => {
43
+ switch (property) {
44
+ case 'id':
45
+ return photo.id;
46
+ case 'thumbnail_path':
47
+ return photo.thumbnail_path;
48
+ case 'image_path':
49
+ return photo.image_path;
50
+ }
51
+
52
+ return photo.image_path;
53
+ }
54
+
55
+ /**
56
+ * Sorts the photos in a row by column number
57
+ * @param row
58
+ */
59
+ export const sortRow = (row: PhotoItem[]) => {
60
+ return row.sort((a, b) => Math.floor(a.column) - Math.floor(b.column))
61
+ }
62
+
63
+ /**
64
+ * Get a photo from a row via id
65
+ * @param row
66
+ * @param id
67
+ */
68
+ const getPhotoForId = (row: PhotoItem[], id: string): PhotoItem => {
69
+ const photoResult = row.find(photo => photo.id === id);
70
+
71
+ if (photoResult === undefined) {
72
+ throw new TypeError('No photo was found in this row for that id');
73
+ }
74
+
75
+ return photoResult;
76
+ }
77
+
78
+ /**
79
+ * Get a photo from a row by column number
80
+ * @param row
81
+ * @param column
82
+ */
83
+ const getPhotoForColumn = (row: PhotoItem[], column: number): PhotoItem => {
84
+ const photoResult = row.find(photo => photo.column === column);
85
+
86
+ if (photoResult === undefined) {
87
+ throw new TypeError('No photo was found in this row for that column');
88
+ }
89
+
90
+ return photoResult;
91
+ }
92
+
93
+ /**
94
+ * Deletes a photo from a row by column number
95
+ * @param row
96
+ * @param column
97
+ */
98
+ const deletePhotoFromRowByColumn = (row: PhotoItem[], column: number): PhotoItem[] => {
99
+ return row.filter((photo: PhotoItem) => photo.column !== column);
100
+ }
101
+
102
+ /**
103
+ * Adds a photo to a row
104
+ * @param row
105
+ * @param photo
106
+ * @param column
107
+ */
108
+ const addPhotoToRow = (row: PhotoItem[] = [], photo: PhotoItem, column: number): PhotoItem[] => {
109
+ photo.column = column;
110
+ row.push(photo);
111
+ return row;
112
+ }
113
+
114
+ /**
115
+ * Swaps two photos around in the row
116
+ * @param row
117
+ * @param firstPhoto
118
+ * @param secondPhoto
119
+ */
120
+ const swapPhotosAround = (
121
+ row: PhotoItem[],
122
+ firstPhoto: PhotoItem,
123
+ secondPhoto: PhotoItem): PhotoItem[] => {
124
+ const firstColumn = firstPhoto.column,
125
+ secondColumn = secondPhoto.column;
126
+
127
+ row = deletePhotoFromRowByColumn(row, firstColumn);
128
+ row = deletePhotoFromRowByColumn(row, secondColumn);
129
+ row = addPhotoToRow(row, firstPhoto, secondColumn);
130
+ row = addPhotoToRow(row, secondPhoto, firstColumn);
131
+
132
+ return row;
133
+ }
134
+
135
+ /**
136
+ * Casts a the rowKey to a number if necessary
137
+ * @param rowKey
138
+ */
139
+ export const castRowKey = (rowKey: string | number): number => {
140
+ if (typeof rowKey == 'string') {
141
+ rowKey = parseInt(rowKey);
142
+ }
143
+
144
+ return rowKey;
145
+ }
146
+
147
+ /**
148
+ * Extract the row key and photo id from the clicked element
149
+ * @param e
150
+ */
151
+ const getPhotoIdAndRowKey = (e: React.MouseEvent<HTMLButtonElement>): PhotoIdAndRowKey => {
152
+ const button = e.currentTarget as HTMLButtonElement,
153
+ id = button.dataset.id,
154
+ rowKey = button.dataset.row;
155
+
156
+ if (!id || !rowKey) {
157
+ throw new TypeError('id or row key missing from photo control');
158
+ }
159
+
160
+ return {
161
+ id: id,
162
+ rowKey: parseInt(rowKey)
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Moves a photo one column to the left
168
+ * @param e
169
+ * @param props
170
+ */
171
+ export const movePhotoLeft = (
172
+ e: React.MouseEvent<HTMLButtonElement>,
173
+ props: PhotoGridProps
174
+ ) => {
175
+ e.preventDefault();
176
+
177
+ const { id, rowKey } = getPhotoIdAndRowKey(e);
178
+
179
+ let rowsCopy = { ...props.rows },
180
+ thisRow = sortRow(rowsCopy[rowKey]);
181
+
182
+ const thisPhoto = getPhotoForId(thisRow, id);
183
+
184
+ if (thisPhoto.column === 1) {
185
+ return;
186
+ }
187
+
188
+ const beforePhoto = getPhotoForColumn(thisRow, thisPhoto.column - 1);
189
+ thisRow = swapPhotosAround(thisRow, beforePhoto, thisPhoto);
190
+
191
+ delete rowsCopy[rowKey];
192
+ rowsCopy[rowKey] = thisRow;
193
+
194
+ props.updateRows(rowsCopy);
195
+ props.increaseChanges();
196
+ }
197
+
198
+ /**
199
+ * Move a photo one column to the right
200
+ * @param e
201
+ * @param props
202
+ */
203
+ export const movePhotoRight = (
204
+ e: React.MouseEvent<HTMLButtonElement>,
205
+ props: PhotoGridProps
206
+ ) => {
207
+ e.preventDefault();
208
+
209
+ const { id, rowKey } = getPhotoIdAndRowKey(e);
210
+
211
+ let rowsCopy = { ...props.rows },
212
+ thisRow = sortRow(rowsCopy[rowKey]);
213
+
214
+ const thisPhoto = getPhotoForId(thisRow, id);
215
+
216
+ if (thisPhoto.column === thisRow.length) {
217
+ return;
218
+ }
219
+
220
+ const afterPhoto = getPhotoForColumn(thisRow, thisPhoto.column + 1);
221
+ thisRow = swapPhotosAround(thisRow, thisPhoto, afterPhoto);
222
+
223
+ delete rowsCopy[rowKey];
224
+ rowsCopy[rowKey] = thisRow;
225
+
226
+ props.updateRows(rowsCopy);
227
+ props.increaseChanges();
228
+ }
229
+
230
+ /**
231
+ * All photos in the row move back a column (to the left)
232
+ * @param row
233
+ * @param start
234
+ * @param end
235
+ */
236
+ const shufflePhotosBackOneColumn = (row: PhotoItem[], start: number, end: number): PhotoItem[] => {
237
+ for (let x = start; x <= end; x++) {
238
+ const selectedPhoto = getPhotoForColumn(row, x);
239
+ row = deletePhotoFromRowByColumn(row, x);
240
+ row = addPhotoToRow(row, selectedPhoto, selectedPhoto.column - 1);
241
+ }
242
+
243
+ return row;
244
+ }
245
+
246
+ /**
247
+ * All the photos in the the row move forward a column (to the right)
248
+ * @param row
249
+ * @param start
250
+ */
251
+ const shufflePhotosForwardOneColumn = (row: PhotoItem[], start: number): PhotoItem[] => {
252
+ for (let x = start; x > 0; x--) {
253
+ const selectedPhoto = getPhotoForColumn(row, x);
254
+ row = deletePhotoFromRowByColumn(row, x);
255
+ row = addPhotoToRow(row, selectedPhoto, selectedPhoto.column + 1);
256
+ }
257
+
258
+ return row;
259
+ }
260
+
261
+ /**
262
+ * Deletes a row index from the data if it's empty
263
+ */
264
+ const deleteRowIfEmpty = (rows: PhotoRows, rowIndex: number) => {
265
+ if (rows[rowIndex] == undefined) {
266
+ Object.entries(rows).map(([index, photos]: [string, PhotoItem[]]) => {
267
+ const thisRowIndex = parseInt(index);
268
+ if (thisRowIndex > rowIndex) {
269
+ delete rows[thisRowIndex];
270
+ rows[thisRowIndex - 1] = photos;
271
+ }
272
+ })
273
+ }
274
+
275
+ return rows;
276
+ }
277
+
278
+ /**
279
+ * Moves a photo to the end of the previous row
280
+ * @param e
281
+ * @param props
282
+ */
283
+ export const movePhotoUp = (
284
+ e: React.MouseEvent<HTMLButtonElement>,
285
+ props: PhotoGridProps
286
+ ): void => {
287
+ e.preventDefault();
288
+ const { id, rowKey } = getPhotoIdAndRowKey(e);
289
+
290
+ let rowsCopy = { ...props.rows },
291
+ thisRow = sortRow(rowsCopy[rowKey]),
292
+ previousRowKey = rowKey - 1,
293
+ previousRow: PhotoItem[] = [];
294
+
295
+ if (rowsCopy[previousRowKey] != undefined) {
296
+ previousRow = sortRow(rowsCopy[previousRowKey]);
297
+ }
298
+
299
+ const thisPhoto = getPhotoForId(thisRow, id);
300
+
301
+ let start = thisPhoto.column + 1,
302
+ end = thisRow.length;
303
+
304
+ thisRow = deletePhotoFromRowByColumn(thisRow, thisPhoto.column);
305
+ delete rowsCopy[rowKey];
306
+
307
+ if (thisRow.length) {
308
+ shufflePhotosBackOneColumn(thisRow, start, end);
309
+ rowsCopy[rowKey] = thisRow;
310
+ }
311
+
312
+ previousRow = addPhotoToRow(previousRow, thisPhoto, previousRow.length + 1);
313
+ delete rowsCopy[previousRowKey];
314
+ rowsCopy[previousRowKey] = previousRow;
315
+
316
+ rowsCopy = deleteRowIfEmpty(rowsCopy, rowKey);
317
+
318
+ props.updateRows(rowsCopy);
319
+ props.increaseChanges();
320
+ }
321
+
322
+ /**
323
+ * Moves a photo to the beginning of the next row
324
+ * @param e
325
+ * @param props
326
+ */
327
+ export const movePhotoDown = (
328
+ e: React.MouseEvent<HTMLButtonElement>,
329
+ props: PhotoGridProps
330
+ ) => {
331
+ e.preventDefault();
332
+ const { id, rowKey } = getPhotoIdAndRowKey(e);
333
+
334
+ let rowsCopy = { ...props.rows },
335
+ thisRow = sortRow(rowsCopy[rowKey]),
336
+ nextRowKey = rowKey + 1;
337
+
338
+ const thisPhoto = getPhotoForId(thisRow, id);
339
+
340
+ let start = thisPhoto.column + 1,
341
+ end = thisRow.length;
342
+
343
+ thisRow = deletePhotoFromRowByColumn(thisRow, thisPhoto.column);
344
+
345
+ delete rowsCopy[rowKey];
346
+
347
+ if (thisRow.length) {
348
+ thisRow = shufflePhotosBackOneColumn(thisRow, start, end);
349
+ }
350
+
351
+ let nextRow = null;
352
+
353
+ if (rowsCopy[nextRowKey] == undefined) {
354
+ thisPhoto.column = 1;
355
+ nextRow = [thisPhoto];
356
+ } else {
357
+ nextRow = sortRow(rowsCopy[nextRowKey]);
358
+ nextRow = shufflePhotosForwardOneColumn(nextRow, nextRow.length);
359
+ nextRow = addPhotoToRow(nextRow, thisPhoto, 1);
360
+ delete rowsCopy[nextRowKey];
361
+ }
362
+
363
+ rowsCopy[nextRowKey] = nextRow;
364
+
365
+ if (thisRow.length) {
366
+ rowsCopy[rowKey] = thisRow;
367
+ }
368
+
369
+ rowsCopy = deleteRowIfEmpty(rowsCopy, rowKey);
370
+
371
+ props.updateRows(rowsCopy);
372
+ props.increaseChanges();
373
+ }
374
+
375
+ /**
376
+ * Swaps the row order
377
+ * @param e
378
+ * @param props
379
+ */
380
+ const swapRows = (
381
+ rows: PhotoRows,
382
+ firstRow: PhotoItem[],
383
+ firstRowKey: number,
384
+ secondRow: PhotoItem[],
385
+ secondRowKey: number
386
+ ): PhotoRows => {
387
+ delete rows[secondRowKey];
388
+ delete rows[firstRowKey];
389
+ rows[secondRowKey] = firstRow;
390
+ rows[firstRowKey] = secondRow;
391
+
392
+ return rows;
393
+ }
394
+
395
+ /**
396
+ * Moves a row up
397
+ * @param e
398
+ * @param props
399
+ */
400
+ export const moveRowUp = (
401
+ e: React.MouseEvent<HTMLButtonElement>,
402
+ props: PhotoGridProps
403
+ ) => {
404
+ e.preventDefault();
405
+ const target = e.currentTarget as HTMLButtonElement;
406
+ let rowKey = target.dataset.row;
407
+
408
+ if (!rowKey) {
409
+ throw new TypeError('row missing from row control');
410
+ }
411
+
412
+ const rowIndex: number = parseInt(rowKey),
413
+ previousRowKey = rowIndex - 1;
414
+
415
+ let rowsCopy = { ...props.rows },
416
+ thisRow = sortRow(rowsCopy[rowIndex]);
417
+
418
+ if (rowsCopy[previousRowKey] == undefined) {
419
+ delete rowsCopy[rowIndex];
420
+ rowsCopy[previousRowKey] = thisRow;
421
+ } else {
422
+ let previousRow = sortRow(rowsCopy[previousRowKey]);
423
+ rowsCopy = swapRows(rowsCopy, thisRow, rowIndex, previousRow, previousRowKey);
424
+ }
425
+
426
+ props.updateRows(rowsCopy);
427
+ props.increaseChanges();
428
+ }
429
+
430
+ /**
431
+ * Moves a row down
432
+ * @param e
433
+ * @param props
434
+ */
435
+ export const moveRowDown = (
436
+ e: React.MouseEvent<HTMLButtonElement>,
437
+ props: PhotoGridProps
438
+ ) => {
439
+ e.preventDefault();
440
+ const target = e.currentTarget as HTMLButtonElement;
441
+ let rowKey = target.dataset.row;
442
+
443
+ if (!rowKey) {
444
+ throw new TypeError('row missing from row control');
445
+ }
446
+
447
+ const rowIndex: number = parseInt(rowKey),
448
+ nextRowKey = rowIndex + 1;
449
+
450
+ let rowsCopy = { ...props.rows },
451
+ thisRow = sortRow(rowsCopy[rowIndex]);
452
+
453
+ if (!rowsCopy[nextRowKey]) {
454
+ throw new TypeError('There is no next row!');
455
+ } else {
456
+ const nextRow = sortRow(rowsCopy[nextRowKey]);
457
+ rowsCopy = swapRows(rowsCopy, thisRow, rowIndex, nextRow, nextRowKey);
458
+ }
459
+
460
+ props.updateRows(rowsCopy);
461
+ props.increaseChanges();
462
462
  }