goobs-frontend 0.9.17 → 0.9.19
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/package.json +4 -5
- package/src/components/Button/index.tsx +3 -0
- package/src/components/DataGrid/ManageRow/index.tsx +9 -2
- package/src/components/DataGrid/index.tsx +22 -6
- package/src/components/DataGrid/types/index.ts +3 -0
- package/src/components/Field/Dropdown/Regular/index.tsx +21 -1
- package/src/components/Field/Dropdown/Searchable/index.tsx +171 -88
- package/src/components/ProjectBoard/forms/AddTask/administrator/companyDropdown/index.tsx +233 -97
- package/src/components/ProjectBoard/forms/AddTask/administrator/companyProvided/index.tsx +218 -92
- package/src/components/ProjectBoard/forms/AddTask/company/customerDropdown/index.tsx +226 -99
- package/src/components/ProjectBoard/forms/AddTask/company/customerProvided/index.tsx +215 -83
- package/src/components/ProjectBoard/forms/AddTask/customer/index.tsx +44 -17
- package/src/components/ProjectBoard/forms/AddTask/noUser/index.tsx +9 -16
- package/src/components/ProjectBoard/index.tsx +12 -5
- package/src/components/ProjectBoard/types/index.tsx +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goobs-frontend",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A comprehensive React-based libary that extends the functionality of Material-UI",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"@emotion/cache": "^11",
|
|
26
26
|
"@emotion/react": "^11",
|
|
27
27
|
"@emotion/styled": "^11",
|
|
28
|
-
"@mui/icons-material": "^
|
|
29
|
-
"@mui/material": "^
|
|
28
|
+
"@mui/icons-material": "^7",
|
|
29
|
+
"@mui/material": "^7",
|
|
30
30
|
"@storybook/addon-links": "^8",
|
|
31
31
|
"@types/lodash": "^4",
|
|
32
32
|
"formik": "^2",
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"next": "15",
|
|
37
37
|
"otplib": "^12",
|
|
38
38
|
"react-datepicker": "^8",
|
|
39
|
-
"react-native": "^0.78.0",
|
|
40
39
|
"react-qr-code": "^2",
|
|
41
40
|
"slate": "^0.112",
|
|
42
41
|
"slate-dom": "^0.112",
|
|
@@ -65,7 +64,7 @@
|
|
|
65
64
|
"eslint-config-next": "^15",
|
|
66
65
|
"eslint-config-prettier": "^10",
|
|
67
66
|
"eslint-plugin-prettier": "^5",
|
|
68
|
-
"eslint-plugin-storybook": "^0.
|
|
67
|
+
"eslint-plugin-storybook": "^0.12",
|
|
69
68
|
"prettier": "^3",
|
|
70
69
|
"react": "^19",
|
|
71
70
|
"react-dom": "^19",
|
|
@@ -46,6 +46,7 @@ function CustomButton({
|
|
|
46
46
|
iconlocation = 'left',
|
|
47
47
|
fontlocation = 'center',
|
|
48
48
|
disabled,
|
|
49
|
+
style = {},
|
|
49
50
|
...restProps
|
|
50
51
|
}: CustomButtonProps) {
|
|
51
52
|
// Merge MUI's "disabled" with our "disableButton"
|
|
@@ -119,6 +120,7 @@ function CustomButton({
|
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
// Inline styles for the top-level container (Box)
|
|
123
|
+
// Merge the passed style prop with our containerStyle
|
|
122
124
|
const containerStyle: React.CSSProperties = {
|
|
123
125
|
display: 'flex',
|
|
124
126
|
flexDirection: 'column',
|
|
@@ -127,6 +129,7 @@ function CustomButton({
|
|
|
127
129
|
height: height || (isIconOnly ? '36px' : isIconAbove ? 'auto' : '40px'),
|
|
128
130
|
minHeight: isIconOnly ? '36px' : isIconAbove ? minHeight : 'auto',
|
|
129
131
|
minWidth: isIconOnly ? '36px' : 'fit-content',
|
|
132
|
+
...style, // Apply any custom styles passed through the style prop
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
// Style for the inner content box
|
|
@@ -43,8 +43,15 @@ function ManageRow({
|
|
|
43
43
|
handleClose()
|
|
44
44
|
break
|
|
45
45
|
case 'delete':
|
|
46
|
-
onDelete
|
|
47
|
-
|
|
46
|
+
if (onDelete) {
|
|
47
|
+
// Execute the delete operation
|
|
48
|
+
onDelete()
|
|
49
|
+
// Clear the selection by setting it to empty array
|
|
50
|
+
if (selectedRows.length > 0) {
|
|
51
|
+
// This will properly close the ManageRow component
|
|
52
|
+
handleClose()
|
|
53
|
+
}
|
|
54
|
+
}
|
|
48
55
|
break
|
|
49
56
|
case 'export':
|
|
50
57
|
if (onExport) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import React, { useState } from 'react'
|
|
3
|
+
import React, { useState, useMemo } from 'react'
|
|
4
4
|
import { Box, Alert } from '@mui/material'
|
|
5
5
|
import CustomToolbar from '../Toolbar'
|
|
6
6
|
import Table from './Table'
|
|
@@ -24,7 +24,16 @@ function DataGrid({
|
|
|
24
24
|
onManage,
|
|
25
25
|
onShow,
|
|
26
26
|
onSelectionChange,
|
|
27
|
+
showIdColumns = false,
|
|
27
28
|
}: DatagridProps) {
|
|
29
|
+
// Filter columns to hide ID columns based on showIdColumns prop
|
|
30
|
+
const filteredColumns = useMemo(() => {
|
|
31
|
+
if (showIdColumns) {
|
|
32
|
+
return columns
|
|
33
|
+
}
|
|
34
|
+
return columns.filter(col => col.field !== 'id' && col.field !== '_id')
|
|
35
|
+
}, [columns, showIdColumns])
|
|
36
|
+
|
|
28
37
|
// Local state
|
|
29
38
|
const [rows, setRows] = useState<RowData[]>(providedRows || [])
|
|
30
39
|
const [selectedRows, setSelectedRows] = useState<string[]>([])
|
|
@@ -32,7 +41,7 @@ function DataGrid({
|
|
|
32
41
|
const [pageSize, setPageSize] = useState(10)
|
|
33
42
|
|
|
34
43
|
// Initialize columns/rows if needed
|
|
35
|
-
useInitializeGrid({ columns, providedRows, setRows })
|
|
44
|
+
useInitializeGrid({ columns: filteredColumns, providedRows, setRows })
|
|
36
45
|
|
|
37
46
|
// 1) When row selection changes
|
|
38
47
|
const handleSelectionChange = (newSelectedIds: string[]) => {
|
|
@@ -60,7 +69,7 @@ function DataGrid({
|
|
|
60
69
|
|
|
61
70
|
// 2) Search logic
|
|
62
71
|
const { filteredRows, updatedSearchbarProps } = useSearchbar({
|
|
63
|
-
columns,
|
|
72
|
+
columns: filteredColumns,
|
|
64
73
|
rows,
|
|
65
74
|
searchbarProps,
|
|
66
75
|
})
|
|
@@ -116,7 +125,14 @@ function DataGrid({
|
|
|
116
125
|
onDuplicate: onDuplicate
|
|
117
126
|
? () => onDuplicate(selectedRows)
|
|
118
127
|
: undefined,
|
|
119
|
-
onDelete: onDelete
|
|
128
|
+
onDelete: onDelete
|
|
129
|
+
? () => {
|
|
130
|
+
// Call the onDelete handler and clear selection after it completes
|
|
131
|
+
onDelete(selectedRows)
|
|
132
|
+
// Clear the selection after delete operation
|
|
133
|
+
handleSelectionChange([])
|
|
134
|
+
}
|
|
135
|
+
: undefined,
|
|
120
136
|
onManage: handleManage,
|
|
121
137
|
onShow: onShow,
|
|
122
138
|
handleClose: handleManageRowClose,
|
|
@@ -138,7 +154,7 @@ function DataGrid({
|
|
|
138
154
|
>
|
|
139
155
|
{/* Table component */}
|
|
140
156
|
<Table
|
|
141
|
-
columns={
|
|
157
|
+
columns={filteredColumns}
|
|
142
158
|
rows={visibleRows}
|
|
143
159
|
selectedRowIds={selectedRows}
|
|
144
160
|
onRowClick={handleRowClick}
|
|
@@ -154,7 +170,7 @@ function DataGrid({
|
|
|
154
170
|
rowCount={filteredRows.length}
|
|
155
171
|
onPageChange={setPage}
|
|
156
172
|
onPageSizeChange={setPageSize}
|
|
157
|
-
columns={
|
|
173
|
+
columns={filteredColumns}
|
|
158
174
|
/>
|
|
159
175
|
</Box>
|
|
160
176
|
</Box>
|
|
@@ -48,6 +48,9 @@ export interface DatagridProps {
|
|
|
48
48
|
searchbarProps?: SearchbarProps
|
|
49
49
|
error?: Error | null
|
|
50
50
|
|
|
51
|
+
// Controls whether ID columns (id/_id) are visible
|
|
52
|
+
showIdColumns?: boolean
|
|
53
|
+
|
|
51
54
|
// Single or multi selection callbacks:
|
|
52
55
|
onManage?: () => void
|
|
53
56
|
onShow?: () => void
|
|
@@ -53,6 +53,8 @@ export interface DropdownProps extends Omit<FormControlProps, 'onChange'> {
|
|
|
53
53
|
value?: string
|
|
54
54
|
width?: string
|
|
55
55
|
disabled?: boolean
|
|
56
|
+
// Controls whether ID columns (containing 'id' or '_id') are visible by default
|
|
57
|
+
showIdColumns?: boolean
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
const StyledFormControl = styled(FormControl)<{ width?: string }>(
|
|
@@ -173,10 +175,28 @@ const Dropdown: React.FC<DropdownProps> = ({
|
|
|
173
175
|
value: externalValue,
|
|
174
176
|
width,
|
|
175
177
|
disabled = false,
|
|
178
|
+
showIdColumns = false, // Default to hiding ID columns for security
|
|
176
179
|
}) => {
|
|
177
180
|
const [selectedValue, setSelectedValue] = useState<string>('')
|
|
178
181
|
const [focused, setFocused] = useState(false)
|
|
179
182
|
|
|
183
|
+
// Filter out options with id values if showIdColumns is false
|
|
184
|
+
const filteredOptions = React.useMemo(() => {
|
|
185
|
+
if (showIdColumns) {
|
|
186
|
+
return options
|
|
187
|
+
}
|
|
188
|
+
// Hide options where the value is exactly 'id' or '_id', or looks like a database ID
|
|
189
|
+
return options.filter(opt => {
|
|
190
|
+
const value = opt.value.toLowerCase()
|
|
191
|
+
// Check if value is an ID field or looks like an ObjectId
|
|
192
|
+
return !(
|
|
193
|
+
value === 'id' ||
|
|
194
|
+
value === '_id' ||
|
|
195
|
+
/^[0-9a-f]{24}$/.test(value) // MongoDB ObjectId format
|
|
196
|
+
)
|
|
197
|
+
})
|
|
198
|
+
}, [options, showIdColumns])
|
|
199
|
+
|
|
180
200
|
useEffect(() => {
|
|
181
201
|
if (externalValue !== undefined) {
|
|
182
202
|
setSelectedValue(externalValue)
|
|
@@ -351,7 +371,7 @@ const Dropdown: React.FC<DropdownProps> = ({
|
|
|
351
371
|
fontcolor={fontcolor}
|
|
352
372
|
disabled={disabled}
|
|
353
373
|
>
|
|
354
|
-
{
|
|
374
|
+
{filteredOptions.map(renderMenuItem)}
|
|
355
375
|
</StyledSelect>
|
|
356
376
|
{helperText && (
|
|
357
377
|
<FormHelperText error={error}>{helperText}</FormHelperText>
|
|
@@ -66,6 +66,8 @@ export interface SearchableDropdownProps {
|
|
|
66
66
|
searchHistory?: HistoryItem[] | string[]
|
|
67
67
|
onSearch?: (searchTerm: string, timestamp?: Date) => void
|
|
68
68
|
maxHistoryItems?: number
|
|
69
|
+
// Controls whether ID columns (containing 'id' or '_id') are visible by default
|
|
70
|
+
showIdColumns?: boolean
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
const StyledFormControl = styled(FormControl)<{ width?: string }>(
|
|
@@ -252,6 +254,28 @@ const StyledFormHelperText = styled(FormHelperText)({
|
|
|
252
254
|
marginLeft: '14px',
|
|
253
255
|
})
|
|
254
256
|
|
|
257
|
+
// Create a utility function to check if a field is an ID field
|
|
258
|
+
const isIdField = (fieldName: string): boolean => {
|
|
259
|
+
if (!fieldName) return false
|
|
260
|
+
|
|
261
|
+
// Check if it's a common ID field name
|
|
262
|
+
if (fieldName.toLowerCase() === 'id' || fieldName.toLowerCase() === '_id') {
|
|
263
|
+
return true
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Check if it contains "id" or "_id" as a standalone word or suffix
|
|
267
|
+
if (/(\b|_)id$/i.test(fieldName)) {
|
|
268
|
+
return true
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Check if it looks like a MongoDB ObjectId
|
|
272
|
+
if (/^[0-9a-f]{24}$/.test(fieldName)) {
|
|
273
|
+
return true
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return false
|
|
277
|
+
}
|
|
278
|
+
|
|
255
279
|
const SearchableDropdown: React.FC<SearchableDropdownProps> = ({
|
|
256
280
|
label,
|
|
257
281
|
options,
|
|
@@ -277,6 +301,7 @@ const SearchableDropdown: React.FC<SearchableDropdownProps> = ({
|
|
|
277
301
|
searchHistory = [], // Default to empty array
|
|
278
302
|
onSearch,
|
|
279
303
|
maxHistoryItems = 5, // Default to showing 5 history items
|
|
304
|
+
showIdColumns = false, // Default to hiding ID columns for security
|
|
280
305
|
}) => {
|
|
281
306
|
const [value, setValue] = useState<DropdownOption | string | null>(null)
|
|
282
307
|
const [inputValue, setInputValue] = useState('')
|
|
@@ -561,6 +586,23 @@ const SearchableDropdown: React.FC<SearchableDropdownProps> = ({
|
|
|
561
586
|
return localHistory
|
|
562
587
|
}, [searchHistory, localHistory])
|
|
563
588
|
|
|
589
|
+
// Filter out options with id values if showIdColumns is false
|
|
590
|
+
const filteredBaseOptions = React.useMemo(() => {
|
|
591
|
+
if (showIdColumns) {
|
|
592
|
+
return options
|
|
593
|
+
}
|
|
594
|
+
// Hide options where the value is exactly 'id' or '_id', or looks like a database ID
|
|
595
|
+
return options.filter(opt => {
|
|
596
|
+
const value = opt.value.toLowerCase()
|
|
597
|
+
// Check if value is an ID field or looks like an ObjectId (MongoDB ID format)
|
|
598
|
+
return !(
|
|
599
|
+
value === 'id' ||
|
|
600
|
+
value === '_id' ||
|
|
601
|
+
/^[0-9a-f]{24}$/.test(value)
|
|
602
|
+
)
|
|
603
|
+
})
|
|
604
|
+
}, [options, showIdColumns])
|
|
605
|
+
|
|
564
606
|
// Create a combined options array based on active tab and input value
|
|
565
607
|
const getFilteredOptions = React.useCallback(() => {
|
|
566
608
|
const currentInputVal = inputValue.trim()
|
|
@@ -581,7 +623,7 @@ const SearchableDropdown: React.FC<SearchableDropdownProps> = ({
|
|
|
581
623
|
// Map history items to dropdown options
|
|
582
624
|
return combinedHistory.map(item => {
|
|
583
625
|
// Check if this history item matches any of the original options
|
|
584
|
-
const matchingOption =
|
|
626
|
+
const matchingOption = filteredBaseOptions.find(
|
|
585
627
|
opt =>
|
|
586
628
|
opt.value.toLowerCase() === item.text.toLowerCase() ||
|
|
587
629
|
(
|
|
@@ -617,11 +659,11 @@ const SearchableDropdown: React.FC<SearchableDropdownProps> = ({
|
|
|
617
659
|
// ALL OPTIONS TAB (activeTab === 0)
|
|
618
660
|
// If input is empty, return all options
|
|
619
661
|
if (!currentInputVal) {
|
|
620
|
-
return
|
|
662
|
+
return filteredBaseOptions
|
|
621
663
|
}
|
|
622
664
|
|
|
623
665
|
// Filter options based on current input
|
|
624
|
-
const filteredOpts =
|
|
666
|
+
const filteredOpts = filteredBaseOptions.filter(opt =>
|
|
625
667
|
opt.value.toLowerCase().includes(currentInputVal.toLowerCase())
|
|
626
668
|
)
|
|
627
669
|
|
|
@@ -654,7 +696,7 @@ const SearchableDropdown: React.FC<SearchableDropdownProps> = ({
|
|
|
654
696
|
}
|
|
655
697
|
|
|
656
698
|
return filteredOpts
|
|
657
|
-
}, [inputValue, combinedHistory,
|
|
699
|
+
}, [inputValue, combinedHistory, filteredBaseOptions, activeTab, variant])
|
|
658
700
|
|
|
659
701
|
// Create the footer component for the dropdown with tabs
|
|
660
702
|
const ListboxFooter = React.forwardRef<HTMLDivElement>((_, ref) => (
|
|
@@ -962,124 +1004,165 @@ const SearchableDropdown: React.FC<SearchableDropdownProps> = ({
|
|
|
962
1004
|
/>
|
|
963
1005
|
)}
|
|
964
1006
|
|
|
965
|
-
{/* For simple variant - show attribute1 and attribute2 on one line */}
|
|
1007
|
+
{/* For simple variant - show attribute1 and attribute2 on one line (excluding ID fields) */}
|
|
966
1008
|
{variant === 'simple' &&
|
|
967
1009
|
!isHistoryItem &&
|
|
968
1010
|
!isCurrentInput &&
|
|
969
1011
|
!isNoHistoryPlaceholder &&
|
|
970
|
-
(
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1012
|
+
(() => {
|
|
1013
|
+
// Filter out ID attributes if showIdColumns is false
|
|
1014
|
+
const filteredAttributes = [
|
|
1015
|
+
option.attribute1,
|
|
1016
|
+
option.attribute2,
|
|
1017
|
+
].filter(attr => showIdColumns || (attr && !isIdField(attr)))
|
|
1018
|
+
|
|
1019
|
+
return filteredAttributes.length > 0 ? (
|
|
1020
|
+
<Typography
|
|
1021
|
+
fontvariant="merriparagraph"
|
|
1022
|
+
text={filteredAttributes.join(' | ')}
|
|
1023
|
+
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1024
|
+
sx={{
|
|
1025
|
+
fontSize: '12px',
|
|
1026
|
+
lineHeight: '16px',
|
|
1027
|
+
width: '100%',
|
|
1028
|
+
textAlign: 'left',
|
|
1029
|
+
}}
|
|
1030
|
+
/>
|
|
1031
|
+
) : null
|
|
1032
|
+
})()}
|
|
985
1033
|
|
|
986
|
-
{/* For complex variant - show attributes on separate lines */}
|
|
1034
|
+
{/* For complex variant - show attributes on separate lines (excluding ID fields) */}
|
|
987
1035
|
{variant === 'complex' &&
|
|
988
1036
|
!isHistoryItem &&
|
|
989
1037
|
!isCurrentInput &&
|
|
990
1038
|
!isNoHistoryPlaceholder && (
|
|
991
1039
|
<>
|
|
992
1040
|
{/* First line of attributes */}
|
|
993
|
-
{(
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1041
|
+
{(() => {
|
|
1042
|
+
const filteredAttributes = [
|
|
1043
|
+
option.attribute1,
|
|
1044
|
+
option.attribute2,
|
|
1045
|
+
].filter(
|
|
1046
|
+
attr => showIdColumns || (attr && !isIdField(attr))
|
|
1047
|
+
)
|
|
1048
|
+
|
|
1049
|
+
return filteredAttributes.length > 0 ? (
|
|
1050
|
+
<Typography
|
|
1051
|
+
fontvariant="merriparagraph"
|
|
1052
|
+
text={filteredAttributes.join(' | ')}
|
|
1053
|
+
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1054
|
+
sx={{
|
|
1055
|
+
fontSize: '12px',
|
|
1056
|
+
lineHeight: '16px',
|
|
1057
|
+
width: '100%',
|
|
1058
|
+
textAlign: 'left',
|
|
1059
|
+
}}
|
|
1060
|
+
/>
|
|
1061
|
+
) : null
|
|
1062
|
+
})()}
|
|
1008
1063
|
|
|
1009
1064
|
{/* Second line of attributes */}
|
|
1010
|
-
{(
|
|
1065
|
+
{(() => {
|
|
1066
|
+
const filteredAttributes = [
|
|
1067
|
+
option.attribute3,
|
|
1068
|
+
option.attribute4,
|
|
1069
|
+
].filter(
|
|
1070
|
+
attr => showIdColumns || (attr && !isIdField(attr))
|
|
1071
|
+
)
|
|
1072
|
+
|
|
1073
|
+
return filteredAttributes.length > 0 ? (
|
|
1074
|
+
<Typography
|
|
1075
|
+
fontvariant="merriparagraph"
|
|
1076
|
+
text={filteredAttributes.join(' | ')}
|
|
1077
|
+
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1078
|
+
sx={{
|
|
1079
|
+
fontSize: '12px',
|
|
1080
|
+
lineHeight: '16px',
|
|
1081
|
+
width: '100%',
|
|
1082
|
+
textAlign: 'left',
|
|
1083
|
+
}}
|
|
1084
|
+
/>
|
|
1085
|
+
) : null
|
|
1086
|
+
})()}
|
|
1087
|
+
|
|
1088
|
+
{/* Third line of attributes */}
|
|
1089
|
+
{(() => {
|
|
1090
|
+
const filteredAttributes = [
|
|
1091
|
+
option.attribute5,
|
|
1092
|
+
option.attribute6,
|
|
1093
|
+
].filter(
|
|
1094
|
+
attr => showIdColumns || (attr && !isIdField(attr))
|
|
1095
|
+
)
|
|
1096
|
+
|
|
1097
|
+
return filteredAttributes.length > 0 ? (
|
|
1098
|
+
<Typography
|
|
1099
|
+
fontvariant="merriparagraph"
|
|
1100
|
+
text={filteredAttributes.join(' | ')}
|
|
1101
|
+
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1102
|
+
sx={{
|
|
1103
|
+
fontSize: '12px',
|
|
1104
|
+
lineHeight: '16px',
|
|
1105
|
+
width: '100%',
|
|
1106
|
+
textAlign: 'left',
|
|
1107
|
+
}}
|
|
1108
|
+
/>
|
|
1109
|
+
) : null
|
|
1110
|
+
})()}
|
|
1111
|
+
</>
|
|
1112
|
+
)}
|
|
1113
|
+
|
|
1114
|
+
{/* For history items, show additional attributes from original options (excluding ID fields) */}
|
|
1115
|
+
{isHistoryItem && variant === 'complex' && (
|
|
1116
|
+
<>
|
|
1117
|
+
{/* Show attribute3/4 as first additional line for history */}
|
|
1118
|
+
{(() => {
|
|
1119
|
+
const filteredAttributes = [
|
|
1120
|
+
option.attribute3,
|
|
1121
|
+
option.attribute4,
|
|
1122
|
+
].filter(
|
|
1123
|
+
attr => showIdColumns || (attr && !isIdField(attr))
|
|
1124
|
+
)
|
|
1125
|
+
|
|
1126
|
+
return filteredAttributes.length > 0 ? (
|
|
1011
1127
|
<Typography
|
|
1012
1128
|
fontvariant="merriparagraph"
|
|
1013
|
-
text={
|
|
1014
|
-
.filter(Boolean)
|
|
1015
|
-
.join(' | ')}
|
|
1129
|
+
text={filteredAttributes.join(' | ')}
|
|
1016
1130
|
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1017
1131
|
sx={{
|
|
1018
1132
|
fontSize: '12px',
|
|
1019
1133
|
lineHeight: '16px',
|
|
1020
1134
|
width: '100%',
|
|
1021
1135
|
textAlign: 'left',
|
|
1136
|
+
fontStyle: 'italic',
|
|
1022
1137
|
}}
|
|
1023
1138
|
/>
|
|
1024
|
-
)
|
|
1139
|
+
) : null
|
|
1140
|
+
})()}
|
|
1025
1141
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1142
|
+
{/* Show attribute5/6 as second additional line for history */}
|
|
1143
|
+
{(() => {
|
|
1144
|
+
const filteredAttributes = [
|
|
1145
|
+
option.attribute5,
|
|
1146
|
+
option.attribute6,
|
|
1147
|
+
].filter(
|
|
1148
|
+
attr => showIdColumns || (attr && !isIdField(attr))
|
|
1149
|
+
)
|
|
1150
|
+
|
|
1151
|
+
return filteredAttributes.length > 0 ? (
|
|
1028
1152
|
<Typography
|
|
1029
1153
|
fontvariant="merriparagraph"
|
|
1030
|
-
text={
|
|
1031
|
-
.filter(Boolean)
|
|
1032
|
-
.join(' | ')}
|
|
1154
|
+
text={filteredAttributes.join(' | ')}
|
|
1033
1155
|
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1034
1156
|
sx={{
|
|
1035
1157
|
fontSize: '12px',
|
|
1036
1158
|
lineHeight: '16px',
|
|
1037
1159
|
width: '100%',
|
|
1038
1160
|
textAlign: 'left',
|
|
1161
|
+
fontStyle: 'italic',
|
|
1039
1162
|
}}
|
|
1040
1163
|
/>
|
|
1041
|
-
)
|
|
1042
|
-
|
|
1043
|
-
)}
|
|
1044
|
-
|
|
1045
|
-
{/* For history items, show additional attributes from original options */}
|
|
1046
|
-
{isHistoryItem && variant === 'complex' && (
|
|
1047
|
-
<>
|
|
1048
|
-
{/* Show attribute3/4 as first additional line for history */}
|
|
1049
|
-
{(option.attribute3 || option.attribute4) && (
|
|
1050
|
-
<Typography
|
|
1051
|
-
fontvariant="merriparagraph"
|
|
1052
|
-
text={[option.attribute3, option.attribute4]
|
|
1053
|
-
.filter(Boolean)
|
|
1054
|
-
.join(' | ')}
|
|
1055
|
-
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1056
|
-
sx={{
|
|
1057
|
-
fontSize: '12px',
|
|
1058
|
-
lineHeight: '16px',
|
|
1059
|
-
width: '100%',
|
|
1060
|
-
textAlign: 'left',
|
|
1061
|
-
fontStyle: 'italic',
|
|
1062
|
-
}}
|
|
1063
|
-
/>
|
|
1064
|
-
)}
|
|
1065
|
-
|
|
1066
|
-
{/* Show attribute5/6 as second additional line for history */}
|
|
1067
|
-
{(option.attribute5 || option.attribute6) && (
|
|
1068
|
-
<Typography
|
|
1069
|
-
fontvariant="merriparagraph"
|
|
1070
|
-
text={[option.attribute5, option.attribute6]
|
|
1071
|
-
.filter(Boolean)
|
|
1072
|
-
.join(' | ')}
|
|
1073
|
-
fontcolor="rgba(0, 0, 0, 0.6)"
|
|
1074
|
-
sx={{
|
|
1075
|
-
fontSize: '12px',
|
|
1076
|
-
lineHeight: '16px',
|
|
1077
|
-
width: '100%',
|
|
1078
|
-
textAlign: 'left',
|
|
1079
|
-
fontStyle: 'italic',
|
|
1080
|
-
}}
|
|
1081
|
-
/>
|
|
1082
|
-
)}
|
|
1164
|
+
) : null
|
|
1165
|
+
})()}
|
|
1083
1166
|
</>
|
|
1084
1167
|
)}
|
|
1085
1168
|
|