Skip to content

Commit e5069d5

Browse files
authored
On edit form, display source when a field value is from template (#5900)
1 parent 7bd264d commit e5069d5

File tree

10 files changed

+190
-30
lines changed

10 files changed

+190
-30
lines changed

frontend/app/src/app/app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import mdiIcons from "@iconify-json/mdi/icons.json";
44
import { QueryClientProvider } from "@tanstack/react-query";
55
import { Provider } from "jotai";
66
import { ErrorBoundary } from "react-error-boundary";
7-
import { RouterProvider } from "react-router/dom";
7+
import { RouterProvider } from "react-router";
88
import { Slide, ToastContainer } from "react-toastify";
99

1010
import { TanStackQueryDevtools } from "@/app/devtools";

frontend/app/src/entities/nodes/api/basicMutation.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

frontend/app/src/entities/nodes/object-item-edit/generateObjectEditFormQuery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const generateObjectEditFormQuery = ({
2020
edges: {
2121
node: {
2222
id: true,
23+
hfid: true,
2324
display_label: true,
2425
...addAttributesToRequest(schema.attributes ?? [], {
2526
withMetadata: true,
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { RESOURCE_GENERIC_KIND } from "@/entities/resource-manager/constants";
2+
import { isPoolSchema } from "@/entities/schema/utils/is-pool-schema";
3+
import { describe, expect, it } from "vitest";
4+
import { generateGenericSchema, generateNodeSchema } from "../../../../tests/fake/schema";
5+
6+
describe("isPoolSchema", () => {
7+
it("should return true for a schema that inherits from resource generic kind", () => {
8+
// GIVEN
9+
const schema = generateNodeSchema({ inherit_from: [RESOURCE_GENERIC_KIND] });
10+
11+
// WHEN
12+
const result = isPoolSchema(schema);
13+
14+
// THEN
15+
expect(result).toBe(true);
16+
});
17+
18+
it("should return true for a schema that inherits from multiple kinds including resource generic kind", () => {
19+
// GIVEN
20+
const schema = generateNodeSchema({ inherit_from: ["SomeOtherKind", RESOURCE_GENERIC_KIND] });
21+
22+
// WHEN
23+
const result = isPoolSchema(schema);
24+
25+
// THEN
26+
expect(result).toBe(true);
27+
});
28+
29+
it("should return false for a schema that does not inherit from resource generic kind", () => {
30+
// GIVEN
31+
const schema = generateNodeSchema({ inherit_from: ["SomeOtherKind"] });
32+
33+
// WHEN
34+
const result = isPoolSchema(schema);
35+
36+
// THEN
37+
expect(result).toBe(false);
38+
});
39+
40+
it("should return false for a schema with undefined inherit_from", () => {
41+
// GIVEN
42+
const schema = generateNodeSchema({ inherit_from: undefined });
43+
44+
// WHEN
45+
const result = isPoolSchema(schema);
46+
47+
// THEN
48+
expect(result).toBe(false);
49+
});
50+
51+
it("should return false for a schema with empty inherit_from array", () => {
52+
// GIVEN
53+
const schema = generateNodeSchema({ inherit_from: [] });
54+
55+
// WHEN
56+
const result = isPoolSchema(schema);
57+
58+
// THEN
59+
expect(result).toBe(false);
60+
});
61+
62+
it("should return false for a generic schema even if it inherits from resource generic kind", () => {
63+
// GIVEN
64+
const schema = generateGenericSchema();
65+
66+
// WHEN
67+
const result = isPoolSchema(schema);
68+
69+
// THEN
70+
expect(result).toBe(false);
71+
});
72+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { RESOURCE_GENERIC_KIND } from "@/entities/resource-manager/constants";
2+
import { ModelSchema } from "@/entities/schema/types";
3+
import { isGenericSchema } from "@/entities/schema/utils/is-generic-schema";
4+
5+
export function isPoolSchema(schema: ModelSchema): boolean {
6+
return !isGenericSchema(schema) && !!schema.inherit_from?.includes(RESOURCE_GENERIC_KIND);
7+
}

frontend/app/src/shared/api/graphql/utils.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@ describe("addAttributesToRequest", () => {
6565
is_visible: true,
6666
source: {
6767
id: true,
68+
hfid: true,
6869
display_label: true,
6970
__typename: true,
7071
},
7172
owner: {
7273
id: true,
74+
hfid: true,
7375
display_label: true,
7476
__typename: true,
7577
},
@@ -122,11 +124,13 @@ describe("addAttributesToRequest", () => {
122124
is_visible: true,
123125
source: {
124126
id: true,
127+
hfid: true,
125128
display_label: true,
126129
__typename: true,
127130
},
128131
owner: {
129132
id: true,
133+
hfid: true,
130134
display_label: true,
131135
__typename: true,
132136
},
@@ -206,11 +210,13 @@ describe("addRelationshipsToRequest", () => {
206210
updated_at: true,
207211
source: {
208212
id: true,
213+
hfid: true,
209214
display_label: true,
210215
__typename: true,
211216
},
212217
owner: {
213218
id: true,
219+
hfid: true,
214220
display_label: true,
215221
__typename: true,
216222
},

frontend/app/src/shared/api/graphql/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ export const addAttributesToRequest = (
3535
is_visible: true,
3636
source: {
3737
id: true,
38+
hfid: true,
3839
display_label: true,
3940
__typename: true,
4041
},
4142
owner: {
4243
id: true,
44+
hfid: true,
4345
display_label: true,
4446
__typename: true,
4547
},
@@ -79,11 +81,13 @@ export const addRelationshipsToRequest = (
7981
updated_at: true,
8082
source: {
8183
id: true,
84+
hfid: true,
8285
display_label: true,
8386
__typename: true,
8487
},
8588
owner: {
8689
id: true,
90+
hfid: true,
8791
display_label: true,
8892
__typename: true,
8993
},

frontend/app/src/shared/components/form/utils/getFieldDefaultValue.test.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,43 @@
11
import { AttributeType } from "@/entities/nodes/getObjectItemDisplayValue";
22
import { NodeObject } from "@/entities/nodes/types";
3+
import {
4+
genericSchemasAtom,
5+
nodeSchemasAtom,
6+
profileSchemasAtom,
7+
templateSchemasAtom,
8+
} from "@/entities/schema/stores/schema.atom";
39
import { ProfileData } from "@/shared/components/form/object-form";
410
import {
511
GetFieldDefaultValue,
612
getFieldDefaultValue,
713
} from "@/shared/components/form/utils/getFieldDefaultValue";
8-
import { describe, expect, it } from "vitest";
14+
import { store } from "@/shared/stores";
15+
import { beforeEach, describe, expect, it } from "vitest";
16+
import {
17+
generateGenericSchema,
18+
generateNodeSchema,
19+
generateProfileSchema,
20+
generateTemplateSchema,
21+
} from "../../../../../tests/fake/schema";
922
import { buildAttributeSchema, buildRelationshipSchema } from "./getFormFieldsFromSchema.test";
1023

1124
describe("getFieldDefaultValue", () => {
25+
beforeEach(() => {
26+
// Initialize schema store with necessary schemas for type checking
27+
const nodeSchema = generateNodeSchema({ kind: "Node" });
28+
const genericSchema = generateGenericSchema({ kind: "Generic" });
29+
const profileSchema = generateProfileSchema({ kind: "Profile" });
30+
const templateSchema = generateTemplateSchema({ kind: "Template" });
31+
const fakeProfileSchema = generateProfileSchema({ kind: "FakeProfileKind" });
32+
const poolSchema = generateGenericSchema({ kind: "FakePool" });
33+
const fakeTemplateSchema = generateTemplateSchema({ kind: "FakeTemplateKind" });
34+
35+
store.set(nodeSchemasAtom, [nodeSchema]);
36+
store.set(genericSchemasAtom, [genericSchema, poolSchema]);
37+
store.set(profileSchemasAtom, [profileSchema, fakeProfileSchema]);
38+
store.set(templateSchemasAtom, [templateSchema, fakeTemplateSchema]);
39+
});
40+
1241
describe("when source is the user", () => {
1342
it("returns current object field's value when value is not from profile", () => {
1443
// GIVEN
@@ -524,6 +553,36 @@ describe("getFieldDefaultValue", () => {
524553
value: null,
525554
});
526555
});
556+
557+
it("retuns template when source is template", () => {
558+
// GIVEN
559+
const fieldSchema = buildAttributeSchema({ default_value: "my-default-value" });
560+
561+
const initialObject: Record<string, AttributeType> = {
562+
field1: {
563+
value: "my-value",
564+
source: {
565+
id: "template-id",
566+
display_label: "Template",
567+
__typename: "FakeTemplateKind",
568+
},
569+
},
570+
};
571+
572+
// WHEN
573+
const defaultValue = getFieldDefaultValue({ fieldSchema, initialObject });
574+
575+
// THEN
576+
expect(defaultValue).to.deep.equal({
577+
source: {
578+
id: "template-id",
579+
kind: "FakeTemplateKind",
580+
label: "Template",
581+
type: "template",
582+
},
583+
value: "my-value",
584+
});
585+
});
527586
});
528587

529588
describe("when source is pool", () => {

frontend/app/src/shared/components/form/utils/getFieldDefaultValue.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { AttributeType, FieldSchema } from "@/entities/nodes/getObjectItemDisplayValue";
22
import { getNodeLabel } from "@/entities/nodes/object/utils/get-node-label";
3-
import { NodeAttribute, NodeObject } from "@/entities/nodes/types";
3+
import { NodeAttribute, NodeCore, NodeObject } from "@/entities/nodes/types";
4+
import { getSchema } from "@/entities/schema/domain/get-schema";
5+
import { isPoolSchema } from "@/entities/schema/utils/is-pool-schema";
6+
import { isTemplateSchema } from "@/entities/schema/utils/is-template-schema";
47
import { LineageSource } from "@/shared/api/graphql/generated/graphql";
58
import { ProfileData } from "@/shared/components/form/object-form";
69
import {
@@ -44,7 +47,7 @@ export const getFieldDefaultValue = ({
4447
export const getCurrentFieldValue = (
4548
fieldName: string,
4649
objectData?: Record<string, AttributeType>
47-
): AttributeValueFromUser | null => {
50+
): AttributeValueFromUser | AttributeValueFromTemplate | null => {
4851
if (!objectData) return null;
4952

5053
const currentField = objectData[fieldName];
@@ -55,11 +58,42 @@ export const getCurrentFieldValue = (
5558
return null;
5659
}
5760

58-
if (currentField.source?.__typename?.match(/Pool$/g)) {
59-
return null;
61+
if (currentField.source && "__typename" in currentField.source) {
62+
const sourceKind = currentField.source.__typename as string;
63+
const { schema: sourceSchema } = getSchema(sourceKind);
64+
65+
if (!sourceSchema) {
66+
return {
67+
source: { type: "user" },
68+
value: currentField.value,
69+
};
70+
}
71+
72+
if (isPoolSchema(sourceSchema)) {
73+
return null;
74+
}
75+
76+
if (isTemplateSchema(sourceSchema)) {
77+
return {
78+
source: {
79+
type: "template",
80+
label: getNodeLabel(currentField.source as NodeCore),
81+
kind: sourceKind,
82+
id: currentField.source.id as string,
83+
},
84+
value: currentField.value,
85+
};
86+
}
87+
88+
if (sourceKind.includes("Pool")) {
89+
return null;
90+
}
6091
}
6192

62-
return { source: { type: "user" }, value: currentField.value };
93+
return {
94+
source: { type: "user" },
95+
value: currentField.value,
96+
};
6397
};
6498

6599
const getDefaultValueFromProfiles = (

frontend/app/src/shared/utils/common.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,6 @@ export const classNames = (...classes: ClassValue[]) => {
66
return twMerge(clsx(classes));
77
};
88

9-
export const objectToString = (object: any) =>
10-
Object.entries(object)
11-
.map(([key, value]) => {
12-
switch (typeof value) {
13-
// Add quotes for string
14-
case "string": {
15-
return `${key}:"${value}"`;
16-
}
17-
default: {
18-
return `${key}:${value}`;
19-
}
20-
}
21-
})
22-
.join(",");
23-
249
export const sortByName = R.sortBy(R.compose(R.toLower, R.prop("name")));
2510

2611
export const sortByOrderWeight = R.sortBy(R.compose(R.prop("order_weight")));

0 commit comments

Comments
 (0)