pixel-react 1.5.5 → 1.5.7
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/.storybook/main.ts +7 -1
- package/lib/components/Charts/LineChart/types.d.ts +3 -0
- package/lib/components/DatePicker/types.d.ts +4 -0
- package/lib/components/Excel/ExcelContextMenu/ExcelContextMenu.d.ts +1 -7
- package/lib/components/Excel/ExcelFile/ExcelFileComponents/DataViewer.d.ts +1 -1
- package/lib/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.d.ts +1 -0
- package/lib/components/Excel/ExcelFile/ExcelFileComponents/reducerFunctions.d.ts +1 -0
- package/lib/components/Excel/ExcelFile/ExcelFileComponents/types.d.ts +5 -0
- package/lib/components/FileDropzone/types.d.ts +3 -0
- package/lib/components/LabelEditTextField/LabelEditTextField.stories.d.ts +0 -2
- package/lib/components/MultiSelect/MultiSelect.stories.d.ts +0 -1
- package/lib/components/Select/Select.stories.d.ts +0 -1
- package/lib/components/StateDropdown/StateDropdown.d.ts +1 -1
- package/lib/components/StateDropdown/StateDropdownTypes.d.ts +3 -0
- package/lib/index.d.ts +52 -2
- package/lib/index.esm.js +950 -581
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +950 -580
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/icons/approval_pending.svg +8 -8
- package/src/assets/icons/configuration.svg +3 -3
- package/src/assets/icons/dashboard_icon.svg +31 -0
- package/src/assets/icons/defects.svg +8 -8
- package/src/assets/icons/element.svg +4 -4
- package/src/assets/icons/info_user.svg +5 -0
- package/src/assets/icons/project_element.svg +4 -4
- package/src/assets/icons/step_group.svg +10 -10
- package/src/assets/icons/variable.svg +3 -3
- package/src/assets/styles/_colors.scss +1 -0
- package/src/components/AllProjectsDropdown/AllProjectsDropdown.scss +1 -1
- package/src/components/Charts/LineChart/LineChart.scss +8 -7
- package/src/components/Charts/LineChart/LineChart.stories.tsx +170 -51
- package/src/components/Charts/LineChart/LineChart.tsx +30 -27
- package/src/components/Charts/LineChart/types.ts +22 -20
- package/src/components/DatePicker/DatePicker.scss +4 -3
- package/src/components/DatePicker/DatePicker.stories.tsx +27 -14
- package/src/components/DatePicker/DatePicker.tsx +62 -49
- package/src/components/DatePicker/types.ts +5 -0
- package/src/components/Excel/ColorBarSelector/ColorBarSelector.scss +8 -4
- package/src/components/Excel/ColorBarSelector/ColorBarSelector.tsx +2 -2
- package/src/components/Excel/ExcelContextMenu/ExcelContextMenu.scss +23 -35
- package/src/components/Excel/ExcelContextMenu/ExcelContextMenu.tsx +3 -12
- package/src/components/Excel/ExcelFile/ExcelFile.scss +31 -25
- package/src/components/Excel/ExcelFile/ExcelFile.tsx +157 -47
- package/src/components/Excel/ExcelFile/ExcelFileComponents/Cell.tsx +5 -4
- package/src/components/Excel/ExcelFile/ExcelFileComponents/ColumnIndicator.tsx +3 -3
- package/src/components/Excel/ExcelFile/ExcelFileComponents/DataViewer.tsx +40 -1
- package/src/components/Excel/ExcelFile/ExcelFileComponents/RowIndicator.tsx +3 -3
- package/src/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.scss +10 -0
- package/src/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.tsx +9 -45
- package/src/components/Excel/ExcelFile/ExcelFileComponents/reducer.ts +43 -2
- package/src/components/Excel/ExcelFile/ExcelFileComponents/reducerFunctions.ts +40 -5
- package/src/components/Excel/ExcelFile/ExcelFileComponents/types.ts +3 -1
- package/src/components/Excel/ExcelFile.stories.tsx +42 -43
- package/src/components/Excel/ExcelToolBar/ExcelToolBar.scss +80 -20
- package/src/components/Excel/ExcelToolBar/ExcelToolBar.tsx +171 -159
- package/src/components/FileDropzone/Dropzone.tsx +2 -0
- package/src/components/FileDropzone/FileDropzone.scss +1 -2
- package/src/components/FileDropzone/FileDropzone.stories.tsx +3 -0
- package/src/components/FileDropzone/FileDropzone.tsx +11 -3
- package/src/components/FileDropzone/types.ts +5 -0
- package/src/components/Icon/Icon.stories.tsx +5 -4
- package/src/components/Icon/iconList.ts +4 -0
- package/src/components/MultiSelect/MultiSelect.scss +41 -50
- package/src/components/MultiSelect/MultiSelect.tsx +48 -48
- package/src/components/Select/Select.scss +11 -1
- package/src/components/Select/Select.tsx +2 -2
- package/src/components/StateDropdown/StateDropdown.stories.tsx +5 -0
- package/src/components/StateDropdown/StateDropdown.tsx +27 -12
- package/src/components/StateDropdown/StateDropdownTypes.tsx +6 -0
- package/src/components/TableTree/TableTree.scss +17 -15
- package/src/components/TableTree/TableTree.tsx +42 -40
- package/src/index.ts +2 -0
- package/lib/assets/fonts/Poppins-Bold.ttf +0 -0
- package/lib/assets/fonts/Poppins-Medium.ttf +0 -0
- package/lib/assets/fonts/Poppins-Regular.ttf +0 -0
- package/lib/assets/fonts/Poppins-SemiBold.ttf +0 -0
- package/lib/components/AddButton/AddButton.d.ts +0 -5
- package/lib/components/AddButton/AddButton.stories.d.ts +0 -6
- package/lib/components/AddButton/index.d.ts +0 -1
- package/lib/components/AddButton/types.d.ts +0 -4
- package/lib/components/AttachImage/AttachImage.stories.d.ts +0 -7
- package/lib/components/Charts/BarChart/BarChart.stories.d.ts +0 -6
- package/lib/components/Charts/IconRadialChart/IconRadialChart.stories.d.ts +0 -8
- package/lib/components/Charts/LineChart/LineChart.stories.d.ts +0 -7
- package/lib/components/Charts/MultiRadialChart/MultiRadialChart.stories.d.ts +0 -8
- package/lib/components/ConnectingBranch/ConnectingBranch.stories.d.ts +0 -6
- package/lib/components/EditTextField/EditTextField.stories.d.ts +0 -10
- package/lib/components/Editor/Editor.stories.d.ts +0 -6
- package/lib/components/Excel/ContextMenu/ContextMenu.d.ts +0 -4
- package/lib/components/Excel/ExcelFile.stories.d.ts +0 -6
- package/lib/components/ExcelFile/ChangeExcelStyles.d.ts +0 -14
- package/lib/components/ExcelFile/ImportExcelStyles.d.ts +0 -24
- package/lib/components/StatusCard/StatusCard.stories.d.ts +0 -11
- package/lib/utils/getSequentialPayload/getSequentialPayload.stories.d.ts +0 -10
- /package/lib/components/ExcelFile/{ColorBarSelector → ColorBarselector}/ColorBarSelector.d.ts +0 -0
@@ -26,6 +26,7 @@ const CustomDatePicker: React.FC<DatePickerProps> = ({
|
|
26
26
|
timeFormat = 'hh:mm a',
|
27
27
|
error,
|
28
28
|
helperText = '',
|
29
|
+
dateOnly = false,
|
29
30
|
}) => {
|
30
31
|
const [timeValue, setTimeValue] = useState<string>('');
|
31
32
|
const [selectedDate, setSelectedDate] = useState<Date | undefined>();
|
@@ -121,17 +122,23 @@ const CustomDatePicker: React.FC<DatePickerProps> = ({
|
|
121
122
|
};
|
122
123
|
|
123
124
|
const handleDaySelect = (date: Date | undefined) => {
|
124
|
-
if (
|
125
|
-
// if need to set time to current time in case no time selected
|
126
|
-
const now = new Date();
|
127
|
-
date?.setHours(now.getHours(), now.getMinutes(), now.getSeconds());
|
128
|
-
|
125
|
+
if (dateOnly) {
|
129
126
|
setSelectedDate(date);
|
127
|
+
onChange(date);
|
128
|
+
resetAndCloseDatePicker();
|
130
129
|
} else {
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
130
|
+
if (!timeValue || !date) {
|
131
|
+
// if need to set time to current time in case no time selected
|
132
|
+
const now = new Date();
|
133
|
+
date?.setHours(now.getHours(), now.getMinutes(), now.getSeconds());
|
134
|
+
|
135
|
+
setSelectedDate(date);
|
136
|
+
} else {
|
137
|
+
const [hoursStr, minutesStr] = timeValue.split(':');
|
138
|
+
date.setHours(parseInt(hoursStr ? hoursStr : '0', 10) || 0);
|
139
|
+
date.setMinutes(parseInt(minutesStr ? minutesStr : '0', 10) || 0);
|
140
|
+
setSelectedDate(date);
|
141
|
+
}
|
135
142
|
}
|
136
143
|
};
|
137
144
|
|
@@ -273,7 +280,7 @@ const CustomDatePicker: React.FC<DatePickerProps> = ({
|
|
273
280
|
onClick={onClick}
|
274
281
|
disabled={disabled}
|
275
282
|
>
|
276
|
-
<Icon name="left_arrow_icon" height={
|
283
|
+
<Icon name="left_arrow_icon" height={20} width={20} />
|
277
284
|
</button>
|
278
285
|
);
|
279
286
|
};
|
@@ -287,7 +294,7 @@ const CustomDatePicker: React.FC<DatePickerProps> = ({
|
|
287
294
|
onClick={onClick}
|
288
295
|
disabled={disabled}
|
289
296
|
>
|
290
|
-
<Icon name="right_arrow_icon" height={
|
297
|
+
<Icon name="right_arrow_icon" height={20} width={20} />
|
291
298
|
</button>
|
292
299
|
);
|
293
300
|
};
|
@@ -340,22 +347,24 @@ const CustomDatePicker: React.FC<DatePickerProps> = ({
|
|
340
347
|
)}
|
341
348
|
</div>
|
342
349
|
|
343
|
-
|
344
|
-
<
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
350
|
+
{!dateOnly && (
|
351
|
+
<div className="ff-input-with-icon ff-time-input-field">
|
352
|
+
<Icon
|
353
|
+
name={'clock_icon'}
|
354
|
+
hoverEffect={false}
|
355
|
+
className="ff-clock-icon"
|
356
|
+
/>
|
357
|
+
<input
|
358
|
+
type="text"
|
359
|
+
placeholder="Select time"
|
360
|
+
className="ff-time-input"
|
361
|
+
value={value ? formatInTimeZone(value, timezone, timeFormat) : ''}
|
362
|
+
disabled={disabled}
|
363
|
+
onClick={handleDateInputClick}
|
364
|
+
readOnly
|
365
|
+
/>
|
366
|
+
</div>
|
367
|
+
)}
|
359
368
|
</div>
|
360
369
|
|
361
370
|
{isPickerOpen && (
|
@@ -406,29 +415,33 @@ const CustomDatePicker: React.FC<DatePickerProps> = ({
|
|
406
415
|
: {}),
|
407
416
|
}}
|
408
417
|
/>
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
<Button
|
419
|
-
className="ff-date-picker-button"
|
420
|
-
variant="secondary"
|
421
|
-
onClick={handleCancel}
|
422
|
-
label="Cancel"
|
423
|
-
/>
|
424
|
-
<Button
|
425
|
-
className="ff-date-picker-button"
|
426
|
-
variant="primary"
|
427
|
-
onClick={handleSave}
|
428
|
-
label="Save"
|
429
|
-
disabled={timeError}
|
430
|
-
/>
|
418
|
+
{!dateOnly && (
|
419
|
+
<TimePicker
|
420
|
+
value={timeValue}
|
421
|
+
onChange={handleTimeChange}
|
422
|
+
minTime={minTime}
|
423
|
+
maxTime={maxTime}
|
424
|
+
onErrorChange={setTimeError}
|
425
|
+
/>
|
426
|
+
)}
|
431
427
|
</div>
|
428
|
+
{!dateOnly && (
|
429
|
+
<div className="ff-date-picker-controls">
|
430
|
+
<Button
|
431
|
+
className="ff-date-picker-button"
|
432
|
+
variant="secondary"
|
433
|
+
onClick={handleCancel}
|
434
|
+
label="Cancel"
|
435
|
+
/>
|
436
|
+
<Button
|
437
|
+
className="ff-date-picker-button"
|
438
|
+
variant="primary"
|
439
|
+
onClick={handleSave}
|
440
|
+
label="Save"
|
441
|
+
disabled={timeError}
|
442
|
+
/>
|
443
|
+
</div>
|
444
|
+
)}
|
432
445
|
</div>
|
433
446
|
)}
|
434
447
|
</div>
|
@@ -58,6 +58,11 @@ export interface DatePickerProps {
|
|
58
58
|
* Helper text to display below the input field, used for error messages or instructions.
|
59
59
|
*/
|
60
60
|
helperText?: string | undefined;
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Select only date .
|
64
|
+
*/
|
65
|
+
dateOnly?: boolean;
|
61
66
|
}
|
62
67
|
|
63
68
|
export type DateValue = Date | undefined;
|
@@ -1,8 +1,12 @@
|
|
1
|
-
.color-
|
1
|
+
.ff-excel-color-selector {
|
2
|
+
position: absolute;
|
2
3
|
background-color: var(--error_light);
|
3
|
-
width:
|
4
|
-
height:
|
5
|
-
|
4
|
+
width: 14px;
|
5
|
+
height: 3px;
|
6
|
+
bottom: 3px;
|
7
|
+
z-index: 200;
|
8
|
+
cursor: pointer;
|
9
|
+
.ff-excel-color-selector-picker {
|
6
10
|
width: 100%;
|
7
11
|
height: 0;
|
8
12
|
padding: 0;
|
@@ -20,7 +20,7 @@ const ColorBarSelector: React.FC<ColorBarSelectorProps> = ({
|
|
20
20
|
|
21
21
|
return (
|
22
22
|
<div
|
23
|
-
className="color-
|
23
|
+
className="ff-excel-color-selector"
|
24
24
|
style={{
|
25
25
|
backgroundColor: `${color}`,
|
26
26
|
}}
|
@@ -29,7 +29,7 @@ const ColorBarSelector: React.FC<ColorBarSelectorProps> = ({
|
|
29
29
|
<input
|
30
30
|
type="color"
|
31
31
|
disabled={disabled}
|
32
|
-
className="
|
32
|
+
className="ff-excel-color-selector-picker"
|
33
33
|
ref={colorInputRef}
|
34
34
|
onChange={(e) => {
|
35
35
|
setColor(e.target.value);
|
@@ -1,39 +1,27 @@
|
|
1
|
-
|
1
|
+
.ff-excel-menu {
|
2
|
+
position: absolute;
|
3
|
+
border: 1px solid var(--option-card-border-color);
|
4
|
+
background: var(--option-card-bg-color);
|
5
|
+
border-radius: 4px;
|
6
|
+
margin: 2px;
|
7
|
+
min-height: 32px;
|
8
|
+
min-width: 111px;
|
9
|
+
white-space: nowrap;
|
10
|
+
z-index: 100;
|
2
11
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
border:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
z-index: 100;
|
14
|
-
|
15
|
-
.ff-options {
|
16
|
-
@extend .fontSm;
|
17
|
-
cursor: pointer;
|
18
|
-
border-radius: 4px;
|
19
|
-
display: flex;
|
20
|
-
align-items: center;
|
21
|
-
padding: 8px;
|
22
|
-
line-height: 16px;
|
23
|
-
gap: 8px;
|
24
|
-
&:hover {
|
25
|
-
background-color: var(--hover-color);
|
26
|
-
}
|
27
|
-
label {
|
28
|
-
cursor: pointer;
|
29
|
-
}
|
12
|
+
.ff-excel-menu-options {
|
13
|
+
color: var(--text-color);
|
14
|
+
cursor: pointer;
|
15
|
+
border-radius: 3px;
|
16
|
+
display: flex;
|
17
|
+
align-items: center;
|
18
|
+
padding: 4px;
|
19
|
+
gap: 8px;
|
20
|
+
&:hover {
|
21
|
+
background-color: var(--hover-color);
|
30
22
|
}
|
31
|
-
|
32
|
-
|
33
|
-
opacity: 0.5;
|
34
|
-
cursor: no-drop;
|
35
|
-
label {
|
36
|
-
cursor: no-drop;
|
37
|
-
}
|
23
|
+
label {
|
24
|
+
cursor: pointer;
|
38
25
|
}
|
39
26
|
}
|
27
|
+
}
|
@@ -1,30 +1,21 @@
|
|
1
1
|
import Icon from '../../Icon';
|
2
2
|
import './ExcelContextMenu.scss';
|
3
3
|
import Typography from '../../Typography';
|
4
|
-
import
|
5
|
-
import {
|
6
|
-
CellBase,
|
7
|
-
ContextMenuState,
|
8
|
-
} from '../ExcelFile/ExcelFileComponents/types';
|
4
|
+
import { ContextMenuState } from '../ExcelFile/ExcelFileComponents/types';
|
9
5
|
|
10
6
|
type ExcelContextMenuProps = {
|
11
|
-
data: Matrix.Matrix<CellBase>;
|
12
7
|
contextMenu: ContextMenuState;
|
13
|
-
addRowTop: (data: Matrix.Matrix<CellBase>) => void;
|
14
|
-
addColumnLeft: (data: Matrix.Matrix<CellBase>) => void;
|
15
|
-
deleteRow: (data: Matrix.Matrix<CellBase>) => void;
|
16
|
-
deleteColumn: (data: Matrix.Matrix<CellBase>) => void;
|
17
8
|
};
|
18
9
|
|
19
10
|
const ExcelContextMenu: React.FC<ExcelContextMenuProps> = ({ contextMenu }) => {
|
20
11
|
return (
|
21
12
|
<div
|
22
|
-
className="ff-
|
13
|
+
className="ff-excel-menu"
|
23
14
|
style={{ left: contextMenu.position.x, top: contextMenu.position.y }}
|
24
15
|
>
|
25
16
|
{contextMenu.options.map((option) => (
|
26
17
|
<div
|
27
|
-
className={'ff-options'}
|
18
|
+
className={'ff-excel-menu-options'}
|
28
19
|
onClick={() => {
|
29
20
|
option.action();
|
30
21
|
}}
|
@@ -1,31 +1,41 @@
|
|
1
|
-
.excel-page {
|
1
|
+
.ff-excel-page {
|
2
2
|
width: 100%;
|
3
3
|
display: flex;
|
4
|
+
margin-top: 40px;
|
4
5
|
flex-direction: column;
|
5
6
|
align-items: center;
|
6
7
|
|
7
|
-
.excel-book {
|
8
|
+
.ff-excel-book {
|
8
9
|
position: relative;
|
9
10
|
width: 100%;
|
10
|
-
.excel-sheet {
|
11
|
-
overflow: auto;
|
12
|
-
scrollbar-width: thin;
|
13
|
-
}
|
14
11
|
|
15
|
-
.sheet
|
16
|
-
|
17
|
-
|
12
|
+
// .ff-excel-sheet { TODO
|
13
|
+
// overflow: auto;
|
14
|
+
// scrollbar-width: none;
|
15
|
+
// &::-webkit-scrollbar {
|
16
|
+
// height: 0px;
|
17
|
+
// }
|
18
|
+
// }
|
19
|
+
|
20
|
+
.ff-excel-sheet-bar {
|
21
|
+
margin-left: 83px;
|
22
|
+
display: flex;
|
23
|
+
height: 36px;
|
18
24
|
align-items: center;
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
color: var(--brand2-color);
|
26
|
+
margin-top: -2px;
|
27
|
+
box-shadow: 0px 0px 4px -1px var(--toggle-strip-shadow);
|
28
|
+
|
29
|
+
.ff-excel-add-sheet-icon {
|
30
|
+
padding: 4px 6px;
|
23
31
|
}
|
24
|
-
.excel-tab-container {
|
32
|
+
.ff-excel-tab-container {
|
33
|
+
height: 36px;
|
34
|
+
width: 860px;
|
25
35
|
display: flex;
|
26
36
|
overflow-x: auto;
|
27
37
|
align-items: center;
|
28
|
-
scrollbar-width:
|
38
|
+
scrollbar-width: none;
|
29
39
|
scrollbar-color: var(--hover-color) transparent;
|
30
40
|
&::-webkit-scrollbar-track {
|
31
41
|
background-color: transparent;
|
@@ -33,12 +43,15 @@
|
|
33
43
|
&::-webkit-scrollbar-thumb {
|
34
44
|
border-radius: 5px;
|
35
45
|
}
|
36
|
-
|
37
|
-
|
46
|
+
&::-webkit-scrollbar {
|
47
|
+
height: 0px;
|
48
|
+
}
|
49
|
+
.ff-excel-tab-list {
|
50
|
+
margin-top: 2px;
|
51
|
+
padding: 10px 9px;
|
38
52
|
min-width: max-content;
|
39
53
|
cursor: pointer;
|
40
54
|
display: flex;
|
41
|
-
font-weight: bold;
|
42
55
|
background-color: var(--hover-color);
|
43
56
|
&.active {
|
44
57
|
background-color: var(--excel-sheet-button-color);
|
@@ -53,10 +66,3 @@
|
|
53
66
|
}
|
54
67
|
}
|
55
68
|
}
|
56
|
-
.menu-list {
|
57
|
-
display: flex;
|
58
|
-
align-items: center;
|
59
|
-
.menu-title {
|
60
|
-
padding-left: 5px;
|
61
|
-
}
|
62
|
-
}
|
@@ -2,11 +2,13 @@ import React, { useState, useRef, useEffect } from 'react';
|
|
2
2
|
import Spreadsheet, { CellBase } from './ExcelFileComponents/index';
|
3
3
|
import * as Matrix from './ExcelFileComponents/matrix';
|
4
4
|
import './ExcelFile.scss';
|
5
|
-
import { Col, Row } from '../../GridLayout/GridLayout';
|
6
5
|
import Tooltip from '../../Tooltip';
|
7
6
|
import Icon from '../../Icon';
|
8
7
|
import Toastify from '../../Toastify';
|
9
8
|
import { toast } from '../../Toastify/Toastify';
|
9
|
+
import { ContextMenuState } from './ExcelFileComponents/types';
|
10
|
+
import ExcelContextMenu from '../ExcelContextMenu/ExcelContextMenu';
|
11
|
+
import Typography from '../../Typography';
|
10
12
|
|
11
13
|
interface ExcelFileProps {
|
12
14
|
/** The Excel data containing sheets and their content */
|
@@ -33,6 +35,12 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
33
35
|
onSave = () => {},
|
34
36
|
}) => {
|
35
37
|
const [sheetNames, setSheetNames] = useState<string[]>([]);
|
38
|
+
const [contextMenu, setContextMenu] = React.useState<ContextMenuState>({
|
39
|
+
open: false,
|
40
|
+
position: { x: 0, y: 0 },
|
41
|
+
options: [{ label: '', value: '', iconName: '', action: () => {} }],
|
42
|
+
});
|
43
|
+
|
36
44
|
const EmptyRow: CellBase = {
|
37
45
|
value: '',
|
38
46
|
style: {
|
@@ -41,6 +49,7 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
41
49
|
borderColor: 'var(--toggle-strip-color)',
|
42
50
|
},
|
43
51
|
};
|
52
|
+
|
44
53
|
const [selectedSheet, setSelectedSheet] = useState<{
|
45
54
|
name: string;
|
46
55
|
index: number;
|
@@ -54,15 +63,37 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
54
63
|
Matrix.Matrix<CellBase>
|
55
64
|
>([[EmptyRow]]);
|
56
65
|
|
57
|
-
|
66
|
+
const pageRef = useRef<string>('');
|
58
67
|
const sheetRef = useRef<HTMLDivElement | null>(null);
|
59
68
|
|
60
|
-
|
69
|
+
const checkVal = (val: any) => {
|
61
70
|
if (val === undefined || val === null) {
|
62
71
|
return null;
|
63
72
|
}
|
64
73
|
return val;
|
65
74
|
};
|
75
|
+
|
76
|
+
const options = [
|
77
|
+
{
|
78
|
+
label: 'Add Sheet',
|
79
|
+
value: 'Add Sheet',
|
80
|
+
iconName: 'plus_icon',
|
81
|
+
action: () => {
|
82
|
+
handleAddSheet();
|
83
|
+
},
|
84
|
+
disable: false,
|
85
|
+
},
|
86
|
+
{
|
87
|
+
label: 'Delete Sheet',
|
88
|
+
value: 'Delete Sheet',
|
89
|
+
iconName: 'delete',
|
90
|
+
action: () => {
|
91
|
+
handleDeleteSheet();
|
92
|
+
},
|
93
|
+
disable: false,
|
94
|
+
},
|
95
|
+
];
|
96
|
+
|
66
97
|
useEffect(() => {
|
67
98
|
const payload = excelData;
|
68
99
|
const sheetNames = payload.sheets.map((e) => e.sheetName);
|
@@ -111,7 +142,7 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
111
142
|
|
112
143
|
const onEvaluateChange = (data: Matrix.Matrix<CellBase>) => {
|
113
144
|
setWorksheetsData((prev) => ({ ...prev, [pageRef.current]: data }));
|
114
|
-
onSave()
|
145
|
+
onSave();
|
115
146
|
};
|
116
147
|
|
117
148
|
const [editingSheet, setEditingSheet] = useState<number | null>(null);
|
@@ -142,6 +173,38 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
142
173
|
pageRef.current = newSheetName;
|
143
174
|
};
|
144
175
|
|
176
|
+
useEffect(() => {
|
177
|
+
const selectedData = worksheetsData[selectedSheet.name];
|
178
|
+
if (selectedData !== undefined) {
|
179
|
+
setSelectedSheetData(selectedData);
|
180
|
+
} else {
|
181
|
+
setSelectedSheetData([]);
|
182
|
+
}
|
183
|
+
}, [selectedSheet.name, worksheetsData]);
|
184
|
+
|
185
|
+
const handleDeleteSheet = () => {
|
186
|
+
const { index, name } = selectedSheet;
|
187
|
+
|
188
|
+
if (sheetNames.length > 1) {
|
189
|
+
let updatedSheetNames = sheetNames.slice();
|
190
|
+
updatedSheetNames.splice(index, 1);
|
191
|
+
|
192
|
+
const updatedWorksheetsData = { ...worksheetsData };
|
193
|
+
|
194
|
+
delete updatedWorksheetsData[name];
|
195
|
+
const newIndex = Math.min(index, updatedSheetNames.length - 1);
|
196
|
+
|
197
|
+
setSheetNames(updatedSheetNames);
|
198
|
+
setWorksheetsData(updatedWorksheetsData);
|
199
|
+
setSelectedSheet({
|
200
|
+
index: newIndex,
|
201
|
+
name: updatedSheetNames[newIndex] ? updatedSheetNames[newIndex] : '',
|
202
|
+
});
|
203
|
+
} else {
|
204
|
+
toast.warning('Cannot delete the last sheet.');
|
205
|
+
}
|
206
|
+
};
|
207
|
+
|
145
208
|
const handleNameChange = (
|
146
209
|
event: React.SyntheticEvent<HTMLDivElement>,
|
147
210
|
index: number,
|
@@ -214,6 +277,9 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
214
277
|
}
|
215
278
|
|
216
279
|
const handleSheetChange = (name: string, index: number) => {
|
280
|
+
if (name === selectedSheet.name || index === selectedSheet.index) {
|
281
|
+
return;
|
282
|
+
}
|
217
283
|
setSelectedSheet({ index, name });
|
218
284
|
setSheetNames((prev: string[]) => {
|
219
285
|
const updatedSheetNames = [...prev];
|
@@ -239,18 +305,63 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
239
305
|
selection?.addRange(range);
|
240
306
|
};
|
241
307
|
|
308
|
+
const handleClickOutside = React.useCallback(
|
309
|
+
(event: MouseEvent) => {
|
310
|
+
if (contextMenu.open) {
|
311
|
+
event.preventDefault();
|
312
|
+
event.stopPropagation();
|
313
|
+
setContextMenu({
|
314
|
+
open: false,
|
315
|
+
position: { x: 0, y: 0 },
|
316
|
+
options: [{ label: '', value: '', iconName: '', action: () => {} }],
|
317
|
+
});
|
318
|
+
}
|
319
|
+
},
|
320
|
+
[contextMenu.open]
|
321
|
+
);
|
322
|
+
|
323
|
+
React.useEffect(() => {
|
324
|
+
document.addEventListener('click', handleClickOutside);
|
325
|
+
return () => {
|
326
|
+
document.removeEventListener('click', handleClickOutside);
|
327
|
+
};
|
328
|
+
}, [handleClickOutside]);
|
329
|
+
|
330
|
+
const contextClick = (event: React.MouseEvent) => {
|
331
|
+
event.preventDefault();
|
332
|
+
const target = event.target as HTMLElement;
|
333
|
+
const selectedSheetName = target.innerText;
|
334
|
+
|
335
|
+
sheetNames.map((name, index) => {
|
336
|
+
if (selectedSheetName === name) {
|
337
|
+
handleSheetChange(name, index);
|
338
|
+
}
|
339
|
+
});
|
340
|
+
|
341
|
+
setContextMenu({
|
342
|
+
open: true,
|
343
|
+
position: {
|
344
|
+
x: event.pageX - 50,
|
345
|
+
y: event.pageY - 350,
|
346
|
+
},
|
347
|
+
options: options,
|
348
|
+
});
|
349
|
+
};
|
350
|
+
|
242
351
|
return (
|
243
|
-
<div className="excel-page">
|
352
|
+
<div className="ff-excel-page">
|
244
353
|
{sheetNames.length > 0 && (
|
245
|
-
<div className="excel-book">
|
246
|
-
<
|
354
|
+
<div className="ff-excel-book">
|
355
|
+
{contextMenu.open && <ExcelContextMenu contextMenu={contextMenu} />}
|
356
|
+
<div ref={sheetRef} className="ff-excel-sheet">
|
247
357
|
<Spreadsheet
|
358
|
+
setContextMenu={setContextMenu}
|
248
359
|
data={selectedSheetData}
|
249
360
|
onEvaluatedDataChange={onEvaluateChange}
|
250
361
|
/>
|
251
362
|
</div>
|
252
|
-
<
|
253
|
-
<
|
363
|
+
<div className="ff-excel-sheet-bar">
|
364
|
+
<div className="ff-excel-add-sheet-icon">
|
254
365
|
<Tooltip title="Add Sheet" placement="top">
|
255
366
|
<Icon
|
256
367
|
className="cursor-pointer ml-1"
|
@@ -263,45 +374,44 @@ const ExcelFile: React.FC<ExcelFileProps> = ({
|
|
263
374
|
width={20}
|
264
375
|
/>
|
265
376
|
</Tooltip>
|
266
|
-
</
|
267
|
-
<
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
377
|
+
</div>
|
378
|
+
<div className="ff-excel-tab-container">
|
379
|
+
{sheetNames.map((name, index) => (
|
380
|
+
<div
|
381
|
+
key={name}
|
382
|
+
onContextMenu={contextClick}
|
383
|
+
className={`ff-excel-tab-list ${
|
384
|
+
name === selectedSheet.name ? 'active' : ''
|
385
|
+
}`}
|
386
|
+
onClick={() => {
|
387
|
+
handleSheetChange(name, index);
|
388
|
+
}}
|
389
|
+
suppressContentEditableWarning={editingSheet === index}
|
390
|
+
onDoubleClick={(e) => {
|
391
|
+
setEditingSheet(index);
|
392
|
+
if (editingSheet === null) {
|
393
|
+
setTimeout(
|
394
|
+
() => setCursorToEnd(e.target as HTMLDivElement),
|
395
|
+
0
|
396
|
+
);
|
397
|
+
}
|
398
|
+
}}
|
399
|
+
contentEditable={editingSheet === index}
|
400
|
+
onBlur={(e) => {
|
401
|
+
handleNameChange(e, index, name);
|
402
|
+
}}
|
403
|
+
onKeyDown={(e) => {
|
404
|
+
if (e.key === 'Enter') {
|
405
|
+
e.preventDefault();
|
290
406
|
handleNameChange(e, index, name);
|
291
|
-
}
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
{name}
|
300
|
-
</div>
|
301
|
-
))}
|
302
|
-
</div>
|
303
|
-
</Col>
|
304
|
-
</Row>
|
407
|
+
}
|
408
|
+
}}
|
409
|
+
>
|
410
|
+
<Typography>{name}</Typography>
|
411
|
+
</div>
|
412
|
+
))}
|
413
|
+
</div>
|
414
|
+
</div>
|
305
415
|
</div>
|
306
416
|
)}
|
307
417
|
<Toastify />
|