pixel-react-excel-sheet 1.0.32 → 1.0.33

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.
Files changed (92) hide show
  1. package/lib/components/Accordion/Accordion.d.ts +1 -1
  2. package/lib/components/Accordion/types.d.ts +4 -0
  3. package/lib/components/AllProjectsDropdown/types.d.ts +2 -0
  4. package/lib/components/Button/Button.d.ts +2 -2
  5. package/lib/components/Button/types.d.ts +17 -0
  6. package/lib/components/Charts/DashboardDonutChart/types.d.ts +1 -0
  7. package/lib/components/Charts/MultiRadialChart/types.d.ts +3 -0
  8. package/lib/components/ChooseFile/ChooseFile.d.ts +3 -0
  9. package/lib/components/ChooseFile/types.d.ts +68 -0
  10. package/lib/components/ConditionalDropdown/ConditionalDropdown.d.ts +1 -2
  11. package/lib/components/ConditionalDropdown/types.d.ts +3 -3
  12. package/lib/components/LabelEditTextField/types.d.ts +3 -1
  13. package/lib/components/ScriptSwitchButton/ScriptSwitchButton.d.ts +9 -0
  14. package/lib/components/ScriptSwitchButton/index.d.ts +1 -0
  15. package/lib/components/StatusCard/types.d.ts +2 -0
  16. package/lib/components/TableTree/Components/TableCell.d.ts +1 -1
  17. package/lib/components/TableTree/Components/TableRow.d.ts +1 -1
  18. package/lib/components/TableTree/data.d.ts +115 -1
  19. package/lib/components/TableTree/types.d.ts +4 -0
  20. package/lib/index.d.ts +218 -65
  21. package/lib/index.esm.js +721 -419
  22. package/lib/index.esm.js.map +1 -1
  23. package/lib/index.js +767 -418
  24. package/lib/index.js.map +1 -1
  25. package/lib/tsconfig.tsbuildinfo +1 -1
  26. package/lib/validations/regex.d.ts +46 -0
  27. package/package.json +1 -1
  28. package/src/StyleGuide/ColorPalette/colorPaletteList.ts +5 -0
  29. package/src/assets/Themes/BaseTheme.scss +1 -1
  30. package/src/assets/Themes/BlueTheme.scss +1 -1
  31. package/src/assets/Themes/DarkTheme.scss +1 -1
  32. package/src/assets/icons/failed_status_icon.svg +1 -1
  33. package/src/assets/icons/flaky_status_icon.svg +1 -1
  34. package/src/assets/icons/settings.svg +3 -0
  35. package/src/assets/icons/skipped_status_icon.svg +1 -1
  36. package/src/assets/icons/warning_status_icon.svg +1 -1
  37. package/src/components/Accordion/Accordion.stories.tsx +13 -0
  38. package/src/components/Accordion/Accordion.tsx +2 -1
  39. package/src/components/Accordion/types.ts +4 -0
  40. package/src/components/AllProjectsDropdown/types.ts +2 -0
  41. package/src/components/AppHeader/AppHeader.scss +6 -2
  42. package/src/components/Button/Button.scss +12 -0
  43. package/src/components/Button/Button.tsx +29 -11
  44. package/src/components/Button/types.ts +21 -0
  45. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.scss +83 -30
  46. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.stories.tsx +2 -0
  47. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.tsx +38 -17
  48. package/src/components/Charts/DashboardDonutChart/types.ts +1 -0
  49. package/src/components/Charts/MultiRadialChart/MultiRadialChart.scss +0 -1
  50. package/src/components/Charts/MultiRadialChart/MultiRadialChart.stories.tsx +2 -1
  51. package/src/components/Charts/MultiRadialChart/MultiRadialChart.tsx +18 -4
  52. package/src/components/Charts/MultiRadialChart/types.ts +4 -1
  53. package/src/components/ChooseFile/ChooseFile.stories.tsx +190 -0
  54. package/src/components/ChooseFile/ChooseFile.tsx +46 -0
  55. package/src/components/ChooseFile/types.ts +78 -0
  56. package/src/components/ConditionalDropdown/ConditionalDropdown.stories.tsx +8 -5
  57. package/src/components/ConditionalDropdown/ConditionalDropdown.tsx +133 -135
  58. package/src/components/ConditionalDropdown/types.ts +8 -8
  59. package/src/components/ConnectingBranch/ConnectingBranch.scss +171 -169
  60. package/src/components/ConnectingBranch/ConnectingBranch.tsx +108 -107
  61. package/src/components/DatePicker/DatePicker.scss +310 -0
  62. package/src/components/Excel/ExcelFile/ExcelFile.tsx +4 -4
  63. package/src/components/Excel/ExcelFile/ExcelFileComponents/ActiveCell.tsx +22 -12
  64. package/src/components/Excel/ExcelFile/ExcelFileComponents/ColumnIndicator.tsx +2 -2
  65. package/src/components/Excel/ExcelFile/ExcelFileComponents/DataEditor.tsx +4 -1
  66. package/src/components/Excel/ExcelFile/ExcelFileComponents/RowIndicator.tsx +2 -2
  67. package/src/components/Excel/ExcelFile/ExcelFileComponents/reducerFunctions.ts +77 -10
  68. package/src/components/Icon/iconList.ts +2 -0
  69. package/src/components/LabelEditTextField/LabelEditTextField.scss +4 -0
  70. package/src/components/LabelEditTextField/LabelEditTextField.stories.tsx +8 -3
  71. package/src/components/LabelEditTextField/LabelEditTextField.tsx +42 -18
  72. package/src/components/LabelEditTextField/types.ts +3 -1
  73. package/src/components/MachineInputField/MachineInputField.tsx +2 -2
  74. package/src/components/NLPInput/components/NlpDropDown/NlpDropdown.scss +1 -1
  75. package/src/components/ScriptSwitchButton/ScriptSwitchButton.scss +33 -0
  76. package/src/components/ScriptSwitchButton/ScriptSwitchButton.stories.tsx +48 -0
  77. package/src/components/ScriptSwitchButton/ScriptSwitchButton.tsx +65 -0
  78. package/src/components/ScriptSwitchButton/index.ts +1 -0
  79. package/src/components/Select/Select.tsx +4 -4
  80. package/src/components/StatusCard/StatusCard.scss +2 -1
  81. package/src/components/StatusCard/StatusCard.stories.tsx +59 -1
  82. package/src/components/StatusCard/StatusCard.tsx +10 -2
  83. package/src/components/StatusCard/types.ts +2 -0
  84. package/src/components/TableTree/Components/TableBody.tsx +20 -16
  85. package/src/components/TableTree/Components/TableCell.tsx +47 -31
  86. package/src/components/TableTree/Components/TableRow.tsx +4 -0
  87. package/src/components/TableTree/TableTree.scss +121 -109
  88. package/src/components/TableTree/data.ts +48 -2
  89. package/src/components/TableTree/types.ts +4 -0
  90. package/src/index.ts +97 -0
  91. package/src/validations/regex.stories.tsx +362 -0
  92. package/src/validations/regex.ts +194 -0
@@ -7,6 +7,7 @@ import Icon from '../Icon';
7
7
  import Tooltip from '../Tooltip';
8
8
  import Input from '../Input/Input';
9
9
  import Select from '../Select/Select';
10
+ import useEscapeKey from '../../hooks/keyboardevents/useEscKeyEvent.js';
10
11
 
11
12
  const getErrorMessage = (
12
13
  inputValue: string,
@@ -21,7 +22,7 @@ const getErrorMessage = (
21
22
  } else if (inputValue.length < 3) {
22
23
  return 'Please enter at least 3 characters.';
23
24
  } else if (customErrorCondition) {
24
- return customError ?? '';
25
+ return customError ?? 'Custom error occurred';
25
26
  }
26
27
  return '';
27
28
  };
@@ -35,6 +36,7 @@ const LabelEditTextField: FC<LabelEditTextFieldTypes> = ({
35
36
  customErrorCondition,
36
37
  cancelIcon,
37
38
  variant = 'textField',
39
+ onInputChange,
38
40
  dropdownData = [],
39
41
  // width,
40
42
  height,
@@ -44,17 +46,19 @@ const LabelEditTextField: FC<LabelEditTextFieldTypes> = ({
44
46
  tooltip,
45
47
  }) => {
46
48
  const [isEditing, setIsEditing] = useState(isOpen ?? false);
47
- const [inputValue, setInputValue] = useState(text);
49
+ const [inputValue, setInputValue] = useState(text ?? '');
48
50
  const [dropdownValue, setDropdownValue] = useState(
49
51
  dropdownData[0]?.value ?? ''
50
52
  );
51
53
  const [showError, setShowError] = useState('');
54
+ const [disabled, isDisabled] = useState(true);
52
55
  const [isTextFieldModified, setIsTextFieldModified] = useState(false);
53
56
  const isThrowingError = showError && isEditing ? true : false;
54
57
 
55
58
  const containerRef = useRef<HTMLDivElement | null>(null);
56
- const cancelRef = useRef<HTMLDivElement | null>(null); // New ref for cancel icon
59
+ const cancelRef = useRef<HTMLDivElement | null>(null);
57
60
  const [clickTimeout, setClickTimeout] = useState<number | null>(null);
61
+ const handleEsc = useEscapeKey('Escape');
58
62
  useEffect(() => {
59
63
  return () => {
60
64
  if (clickTimeout) {
@@ -87,14 +91,16 @@ const LabelEditTextField: FC<LabelEditTextFieldTypes> = ({
87
91
  setClickTimeout(timeout);
88
92
  };
89
93
  const handleConfirm = () => {
90
- const errorMessage = getErrorMessage(
91
- inputValue,
92
- text,
93
- customError,
94
- customErrorCondition
95
- );
94
+ let errorMessage = '';
95
+ if (inputValue.length === 0 || inputValue.trim().length === 0) {
96
+ errorMessage = 'Please type any text.';
97
+ } else if (inputValue.length < 3) {
98
+ errorMessage = 'Please enter at least 3 characters.';
99
+ } else if (customErrorCondition) {
100
+ errorMessage = customError ?? 'Invalid input.';
101
+ }
96
102
 
97
- if (errorMessage && isEditing) {
103
+ if (errorMessage) {
98
104
  setShowError(errorMessage);
99
105
  } else {
100
106
  setIsEditing(false);
@@ -104,7 +110,7 @@ const LabelEditTextField: FC<LabelEditTextFieldTypes> = ({
104
110
  };
105
111
 
106
112
  const handleCancel = () => {
107
- setInputValue(text);
113
+ setInputValue(text ?? '');
108
114
  setDropdownValue(dropdownData[0]?.value ?? '');
109
115
  setIsEditing(false);
110
116
  setShowError('');
@@ -112,18 +118,33 @@ const LabelEditTextField: FC<LabelEditTextFieldTypes> = ({
112
118
  };
113
119
 
114
120
  const handleTextFieldChange = (e: React.ChangeEvent<HTMLInputElement>) => {
115
- setInputValue(e.target.value);
116
- setIsTextFieldModified(true);
117
- setShowError('');
121
+ const newValue = e.target.value;
122
+ setInputValue(newValue);
123
+ isDisabled(false);
124
+ if (newValue.length === 0 || newValue.trim().length === 0) {
125
+ setShowError('Please type any text.');
126
+ } else if (newValue.length < 3) {
127
+ setShowError('Please enter at least 3 characters.');
128
+ } else if (customErrorCondition) {
129
+ setShowError(customError ?? 'Invalid input.');
130
+ } else {
131
+ setShowError('');
132
+ }
133
+
134
+ setIsTextFieldModified(newValue !== text);
135
+
136
+ if (onInputChange) {
137
+ onInputChange(newValue);
138
+ }
118
139
  };
119
140
 
120
141
  const handleBlur = (e: MouseEvent) => {
121
142
  if (
122
143
  containerRef.current &&
123
144
  !containerRef.current.contains(e.target as Node) &&
124
- cancelRef.current !== e.target // Exclude clicks on cancel icon
145
+ cancelRef.current !== e.target
125
146
  ) {
126
- const errorMessage = getErrorMessage(inputValue, text, customError);
147
+ const errorMessage = getErrorMessage(inputValue, text ?? '', customError);
127
148
 
128
149
  if (errorMessage && isEditing) {
129
150
  setShowError(errorMessage);
@@ -140,7 +161,7 @@ const LabelEditTextField: FC<LabelEditTextFieldTypes> = ({
140
161
  document.removeEventListener('click', handleBlur);
141
162
  };
142
163
  }, [inputValue]);
143
-
164
+ handleEsc(handleCancel);
144
165
  return (
145
166
  <div className="ff-label-edit-text-field" ref={containerRef}>
146
167
  {isEditing ? (
@@ -195,7 +216,10 @@ const LabelEditTextField: FC<LabelEditTextFieldTypes> = ({
195
216
  height={20}
196
217
  width={20}
197
218
  name={confirmIcon.name}
198
- className="confirm-icon"
219
+ disabled={disabled}
220
+ className={`${
221
+ disabled ? 'disabled-confirm-icon' : 'confirm-icon'
222
+ }`}
199
223
  onClick={handleConfirm}
200
224
  />
201
225
  )}
@@ -16,7 +16,7 @@ export interface LabelEditTextFieldTypes {
16
16
  /** Label text displayed above the input field. */
17
17
  label?: string;
18
18
  /** Initial text displayed in the input field. */
19
- text: string;
19
+ text?: string;
20
20
  /** Text to be highlighted within the displayed text, if provided. */
21
21
  highlightText?: string;
22
22
  /** Custom error message to be displayed, if applicable. */
@@ -40,6 +40,8 @@ export interface LabelEditTextFieldTypes {
40
40
  customErrorCondition?: boolean;
41
41
  placeholder?: string;
42
42
  onClick?: () => void;
43
+ /** Function called when every input character got changed */
44
+ onInputChange?: (newInputValue: string) => void;
43
45
  tooltip?: {
44
46
  tooltipTitle?: string;
45
47
  tooltipPlacement?: string;
@@ -53,7 +53,7 @@ const MachineInputField = ({
53
53
  'ff-machine-input-field-reverse': contentReverse,
54
54
  })}
55
55
  >
56
- {options.map(({ label, type }) => (
56
+ {options.map(({ label, type = 'local' }) => (
57
57
  <div
58
58
  key={type}
59
59
  className={classNames('ff-machine-icon-text-wrapper', {
@@ -61,7 +61,7 @@ const MachineInputField = ({
61
61
  })}
62
62
  >
63
63
  <Icon
64
- name={getIcon[type.toLowerCase()] || 'local'}
64
+ name={getIcon[type?.toLowerCase()] || 'local'}
65
65
  className="ff-machine-icon"
66
66
  />
67
67
  <Typography
@@ -16,7 +16,7 @@
16
16
  .ff-nlp-dropdown-wrapper {
17
17
  .ff-nlp-options-wrapper {
18
18
  max-height: 256px;
19
- z-index: 100;
19
+ z-index: 999;
20
20
  position: absolute;
21
21
  border: 1px solid var(--nlp-border-color);
22
22
  box-sizing: border-box;
@@ -0,0 +1,33 @@
1
+ /* Container Styling */
2
+ .ff-script-switch-container {
3
+ display: flex;
4
+ background-color: var(--base-bg-color);
5
+ height: 24px;
6
+ width: 48px;
7
+ border-radius: 6px;
8
+ border: 1px solid var(--border-color);
9
+ align-items: center;
10
+ justify-content: center;
11
+
12
+ /* Button Styling */
13
+ .ff-script-switch-button {
14
+ padding: 0.1px;
15
+ border: none;
16
+ border-radius: 4px;
17
+ cursor: pointer;
18
+ outline: none;
19
+ transition: all 0.3s ease;
20
+
21
+ /* Button Hover Effect */
22
+ &:hover {
23
+ background-color: var(--hover-color);
24
+ color: var(--brand-color);
25
+ }
26
+ }
27
+
28
+ /* Active Button */
29
+ .ff-script-switch-button.active {
30
+ background-color: var(--ff-line-number-bg);
31
+ color: var(--base-bg-color);
32
+ }
33
+ }
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import React, { useState } from 'react';
3
+ import ScriptSwitchButton from './ScriptSwitchButton';
4
+
5
+ const meta: Meta<typeof ScriptSwitchButton> = {
6
+ title: 'Components/ScriptSwitchButton',
7
+ component: ScriptSwitchButton,
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ selected: {
11
+ control: { type: 'radio' },
12
+ options: ['Automation', 'Manual'],
13
+ },
14
+ },
15
+ };
16
+
17
+ export default meta;
18
+
19
+ type Story = StoryObj<typeof ScriptSwitchButton>;
20
+
21
+ export const Default: Story = {
22
+ args: {
23
+ selected: 'Automation',
24
+ tabList: ['Automation', 'Manual'],
25
+ handleClick: () => {},
26
+ },
27
+ };
28
+
29
+ export const Switch: Story = {
30
+ render: () => {
31
+ const [selected, setSelected] = useState<string>('Automation');
32
+ const handleChange = (selectedSwitch: string) => {
33
+ if (selectedSwitch.includes('Automation')) {
34
+ !selectedSwitch.includes('Add') && setSelected(selectedSwitch);
35
+ } else {
36
+ !selectedSwitch.includes('Add') && setSelected(selectedSwitch);
37
+ }
38
+ };
39
+
40
+ return (
41
+ <ScriptSwitchButton
42
+ selected={selected}
43
+ tabList={['Automation', 'Manual']}
44
+ handleClick={handleChange}
45
+ />
46
+ );
47
+ },
48
+ };
@@ -0,0 +1,65 @@
1
+ import React, { type JSX } from 'react';
2
+ import './ScriptSwitchButton.scss';
3
+ import Icon from '../Icon';
4
+ import Tooltip from '../Tooltip';
5
+
6
+ interface ScriptSwitchButtonProps {
7
+ handleClick: (selected: string) => void;
8
+ selected: string;
9
+ tabList: Array<'Automation' | 'Manual'>;
10
+ }
11
+
12
+ const ScriptSwitchButton: React.FC<ScriptSwitchButtonProps> = ({
13
+ selected = 'text',
14
+ handleClick,
15
+ tabList, // ['Automation' , 'Manual']
16
+ }): JSX.Element => {
17
+ const isAutomation = tabList?.includes('Automation');
18
+ const isManual = tabList?.includes('Manual');
19
+
20
+ return (
21
+ <div className="ff-script-switch-container">
22
+ <Tooltip
23
+ title={isAutomation ? 'Automation' : 'Add Automation'}
24
+ zIndex={1000}
25
+ >
26
+ <div
27
+ className={`ff-script-switch-button ${
28
+ selected === 'Automation' ? 'active' : ''
29
+ }`}
30
+ onClick={() =>
31
+ handleClick(isAutomation ? 'Automation' : 'Add Automation')
32
+ }
33
+ >
34
+ <Icon
35
+ name={isAutomation ? 'automation_testcase' : 'add_testcase'}
36
+ color={
37
+ selected === 'Automation'
38
+ ? 'var(--primary-button-text-color)'
39
+ : 'var(--description-text)'
40
+ }
41
+ />
42
+ </div>
43
+ </Tooltip>
44
+ <Tooltip title={isManual ? 'Manual' : 'Add Manual'} zIndex={1000}>
45
+ <div
46
+ className={`ff-script-switch-button ${
47
+ selected === 'Manual' ? 'active' : ''
48
+ }`}
49
+ onClick={() => handleClick(isManual ? 'Manual' : 'Add Manual')}
50
+ >
51
+ <Icon
52
+ name={isManual ? 'manual_testcase' : 'add_testcase'}
53
+ color={
54
+ selected === 'Manual'
55
+ ? 'var(--primary-button-text-color)'
56
+ : 'var(--description-text)'
57
+ }
58
+ />
59
+ </div>
60
+ </Tooltip>
61
+ </div>
62
+ );
63
+ };
64
+
65
+ export default ScriptSwitchButton;
@@ -0,0 +1 @@
1
+ export { default } from './ScriptSwitchButton';
@@ -228,10 +228,10 @@ const Select: FC<SelectProps> = ({
228
228
  as="span"
229
229
  className={classNames('ff-select-labels', {
230
230
  'ff-select-labels__icon': showIcon,
231
- 'ff-select-labels__active': searchedOption,
231
+ 'ff-select-labels__active': searchedText,
232
232
  })}
233
- fontSize={searchedOption || showDropdownOptions ? 8 : 12}
234
- lineHeight={searchedOption || showDropdownOptions ? '8px' : '12px'}
233
+ fontSize={searchedText || showDropdownOptions ? 10 : 12}
234
+ lineHeight={searchedText || showDropdownOptions ? '10px' : '12px'}
235
235
  required={required}
236
236
  >
237
237
  {label}
@@ -264,7 +264,7 @@ const Select: FC<SelectProps> = ({
264
264
  onSelectBlur={onSelectBlur}
265
265
  onSelectOptionSelector={onSelectOptionSelector}
266
266
  heightFromTop={height}
267
- selectedOption={searchedOption}
267
+ selectedOption={searchedText}
268
268
  showIcon={showIcon}
269
269
  />,
270
270
  document.body
@@ -68,8 +68,9 @@
68
68
  }
69
69
 
70
70
  .ff-content {
71
+ height: 100%;
71
72
  flex: 1;
72
- padding: 8px;
73
+ padding: 0px 8px;
73
74
  display: flex;
74
75
  flex-direction: column;
75
76
  justify-content: center;
@@ -1,6 +1,8 @@
1
+ import React, { useState } from 'react';
1
2
  import { Meta, StoryObj } from '@storybook/react';
2
3
  import Card from './StatusCard';
3
4
  import { CardProps } from './types';
5
+ import StatusCard from './StatusCard';
4
6
 
5
7
  const meta: Meta<typeof Card> = {
6
8
  title: 'Components/Card',
@@ -18,7 +20,7 @@ export const Passed: Story = {
18
20
  status: 'Passed',
19
21
  count: 66,
20
22
  text: 'Scripts were passed all the time.',
21
- style:{width:'200px'},
23
+ style: { width: '200px' },
22
24
  },
23
25
  };
24
26
 
@@ -57,3 +59,59 @@ export const Flaky: Story = {
57
59
  text: 'Scripts were flaky in their behavior.',
58
60
  },
59
61
  };
62
+
63
+ export const AllCards: Story = {
64
+ render: () => {
65
+ const [toggledCard, setToggledCard] = useState<number | null>(null);
66
+
67
+ const data = [
68
+ {
69
+ name: 'Passed',
70
+ count: 6,
71
+ text: 'Scripts were Passed all the time',
72
+ },
73
+ {
74
+ name: 'Failed',
75
+ count: 6,
76
+ text: 'Scripts were Failed all the time',
77
+ },
78
+ {
79
+ name: 'Warning',
80
+ count: 6,
81
+ text: 'Scripts were Warning all the time',
82
+ },
83
+ {
84
+ name: 'Skipped',
85
+ count: 6,
86
+ text: 'Scripts were Skip all the time',
87
+ },
88
+ {
89
+ name: 'Flaky',
90
+ count: 6,
91
+ text: 'Scripts were Flaky all the time',
92
+ },
93
+ ];
94
+
95
+ const onHandleStatus = (status: string, index: number) => {
96
+ setToggledCard(index);
97
+ console.log(`Selected status: ${status}`);
98
+ };
99
+
100
+ return (
101
+ <div style={{ display: 'flex', gap: '8px' }}>
102
+ {data.map((row, index) => (
103
+ <div key={index}>
104
+ <StatusCard
105
+ count={row?.count}
106
+ icon={`${row.name.toLowerCase()}_status_icon`}
107
+ status={row?.name as any}
108
+ text={row.text}
109
+ onSelectedStatus={(status) => onHandleStatus(status, index)}
110
+ resetToggle={toggledCard !== index}
111
+ />
112
+ </div>
113
+ ))}
114
+ </div>
115
+ );
116
+ },
117
+ };
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import './StatusCard.scss';
3
3
  import { CardProps } from './types';
4
4
  import Typography from '../Typography';
@@ -10,6 +10,7 @@ const StatusCard: React.FC<CardProps> = ({
10
10
  count,
11
11
  text,
12
12
  style = { width: '196.4px' },
13
+ resetToggle,
13
14
  onSelectedStatus = (_status) => {},
14
15
  }) => {
15
16
  const [isToggled, setIsToggled] = useState<boolean>(false);
@@ -18,10 +19,17 @@ const StatusCard: React.FC<CardProps> = ({
18
19
  setIsToggled(true);
19
20
  onSelectedStatus(status);
20
21
  };
22
+
23
+ useEffect(() => {
24
+ if (resetToggle) {
25
+ setIsToggled(false);
26
+ }
27
+ }, [resetToggle]);
28
+
21
29
  return (
22
30
  <div
23
31
  className={`ff-card-container ${status.toLowerCase()} ${
24
- isToggled ? 'toggled' : ''
32
+ isToggled ? `toggled` : ''
25
33
  }`}
26
34
  style={style}
27
35
  onClick={() => handleSelectStatus(status)}
@@ -11,6 +11,8 @@ export interface CardProps {
11
11
  style?: React.CSSProperties;
12
12
  /** toggle update */
13
13
  handleToggleStatus?: (_status: boolean) => void;
14
+ /** make Card Select false */
15
+ resetToggle?: boolean;
14
16
  /** call back */
15
17
  onSelectedStatus?: (_status: string) => void;
16
18
  }
@@ -12,23 +12,27 @@ const TableBody = React.memo(
12
12
  onToggleExpand,
13
13
  onCheckBoxChange,
14
14
  }: TableBodyProps) => (
15
- <tbody>
15
+ <tbody className='ff-table-tree-body'>
16
16
  <tr id="ff-table-tree-first-node" />
17
- {flattenedTreeData?.map(({ node, level }) => {
18
- return (
19
- <TableRow
20
- key={node.id}
21
- node={node}
22
- level={level}
23
- columnsData={columnsData}
24
- selected={selected}
25
- select={select}
26
- onRowClick={onRowClick}
27
- onToggleExpand={onToggleExpand}
28
- onCheckBoxChange={onCheckBoxChange}
29
- />
30
- );
31
- })}
17
+ {flattenedTreeData?.map(
18
+ ({ node, level, parentSiblings = [], isLast = false }) => {
19
+ return (
20
+ <TableRow
21
+ key={node.id}
22
+ node={node}
23
+ level={level}
24
+ columnsData={columnsData}
25
+ selected={selected}
26
+ select={select}
27
+ onRowClick={onRowClick}
28
+ onToggleExpand={onToggleExpand}
29
+ onCheckBoxChange={onCheckBoxChange}
30
+ parentSiblings={parentSiblings}
31
+ isLast={isLast}
32
+ />
33
+ );
34
+ }
35
+ )}
32
36
  <tr id="ff-table-tree-last-node" />
33
37
  </tbody>
34
38
  )
@@ -5,10 +5,22 @@ import { TableCellProps } from '../types';
5
5
  import Arrow from '../../../assets/icons/arrows_down_icon.svg?react';
6
6
  import React from 'react';
7
7
 
8
- const renderSpaces = (level: number) =>
9
- Array.from({ length: level }).map((_, i) => (
10
- <span key={i} className="tree-table-space-block" />
11
- ));
8
+ const renderSpaces = (
9
+ level: number,
10
+ parentSiblings: boolean[],
11
+ isLast?: boolean | undefined
12
+ ) => (
13
+ <div className="tree-table-space-container">
14
+ {parentSiblings.reverse().map((line, i) => (
15
+ <span
16
+ key={i}
17
+ className={`tree-table-space-block ${!line ? 'no-lines' : ''} ${
18
+ isLast && i === level-1 ? 'last-node' : ''
19
+ }`}
20
+ />
21
+ ))}
22
+ </div>
23
+ );
12
24
 
13
25
  const TableCell = React.memo(
14
26
  ({
@@ -19,36 +31,40 @@ const TableCell = React.memo(
19
31
  select,
20
32
  onCheckBoxChange,
21
33
  onToggleExpand,
34
+ parentSiblings,
35
+ isLast,
22
36
  }: TableCellProps) => (
23
37
  <td>
24
- {col.isTree && renderSpaces(level + 1)}
25
- {col.isTree && (
26
- <span
27
- className={`tree-table-space-block last-block ${
28
- node.isExpanded ? 'tree-row-expanded' : 'tree-row-collapsed'
29
- } ${node.folder ? '' : 'no-folder'}`}
30
- onClick={() => onToggleExpand(node)}
31
- >
32
- {node.folder && <Arrow />}
33
- </span>
34
- )}
35
- <span className="tree-table-td-content">
36
- {col.isTree && select === 'checkbox' && (
37
- <Checkbox
38
- checked={selected.includes(node.id)}
39
- onChange={() => onCheckBoxChange('checkbox', node)}
40
- />
38
+ {col.isTree && renderSpaces(level + 1, parentSiblings, isLast)}
39
+ <div className="tree-title-container">
40
+ {col.isTree && (
41
+ <span
42
+ className={`tree-table-space-block last-block ${
43
+ node.isExpanded ? 'tree-row-expanded' : 'tree-row-collapsed'
44
+ } ${node.folder ? '' : 'no-folder'}`}
45
+ onClick={() => onToggleExpand(node)}
46
+ >
47
+ {node.folder && <Arrow />}
48
+ </span>
41
49
  )}
42
- {col.isTree && select === 'radio' && (
43
- <RadioButton
44
- name={node.title}
45
- checked={selected.includes(node.id)}
46
- value={node.id}
47
- onChange={() => onCheckBoxChange('radio', node)}
48
- />
49
- )}
50
- {prepareData(node, col)}
51
- </span>
50
+ <span className="tree-table-td-content">
51
+ {col.isTree && select === 'checkbox' && (
52
+ <Checkbox
53
+ checked={selected.includes(node.id)}
54
+ onChange={() => onCheckBoxChange('checkbox', node)}
55
+ />
56
+ )}
57
+ {col.isTree && select === 'radio' && (
58
+ <RadioButton
59
+ name={node.title}
60
+ checked={selected.includes(node.id)}
61
+ value={node.id}
62
+ onChange={() => onCheckBoxChange('radio', node)}
63
+ />
64
+ )}
65
+ {prepareData(node, col)}
66
+ </span>
67
+ </div>
52
68
  {col.actions && (
53
69
  <div className="table-tree-row-action">{col.actions(node)}</div>
54
70
  )}
@@ -12,6 +12,8 @@ const TableRow = React.memo(
12
12
  onRowClick,
13
13
  onToggleExpand,
14
14
  onCheckBoxChange,
15
+ parentSiblings,
16
+ isLast,
15
17
  }: TableRowProps) => (
16
18
  <tr
17
19
  data-level={level}
@@ -28,6 +30,8 @@ const TableRow = React.memo(
28
30
  select={select}
29
31
  onCheckBoxChange={onCheckBoxChange}
30
32
  onToggleExpand={onToggleExpand}
33
+ parentSiblings={parentSiblings}
34
+ isLast={isLast}
31
35
  />
32
36
  ))}
33
37
  </tr>