Skip to content

Commit ffc68d5

Browse files
Use schemas to dynamically display editPage
Update routes with correct names
1 parent 21ed72d commit ffc68d5

File tree

4 files changed

+594
-2
lines changed

4 files changed

+594
-2
lines changed

pydatalab/src/pydatalab/routes/v0_1/info.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pydatalab import __version__
1212
from pydatalab.blocks import BLOCK_TYPES
1313
from pydatalab.config import CONFIG, FEATURE_FLAGS, FeatureFlags
14-
from pydatalab.models import Person
14+
from pydatalab.models import Collection, Equipment, Person, Sample, StartingMaterial
1515
from pydatalab.mongo import flask_mongo
1616

1717
from ._version import __api_version__
@@ -143,3 +143,39 @@ def list_block_types():
143143
).json()
144144
)
145145
)
146+
147+
148+
@INFO.route("/info/types", methods=["GET"])
149+
def list_supported_types_schemas():
150+
"""Returns a dictionary of supported item types and their schemas."""
151+
schemas = {
152+
"samples": Sample.schema(),
153+
"collections": Collection.schema(),
154+
"starting_materials": StartingMaterial.schema(),
155+
"equipment": Equipment.schema(),
156+
}
157+
return jsonify(schemas)
158+
159+
160+
@INFO.route("/info/types/samples", methods=["GET"])
161+
def get_sample_schema():
162+
"""Returns the JSON schema for the Sample type."""
163+
return jsonify(Sample.schema())
164+
165+
166+
@INFO.route("/info/types/collections", methods=["GET"])
167+
def get_collection_schema():
168+
"""Returns the JSON schema for the Collection type."""
169+
return jsonify(Collection.schema())
170+
171+
172+
@INFO.route("/info/types/starting_materials", methods=["GET"])
173+
def get_starting_material_schema():
174+
"""Returns the JSON StartingMaterial for the Sample type."""
175+
return jsonify(StartingMaterial.schema())
176+
177+
178+
@INFO.route("/info/types/equipment", methods=["GET"])
179+
def get_equipment_schema():
180+
"""Returns the JSON schema for the Equipment type."""
181+
return jsonify(Equipment.schema())
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<template>
2+
<div v-if="schema?.properties && data">
3+
<div v-for="(field, index) in Object.keys(schema.properties)" :key="index">
4+
<label v-if="field != 'relationships'" :for="field">{{
5+
schema.properties[field].title
6+
}}</label>
7+
8+
<component
9+
:is="getComponentType(field)"
10+
:key="index"
11+
:value="data[field]"
12+
:placeholder="field.title"
13+
v-bind="getComponentProps(field)"
14+
@input="(value) => updateData(field.name, value)"
15+
/>
16+
</div>
17+
</div>
18+
</template>
19+
20+
<script>
21+
import { getSchema } from "@/server_fetch_utils";
22+
import FormattedItemName from "@/components/FormattedItemName";
23+
import FormattedRefcode from "@/components/FormattedRefcode";
24+
import Creators from "@/components/Creators";
25+
import ToggleableCollectionFormGroup from "@/components/ToggleableCollectionFormGroup";
26+
import TinyMceInline from "@/components/TinyMceInline";
27+
import ItemRelationshipVisualization from "@/components/ItemRelationshipVisualization";
28+
29+
export default {
30+
props: {
31+
modelValue: {
32+
type: Object,
33+
required: true,
34+
},
35+
},
36+
emits: ["update:modelValue"],
37+
data() {
38+
return {
39+
schema: null,
40+
};
41+
},
42+
computed: {
43+
data() {
44+
return this.modelValue;
45+
},
46+
},
47+
async mounted() {
48+
this.schema = await getSchema(this.data?.type);
49+
console.log("#%#%%#%#%#%#%#%#%#");
50+
console.log(this.schema);
51+
console.log("#%#%%#%#%#%#%#%#%#");
52+
},
53+
methods: {
54+
getComponentType(field) {
55+
const fieldSchema = this.schema.properties[field];
56+
57+
switch (field) {
58+
case "item_id":
59+
return FormattedItemName;
60+
case "refcode":
61+
return FormattedRefcode;
62+
case "creators":
63+
return Creators;
64+
case "collections":
65+
return ToggleableCollectionFormGroup;
66+
case "description":
67+
return TinyMceInline;
68+
case "relationships":
69+
return ItemRelationshipVisualization;
70+
71+
case fieldSchema.type:
72+
if (["date", "string", "integer", "object"].includes(fieldSchema.type)) {
73+
return "input";
74+
}
75+
if (fieldSchema.type === "array") {
76+
return "textarea";
77+
}
78+
79+
return "input";
80+
default:
81+
return "input";
82+
}
83+
},
84+
85+
getComponentProps(field) {
86+
const fieldSchema = this.schema.properties[field];
87+
88+
if (field === "item_id") {
89+
return {
90+
itemType: this.data.type,
91+
item_id: this.data.item_id,
92+
enableClick: true,
93+
};
94+
}
95+
if (field === "refcode") {
96+
return {
97+
refcode: this.data.refcode,
98+
};
99+
}
100+
if (field === "creators") {
101+
return {
102+
creators: this.data.creators,
103+
};
104+
}
105+
if (field === "collections") {
106+
return {
107+
modelValue: this.data.collections,
108+
};
109+
}
110+
if (field === "description") {
111+
return {
112+
modelValue: this.data.description,
113+
};
114+
}
115+
if (field === "relationships") {
116+
return {
117+
item_id: this.data.item_id,
118+
};
119+
}
120+
121+
if (fieldSchema.type === "date") {
122+
return {
123+
value: this.data[field],
124+
type: "datetime-local",
125+
class: "form-control",
126+
};
127+
}
128+
if (fieldSchema.type === "string") {
129+
return {
130+
value: this.data[field],
131+
type: "text",
132+
class: "form-control",
133+
};
134+
}
135+
if (fieldSchema.type === "integer") {
136+
return {
137+
value: this.data[field],
138+
type: "number",
139+
class: "form-control",
140+
};
141+
}
142+
if (fieldSchema.type === "array") {
143+
return {
144+
value: this.data[field].join(", "),
145+
class: "form-control",
146+
};
147+
}
148+
if (fieldSchema.type === "object") {
149+
return {
150+
value: JSON.stringify(this.data[field]),
151+
class: "form-control",
152+
};
153+
}
154+
155+
return { readonly: true, disabled: true };
156+
},
157+
updateData(fieldName, value) {
158+
const newData = { ...this.data, [fieldName]: value };
159+
this.$emit("update:modelValue", newData);
160+
},
161+
},
162+
};
163+
</script>

webapp/src/router/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Equipment from "../views/Equipment.vue";
44
import StartingMaterials from "../views/StartingMaterials.vue";
55
import Collections from "@/views/Collections.vue";
66
import NotFound from "../views/NotFound.vue";
7-
import EditPage from "../views/EditPage.vue";
7+
import EditPage from "../views/EditPageV2.vue";
88
import CollectionPage from "../views/CollectionPage.vue";
99
import ExampleGraph from "@/views/ExampleGraph.vue";
1010
import ItemGraphPage from "@/views/ItemGraphPage.vue";

0 commit comments

Comments
 (0)