goobs-frontend 0.9.23 → 0.9.24
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 +1 -1
- package/src/components/Field/Dropdown/MultiSelect/index.tsx +113 -6
- package/src/components/ProjectBoard/forms/AddTask/administrator/companyDropdown/index.tsx +107 -79
- package/src/components/ProjectBoard/forms/AddTask/administrator/companyProvided/index.tsx +103 -76
- package/src/components/ProjectBoard/forms/AddTask/company/customerDropdown/index.tsx +121 -86
- package/src/components/ProjectBoard/forms/AddTask/company/customerProvided/index.tsx +104 -76
- package/src/components/ProjectBoard/forms/AddTask/customer/index.tsx +80 -19
- package/src/components/ProjectBoard/forms/AddTask/noUser/index.tsx +51 -5
package/package.json
CHANGED
|
@@ -10,12 +10,42 @@ import FormControl, { FormControlProps } from '@mui/material/FormControl'
|
|
|
10
10
|
import Select, { SelectChangeEvent } from '@mui/material/Select'
|
|
11
11
|
import Chip from '@mui/material/Chip'
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Interface for dropdown options with attributes, matching SearchableDropdown format
|
|
15
|
+
*/
|
|
16
|
+
export interface DropdownOption {
|
|
17
|
+
value: string
|
|
18
|
+
attribute1?: string
|
|
19
|
+
attribute2?: string
|
|
20
|
+
attribute3?: string
|
|
21
|
+
attribute4?: string
|
|
22
|
+
attribute5?: string
|
|
23
|
+
attribute6?: string
|
|
24
|
+
uniqueKey?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
13
27
|
export interface MultiSelectChipProps
|
|
14
28
|
extends Omit<FormControlProps, 'onChange'> {
|
|
15
29
|
label?: React.ReactNode
|
|
16
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Can be either:
|
|
32
|
+
* - string[] for simple options
|
|
33
|
+
* - DropdownOption[] for complex options with attributes
|
|
34
|
+
*/
|
|
35
|
+
options?: string[] | DropdownOption[]
|
|
36
|
+
/**
|
|
37
|
+
* The values of the selected items
|
|
38
|
+
*/
|
|
17
39
|
defaultSelected?: string[]
|
|
40
|
+
/**
|
|
41
|
+
* Callback when selection changes - returns array of selected values
|
|
42
|
+
*/
|
|
18
43
|
onChange?: (values: string[]) => void
|
|
44
|
+
/**
|
|
45
|
+
* Whether options are complex DropdownOption objects or simple strings
|
|
46
|
+
* Defaults to auto-detect
|
|
47
|
+
*/
|
|
48
|
+
complexOptions?: boolean
|
|
19
49
|
|
|
20
50
|
backgroundcolor?: string
|
|
21
51
|
outlinecolor?: string
|
|
@@ -27,6 +57,10 @@ export interface MultiSelectChipProps
|
|
|
27
57
|
|
|
28
58
|
shrunklabelposition?: 'onNotch' | 'aboveNotch'
|
|
29
59
|
sx?: SxProps
|
|
60
|
+
/**
|
|
61
|
+
* Whether to show option details in the dropdown - only applies to complex options
|
|
62
|
+
*/
|
|
63
|
+
showOptionDetails?: boolean
|
|
30
64
|
}
|
|
31
65
|
|
|
32
66
|
const ITEM_HEIGHT = 40
|
|
@@ -146,6 +180,8 @@ export default function MultipleSelectChip(props: MultiSelectChipProps) {
|
|
|
146
180
|
options = [],
|
|
147
181
|
defaultSelected = [],
|
|
148
182
|
onChange,
|
|
183
|
+
complexOptions: userSpecifiedComplexOptions,
|
|
184
|
+
showOptionDetails = false,
|
|
149
185
|
|
|
150
186
|
backgroundcolor,
|
|
151
187
|
outlinecolor,
|
|
@@ -163,6 +199,48 @@ export default function MultipleSelectChip(props: MultiSelectChipProps) {
|
|
|
163
199
|
const [selectedValues, setSelectedValues] =
|
|
164
200
|
React.useState<string[]>(defaultSelected)
|
|
165
201
|
|
|
202
|
+
// Auto-detect if options are complex (DropdownOption[]) or simple (string[])
|
|
203
|
+
const isComplexOptions = React.useMemo(() => {
|
|
204
|
+
if (userSpecifiedComplexOptions !== undefined) {
|
|
205
|
+
return userSpecifiedComplexOptions
|
|
206
|
+
}
|
|
207
|
+
// Check if options is an array and the first item is an object with a value property
|
|
208
|
+
return (
|
|
209
|
+
options.length > 0 &&
|
|
210
|
+
typeof options[0] !== 'string' &&
|
|
211
|
+
'value' in options[0]
|
|
212
|
+
)
|
|
213
|
+
}, [options, userSpecifiedComplexOptions])
|
|
214
|
+
|
|
215
|
+
// Parse options to get display values and lookup
|
|
216
|
+
const optionsData = React.useMemo(() => {
|
|
217
|
+
if (!isComplexOptions) {
|
|
218
|
+
// Simple string options
|
|
219
|
+
return {
|
|
220
|
+
displayOptions: options as string[],
|
|
221
|
+
optionsMap: new Map<string, string>(),
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Complex options with attributes
|
|
226
|
+
const complexOptions = options as DropdownOption[]
|
|
227
|
+
// Use DropdownOption type explicitly for the map
|
|
228
|
+
const optionsMap = new Map<string, DropdownOption>()
|
|
229
|
+
|
|
230
|
+
// Create a map of value to original option object for quick lookups
|
|
231
|
+
complexOptions.forEach(option => {
|
|
232
|
+
optionsMap.set(option.value, option)
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
// Extract just the values for the dropdown
|
|
236
|
+
const displayOptions = complexOptions.map(option => option.value)
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
displayOptions,
|
|
240
|
+
optionsMap,
|
|
241
|
+
}
|
|
242
|
+
}, [options, isComplexOptions])
|
|
243
|
+
|
|
166
244
|
const hasValue = React.useMemo(
|
|
167
245
|
() => (selectedValues.length > 0).toString(),
|
|
168
246
|
[selectedValues]
|
|
@@ -179,6 +257,35 @@ export default function MultipleSelectChip(props: MultiSelectChipProps) {
|
|
|
179
257
|
}
|
|
180
258
|
}
|
|
181
259
|
|
|
260
|
+
// Render menu item text appropriately based on option type
|
|
261
|
+
const renderMenuItemText = (value: string) => {
|
|
262
|
+
if (!isComplexOptions) {
|
|
263
|
+
return value
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Cast optionsMap to the correct type with DropdownOption
|
|
267
|
+
const optionsMap = optionsData.optionsMap as Map<string, DropdownOption>
|
|
268
|
+
const option = optionsMap.get(value)
|
|
269
|
+
|
|
270
|
+
// If no option found in the map, just return the value
|
|
271
|
+
if (!option) return value
|
|
272
|
+
|
|
273
|
+
// Check if we should show details and if attribute1 exists
|
|
274
|
+
if (!showOptionDetails || typeof option.attribute1 === 'undefined') {
|
|
275
|
+
return value
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// If showing details, include attribute1 (typically description/department)
|
|
279
|
+
return (
|
|
280
|
+
<Box>
|
|
281
|
+
<Box>{value}</Box>
|
|
282
|
+
<Box sx={{ fontSize: '0.8em', color: 'text.secondary' }}>
|
|
283
|
+
{option.attribute1}
|
|
284
|
+
</Box>
|
|
285
|
+
</Box>
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
|
|
182
289
|
return (
|
|
183
290
|
<Box
|
|
184
291
|
sx={{
|
|
@@ -251,13 +358,13 @@ export default function MultipleSelectChip(props: MultiSelectChipProps) {
|
|
|
251
358
|
)}
|
|
252
359
|
MenuProps={MenuProps}
|
|
253
360
|
>
|
|
254
|
-
{
|
|
361
|
+
{optionsData.displayOptions.map(value => (
|
|
255
362
|
<MenuItem
|
|
256
|
-
key={
|
|
257
|
-
value={
|
|
258
|
-
style={getStyles(
|
|
363
|
+
key={value}
|
|
364
|
+
value={value}
|
|
365
|
+
style={getStyles(value, selectedValues, theme)}
|
|
259
366
|
>
|
|
260
|
-
{
|
|
367
|
+
{renderMenuItemText(value)}
|
|
261
368
|
</MenuItem>
|
|
262
369
|
))}
|
|
263
370
|
</Select>
|
|
@@ -55,10 +55,15 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
55
55
|
|
|
56
56
|
// ------------------ FORM STATE ------------------
|
|
57
57
|
const [selectedCompany, setSelectedCompany] = useState('')
|
|
58
|
+
const [selectedCompanyId, setSelectedCompanyId] = useState('')
|
|
58
59
|
const [selectedSeverity, setSelectedSeverity] = useState('')
|
|
60
|
+
const [selectedSeverityId, setSelectedSeverityId] = useState('')
|
|
59
61
|
const [selectedQueue, setSelectedQueue] = useState('')
|
|
62
|
+
const [selectedQueueId, setSelectedQueueId] = useState('')
|
|
60
63
|
const [selectedStatus, setSelectedStatus] = useState('')
|
|
64
|
+
const [selectedStatusId, setSelectedStatusId] = useState('')
|
|
61
65
|
const [selectedSubStatus, setSelectedSubStatus] = useState('')
|
|
66
|
+
const [selectedSubStatusId, setSelectedSubStatusId] = useState('')
|
|
62
67
|
const [selectedTopicIds, setSelectedTopicIds] = useState<string[]>([])
|
|
63
68
|
const [selectedArticleIds, setSelectedArticleIds] = useState<string[]>([])
|
|
64
69
|
const [taskTitle, setTaskTitle] = useState('')
|
|
@@ -75,15 +80,18 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
75
80
|
// ------------------ DROPDOWN OPTIONS ------------------
|
|
76
81
|
const companyOptions = rawCompanies.map(c => ({
|
|
77
82
|
value: c.companyName,
|
|
83
|
+
attribute1: c._id,
|
|
78
84
|
}))
|
|
79
85
|
|
|
80
86
|
const severityOptions = severityLevels.map(sl => ({
|
|
81
87
|
value: String(sl.severityLevel),
|
|
82
88
|
attribute1: sl.description || '',
|
|
89
|
+
attribute2: sl._id,
|
|
83
90
|
}))
|
|
84
91
|
|
|
85
92
|
const statusOptions = statuses.map(s => ({
|
|
86
93
|
value: s.status,
|
|
94
|
+
attribute1: s._id,
|
|
87
95
|
}))
|
|
88
96
|
|
|
89
97
|
// Filter substatuses based on the selected status
|
|
@@ -114,6 +122,7 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
114
122
|
return {
|
|
115
123
|
value: s.subStatus,
|
|
116
124
|
attribute1: associatedStatus,
|
|
125
|
+
attribute2: s._id,
|
|
117
126
|
}
|
|
118
127
|
})
|
|
119
128
|
|
|
@@ -126,6 +135,7 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
126
135
|
{
|
|
127
136
|
value: 'No substatuses available for this status',
|
|
128
137
|
attribute1: '',
|
|
138
|
+
attribute2: '',
|
|
129
139
|
},
|
|
130
140
|
]
|
|
131
141
|
: []
|
|
@@ -134,27 +144,19 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
134
144
|
|
|
135
145
|
const queueOptions = schedulingQueues.map(q => ({
|
|
136
146
|
value: q.queueName,
|
|
147
|
+
attribute1: q._id,
|
|
137
148
|
}))
|
|
138
149
|
|
|
139
150
|
// Effect to reset substatus when status changes
|
|
140
151
|
React.useEffect(() => {
|
|
141
152
|
// Clear the selected substatus when the status changes
|
|
142
153
|
setSelectedSubStatus('')
|
|
154
|
+
setSelectedSubStatusId('')
|
|
143
155
|
}, [selectedStatus])
|
|
144
156
|
|
|
145
157
|
// ------------------ SUBMIT HANDLER ------------------
|
|
146
158
|
const handleSubmit = useCallback(() => {
|
|
147
|
-
|
|
148
|
-
const selectedStatusId =
|
|
149
|
-
statuses.find(s => s.status === selectedStatus)?._id || ''
|
|
150
|
-
const selectedSubStatusId =
|
|
151
|
-
subStatuses.find(s => s.subStatus === selectedSubStatus)?._id || ''
|
|
152
|
-
const selectedQueueId =
|
|
153
|
-
schedulingQueues.find(q => q.queueName === selectedQueue)?._id || ''
|
|
154
|
-
const selectedCompanyId =
|
|
155
|
-
rawCompanies.find(c => c.companyName === selectedCompany)?._id || ''
|
|
156
|
-
|
|
157
|
-
console.log('Submitting task with mapped IDs:', {
|
|
159
|
+
console.log('Submitting task with stored IDs:', {
|
|
158
160
|
statusValue: selectedStatus,
|
|
159
161
|
statusId: selectedStatusId,
|
|
160
162
|
subStatusValue: selectedSubStatus,
|
|
@@ -163,14 +165,35 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
163
165
|
queueId: selectedQueueId,
|
|
164
166
|
companyValue: selectedCompany,
|
|
165
167
|
companyId: selectedCompanyId,
|
|
168
|
+
severityValue: selectedSeverity,
|
|
169
|
+
severityId: selectedSeverityId,
|
|
166
170
|
})
|
|
167
171
|
|
|
172
|
+
// Validate required fields before submission
|
|
173
|
+
if (!selectedSeverityId) {
|
|
174
|
+
console.error('Error: Severity Level is required')
|
|
175
|
+
alert('Please select a Severity Level')
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!selectedStatusId) {
|
|
180
|
+
console.error('Error: Status is required')
|
|
181
|
+
alert('Please select a Status')
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (!selectedSubStatusId) {
|
|
186
|
+
console.error('Error: Substatus is required')
|
|
187
|
+
alert('Please select a Substatus')
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
168
191
|
const newTaskData: Omit<Task, '_id'> = {
|
|
169
192
|
title: taskTitle,
|
|
170
193
|
description: taskDescription,
|
|
171
194
|
topicIds: selectedTopicIds,
|
|
172
195
|
articleIds: selectedArticleIds,
|
|
173
|
-
severityId:
|
|
196
|
+
severityId: selectedSeverityId,
|
|
174
197
|
schedulingQueueId: selectedQueueId,
|
|
175
198
|
statusId: selectedStatusId,
|
|
176
199
|
substatusId: selectedSubStatusId,
|
|
@@ -200,17 +223,18 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
200
223
|
taskDescription,
|
|
201
224
|
selectedTopicIds,
|
|
202
225
|
selectedArticleIds,
|
|
203
|
-
|
|
204
|
-
|
|
226
|
+
selectedSeverityId,
|
|
227
|
+
selectedQueueId,
|
|
228
|
+
selectedStatusId,
|
|
229
|
+
selectedSubStatusId,
|
|
230
|
+
selectedCompanyId,
|
|
205
231
|
selectedStatus,
|
|
206
232
|
selectedSubStatus,
|
|
233
|
+
selectedQueue,
|
|
207
234
|
selectedCompany,
|
|
235
|
+
selectedSeverity,
|
|
208
236
|
createdUserId,
|
|
209
237
|
onAdd,
|
|
210
|
-
statuses,
|
|
211
|
-
subStatuses,
|
|
212
|
-
schedulingQueues,
|
|
213
|
-
rawCompanies,
|
|
214
238
|
])
|
|
215
239
|
|
|
216
240
|
// ------------------ RENDER ------------------
|
|
@@ -275,6 +299,7 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
275
299
|
}
|
|
276
300
|
onChange={option => {
|
|
277
301
|
setSelectedCompany(option?.value || '')
|
|
302
|
+
setSelectedCompanyId(option?.attribute1 || '')
|
|
278
303
|
}}
|
|
279
304
|
placeholder="Select a company"
|
|
280
305
|
/>
|
|
@@ -301,11 +326,14 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
301
326
|
options={severityOptions}
|
|
302
327
|
defaultValue={
|
|
303
328
|
severityOptions.find(
|
|
304
|
-
opt => opt.
|
|
329
|
+
opt => opt.attribute2 === selectedSeverityId
|
|
305
330
|
)?.value
|
|
306
331
|
}
|
|
307
332
|
onChange={option => {
|
|
308
|
-
|
|
333
|
+
// Store the severity level as display value and the ID properly
|
|
334
|
+
setSelectedSeverity(option?.value || '')
|
|
335
|
+
setSelectedSeverityId(option?.attribute2 || '')
|
|
336
|
+
console.log('Selected severity ID:', option?.attribute2)
|
|
309
337
|
}}
|
|
310
338
|
placeholder="Select severity level"
|
|
311
339
|
/>
|
|
@@ -313,17 +341,19 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
313
341
|
label="Status"
|
|
314
342
|
options={statusOptions}
|
|
315
343
|
defaultValue={
|
|
316
|
-
statusOptions.find(opt => opt.
|
|
344
|
+
statusOptions.find(opt => opt.attribute1 === selectedStatusId)
|
|
345
|
+
?.value
|
|
317
346
|
}
|
|
318
347
|
onChange={option => {
|
|
319
348
|
const newStatus = option?.value || ''
|
|
320
349
|
console.log('Status selected:', newStatus)
|
|
321
350
|
|
|
322
|
-
// Find the status ID for the selected status
|
|
323
|
-
const statusObj = statuses.find(s => s.status === newStatus)
|
|
324
|
-
console.log('Selected status object:', statusObj)
|
|
325
|
-
|
|
326
351
|
setSelectedStatus(newStatus)
|
|
352
|
+
setSelectedStatusId(option?.attribute1 || '')
|
|
353
|
+
console.log(
|
|
354
|
+
'Selected status ID from attribute1:',
|
|
355
|
+
option?.attribute1
|
|
356
|
+
)
|
|
327
357
|
}}
|
|
328
358
|
placeholder="Select status"
|
|
329
359
|
/>
|
|
@@ -342,10 +372,13 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
342
372
|
label="Associated Product (Queue)"
|
|
343
373
|
options={queueOptions}
|
|
344
374
|
defaultValue={
|
|
345
|
-
queueOptions.find(opt => opt.
|
|
375
|
+
queueOptions.find(opt => opt.attribute1 === selectedQueueId)
|
|
376
|
+
?.value
|
|
346
377
|
}
|
|
347
378
|
onChange={option => {
|
|
348
379
|
setSelectedQueue(option?.value || '')
|
|
380
|
+
setSelectedQueueId(option?.attribute1 || '')
|
|
381
|
+
console.log('Selected queue ID:', option?.attribute1)
|
|
349
382
|
}}
|
|
350
383
|
placeholder="Select product queue"
|
|
351
384
|
/>
|
|
@@ -354,11 +387,13 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
354
387
|
options={finalSubStatusOptions}
|
|
355
388
|
defaultValue={
|
|
356
389
|
finalSubStatusOptions.find(
|
|
357
|
-
opt => opt.
|
|
390
|
+
opt => opt.attribute2 === selectedSubStatusId
|
|
358
391
|
)?.value
|
|
359
392
|
}
|
|
360
393
|
onChange={option => {
|
|
361
394
|
setSelectedSubStatus(option?.value || '')
|
|
395
|
+
setSelectedSubStatusId(option?.attribute2 || '')
|
|
396
|
+
console.log('Selected substatus ID:', option?.attribute2)
|
|
362
397
|
}}
|
|
363
398
|
placeholder={
|
|
364
399
|
selectedStatus
|
|
@@ -375,87 +410,80 @@ const AdministratorAddTaskCompanyDropdown: React.FC<
|
|
|
375
410
|
{React.useMemo(() => {
|
|
376
411
|
console.log('Topics being mapped for dropdown:', topics)
|
|
377
412
|
|
|
378
|
-
// Create
|
|
379
|
-
const
|
|
380
|
-
|
|
413
|
+
// Create complex options for topics with _id as attribute1
|
|
414
|
+
const topicOptions = topics.map(t => ({
|
|
415
|
+
value: t.topic || `Topic ${t._id}`,
|
|
416
|
+
attribute1: t._id, // Store ID in attribute1
|
|
417
|
+
}))
|
|
381
418
|
|
|
382
|
-
|
|
383
|
-
const displayName = t.topic || `Topic ${t._id}`
|
|
384
|
-
topicNameToId[displayName] = t._id
|
|
385
|
-
topicIdToName[t._id] = displayName
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
console.log('Topic mappings created:', {
|
|
389
|
-
topicNameToId,
|
|
390
|
-
topicIdToName,
|
|
391
|
-
})
|
|
392
|
-
|
|
393
|
-
// Create user-friendly display options for topics
|
|
394
|
-
const topicOptions = topics.map(t => t.topic || `Topic ${t._id}`)
|
|
419
|
+
console.log('Topic options created:', topicOptions)
|
|
395
420
|
|
|
396
421
|
// Translate selected IDs to names for display
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
422
|
+
const selectedTopicValues = selectedTopicIds.map(id => {
|
|
423
|
+
const topic = topics.find(t => t._id === id)
|
|
424
|
+
return topic ? topic.topic || `Topic ${topic._id}` : id
|
|
425
|
+
})
|
|
400
426
|
|
|
401
427
|
return (
|
|
402
428
|
<>
|
|
403
|
-
{/* Topics multi-select – using
|
|
429
|
+
{/* Topics multi-select – using complex options with IDs in attribute1 */}
|
|
404
430
|
<MultiSelect
|
|
405
431
|
label="Topics"
|
|
406
432
|
options={topicOptions}
|
|
407
|
-
defaultSelected={
|
|
408
|
-
onChange={
|
|
409
|
-
console.log('Selected topic
|
|
433
|
+
defaultSelected={selectedTopicValues}
|
|
434
|
+
onChange={selectedValues => {
|
|
435
|
+
console.log('Selected topic values:', selectedValues)
|
|
436
|
+
|
|
437
|
+
// Find the selected topics and get their IDs
|
|
438
|
+
const newSelectedIds = selectedValues.map(value => {
|
|
439
|
+
const matchingTopic = topicOptions.find(
|
|
440
|
+
opt => opt.value === value
|
|
441
|
+
)
|
|
442
|
+
return matchingTopic?.attribute1 || value // Fall back to value if no match
|
|
443
|
+
})
|
|
410
444
|
|
|
411
|
-
// Map the selected names back to IDs
|
|
412
|
-
const newSelectedIds = selectedNames.map(
|
|
413
|
-
name => topicNameToId[name] || name // Fallback to name if mapping not found
|
|
414
|
-
)
|
|
415
445
|
console.log('Mapped to topic IDs:', newSelectedIds)
|
|
416
|
-
|
|
417
446
|
setSelectedTopicIds(newSelectedIds)
|
|
418
447
|
}}
|
|
448
|
+
complexOptions={true} // Explicitly set to use complex options
|
|
419
449
|
/>
|
|
420
450
|
</>
|
|
421
451
|
)
|
|
422
452
|
}, [topics, selectedTopicIds])}
|
|
423
453
|
|
|
424
|
-
{/* Knowledgebase Articles multi-select – using article titles
|
|
454
|
+
{/* Knowledgebase Articles multi-select – using article titles with IDs in attribute1 */}
|
|
425
455
|
{React.useMemo(() => {
|
|
426
|
-
// Create
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const title = a.articleTitle || `Article ${a._id}`
|
|
432
|
-
articleTitleToId[title] = a._id
|
|
433
|
-
articleIdToTitle[a._id] = title
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
// Create user-friendly display options for articles
|
|
437
|
-
const articleOptions = knowledgebaseArticles.map(
|
|
438
|
-
a => a.articleTitle || `Article ${a._id}`
|
|
439
|
-
)
|
|
456
|
+
// Create complex options with article IDs
|
|
457
|
+
const articleOptions = knowledgebaseArticles.map(a => ({
|
|
458
|
+
value: a.articleTitle || `Article ${a._id}`,
|
|
459
|
+
attribute1: a._id, // Store ID in attribute1
|
|
460
|
+
}))
|
|
440
461
|
|
|
441
462
|
// Translate selected IDs to titles for display
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
463
|
+
const selectedArticleValues = selectedArticleIds.map(id => {
|
|
464
|
+
const article = knowledgebaseArticles.find(a => a._id === id)
|
|
465
|
+
return article
|
|
466
|
+
? article.articleTitle || `Article ${article._id}`
|
|
467
|
+
: id
|
|
468
|
+
})
|
|
445
469
|
|
|
446
470
|
return (
|
|
447
471
|
<MultiSelect
|
|
448
472
|
label="Knowledgebase Articles"
|
|
449
473
|
options={articleOptions}
|
|
450
|
-
defaultSelected={
|
|
451
|
-
onChange={
|
|
452
|
-
// Map the selected
|
|
453
|
-
const newSelectedIds =
|
|
454
|
-
|
|
455
|
-
|
|
474
|
+
defaultSelected={selectedArticleValues}
|
|
475
|
+
onChange={selectedValues => {
|
|
476
|
+
// Map the selected values to IDs using attribute1
|
|
477
|
+
const newSelectedIds = selectedValues.map(value => {
|
|
478
|
+
const matchingArticle = articleOptions.find(
|
|
479
|
+
opt => opt.value === value
|
|
480
|
+
)
|
|
481
|
+
return matchingArticle?.attribute1 || value // Fall back to value if no match
|
|
482
|
+
})
|
|
456
483
|
|
|
457
484
|
setSelectedArticleIds(newSelectedIds)
|
|
458
485
|
}}
|
|
486
|
+
complexOptions={true} // Explicitly set to use complex options
|
|
459
487
|
/>
|
|
460
488
|
)
|
|
461
489
|
}, [knowledgebaseArticles, selectedArticleIds])}
|