Skip to content

Commit 05acabc

Browse files
Merge pull request #695 from zendesk/khopek/PDSC-218
feat: Add Serial number to Option in LookupField
2 parents ed71404 + ef71d30 commit 05acabc

File tree

5 files changed

+58
-7
lines changed

5 files changed

+58
-7
lines changed

src/modules/service-catalog/components/service-catalog-item/ItemRequestForm.tsx

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import { CollapsibleDescription } from "./CollapsibleDescription";
99
import type { TicketFieldObject } from "../../../ticket-fields/data-types/TicketFieldObject";
1010
import type { CustomObjectRecord } from "../../../ticket-fields/data-types/CustomObjectRecord";
1111
import { useAssetDataFetchers } from "../../../service-catalog/hooks/useAssetDataFetchers";
12+
import type { ITAMAssetOptionObject } from "../../data-types/ITAMAssetOptionObject";
13+
import { Span } from "@zendeskgarden/react-typography";
14+
import { Option } from "@zendeskgarden/react-dropdowns.next";
1215

1316
const Form = styled.form`
1417
display: flex;
@@ -238,11 +241,17 @@ export function ItemRequestForm({
238241
const buildLookupFieldOptions = async (
239242
records: CustomObjectRecord[],
240243
field: TicketFieldObject
241-
) => {
244+
): Promise<ITAMAssetOptionObject[]> => {
242245
if (!Array.isArray(records) || records.length === 0) return [];
243246

244-
const options = records.map((rec) => {
245-
const base = { name: rec.name, value: rec.id };
247+
const options: ITAMAssetOptionObject[] = records.map((rec) => {
248+
const base = {
249+
name: rec.name,
250+
value: rec.id,
251+
serialNumber: rec.custom_object_fields["standard::serial_number"] as
252+
| string
253+
| undefined,
254+
};
246255

247256
if (rec.custom_object_key === "standard::itam_asset") {
248257
const fields = (rec.custom_object_fields ?? {}) as {
@@ -271,7 +280,31 @@ export function ItemRequestForm({
271280
}
272281
return list;
273282
}
274-
return options.map(({ name, value }) => ({ name, value }));
283+
return options.map(({ name, value, serialNumber }) => ({
284+
name,
285+
value,
286+
serialNumber,
287+
}));
288+
};
289+
290+
const renderLookupFieldOption = (option: ITAMAssetOptionObject) => {
291+
if (option.serialNumber) {
292+
return (
293+
<>
294+
{option.name}
295+
<Option.Meta>
296+
<Span hue="grey">
297+
{t(
298+
"service-catalog.item.serial-number-label",
299+
"SN: {{serialNumber}}",
300+
{ serialNumber: option.serialNumber }
301+
)}
302+
</Span>
303+
</Option.Meta>
304+
</>
305+
);
306+
}
307+
return option.name;
275308
};
276309

277310
return (
@@ -319,6 +352,7 @@ export function ItemRequestForm({
319352
handleChange={handleChange}
320353
visibleFields={requestFields}
321354
buildLookupFieldOptions={buildLookupFieldOptions}
355+
renderLookupFieldOption={renderLookupFieldOption}
322356
/>
323357
);
324358
})}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { TicketFieldOptionObject } from "../../ticket-fields/data-types/TicketFieldObject";
2+
3+
/**
4+
* Extended option type for ITAM (IT Asset Management) assets from Service Catalog.
5+
* These options include additional metadata like serial numbers and asset type IDs.
6+
*/
7+
export interface ITAMAssetOptionObject extends TicketFieldOptionObject {
8+
serialNumber?: string;
9+
item_asset_type_id?: string;
10+
}

src/modules/ticket-fields/RequestFormField.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface RequestFormFieldProps {
2727
value: TicketFieldObject["value"]
2828
) => void;
2929
buildLookupFieldOptions?: LookupFieldProps["buildLookupFieldOptions"];
30+
renderLookupFieldOption?: LookupFieldProps["renderOption"];
3031
}
3132

3233
export const RequestFormField = ({
@@ -43,6 +44,7 @@ export const RequestFormField = ({
4344
handleDueDateChange,
4445
handleChange,
4546
buildLookupFieldOptions,
47+
renderLookupFieldOption,
4648
}: RequestFormFieldProps) => {
4749
switch (field.type) {
4850
case "text":
@@ -144,6 +146,7 @@ export const RequestFormField = ({
144146
visibleFields={visibleFields}
145147
onChange={(value) => handleChange(field, value)}
146148
buildLookupFieldOptions={buildLookupFieldOptions}
149+
renderOption={renderLookupFieldOption}
147150
/>
148151
);
149152
default:

src/modules/ticket-fields/data-types/CustomObjectRecord.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ export interface CustomObjectRecord {
22
id: string;
33
name: string;
44
custom_object_key: string;
5-
custom_object_fields: object;
5+
custom_object_fields: Record<string, string | number | boolean | unknown>;
66
}

src/modules/ticket-fields/fields/LookupField.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ export interface LookupFieldProps {
6464
buildLookupFieldOptions?: (
6565
records: CustomObjectRecord[],
6666
field: TicketFieldObject
67-
) => Promise<{ name: string; value: string }[]>;
67+
) => Promise<TicketFieldOptionObject[]>;
68+
renderOption?: (option: TicketFieldOptionObject) => React.ReactNode;
6869
}
6970

7071
export function LookupField({
@@ -74,6 +75,7 @@ export function LookupField({
7475
onChange,
7576
visibleFields,
7677
buildLookupFieldOptions,
78+
renderOption,
7779
}: LookupFieldProps) {
7880
const {
7981
id: fieldId,
@@ -315,7 +317,9 @@ export function LookupField({
315317
value={option.value}
316318
label={option.name}
317319
data-test-id={`option-${option.name}`}
318-
/>
320+
>
321+
{renderOption ? renderOption(option) : option.name}
322+
</Option>
319323
))}
320324
</Combobox>
321325
{error && <Message validation="error">{error}</Message>}

0 commit comments

Comments
 (0)