Skip to content

Commit 562bc11

Browse files
committed
update(Frontend v2): Finished Enums
1 parent c9ef5d9 commit 562bc11

13 files changed

Lines changed: 762 additions & 223 deletions

File tree

fastapi_forge/schemas.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Annotated, Any, Self
1+
from typing import Annotated, Any, Self
22

33
from pydantic import (
44
BaseModel,

frontend/src/assets/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ body {
66
:root {
77
--color-primary: #5294fd;
88
--color-secondary: #dcebfe;
9-
--color-success: #b8fd9f;
9+
--color-success: #7fbc8c;
1010
--color-danger: #ff6b6b;
1111
--color-background: #f4f4f0;
1212
}

frontend/src/components/StepWizard.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const goToStep = (index) => {
9191
}
9292
9393
.step.completed {
94-
background-color: #7fbc8c;
94+
background-color: var(--color-success);
9595
}
9696
9797
.step-content {
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<template>
2+
<main class="field-modal-container">
3+
<div class="input-container">
4+
<div class="input-group">
5+
<label class="field-label">Name</label>
6+
<input class="field-input" v-model="name" type="text" />
7+
</div>
8+
9+
<div class="input-group">
10+
<label class="field-label">Value</label>
11+
<input class="field-input" v-model="value" type="text" />
12+
</div>
13+
</div>
14+
15+
<div class="action-group">
16+
<button class="save-field-btn" @click="saveEnumValue">Save</button>
17+
</div>
18+
</main>
19+
</template>
20+
21+
<script setup lang="ts">
22+
import { ref } from "vue"
23+
import { useProjectStore } from "@/stores/useProjectStore"
24+
import { useModalStore } from "@/stores/useModalStore"
25+
26+
const props = defineProps<{
27+
enumName: string
28+
}>()
29+
30+
const projectStore = useProjectStore()
31+
const modalStore = useModalStore()
32+
33+
const name = ref("")
34+
const value = ref("auto()")
35+
36+
const saveEnumValue = () => {
37+
projectStore.addEnumValue(props.enumName, {
38+
name: name.value,
39+
value: value.value,
40+
})
41+
modalStore.close()
42+
}
43+
</script>
44+
45+
<style scoped>
46+
.field-modal-container {
47+
display: flex;
48+
flex-direction: column;
49+
gap: 1rem;
50+
padding: 1rem;
51+
}
52+
53+
.input-container {
54+
display: flex;
55+
flex-direction: column;
56+
gap: 1rem;
57+
}
58+
59+
.input-group {
60+
display: flex;
61+
flex-direction: column;
62+
gap: 0.15rem;
63+
}
64+
65+
.field-label {
66+
font-weight: bold;
67+
margin-bottom: 5px;
68+
}
69+
70+
.field-input {
71+
border: 2px solid black;
72+
border-radius: 6px;
73+
padding: 0.6rem;
74+
background-color: white;
75+
}
76+
77+
.action-group {
78+
gap: 0.5rem;
79+
margin-top: 2rem;
80+
display: flex;
81+
flex-direction: column;
82+
}
83+
84+
.save-field-btn {
85+
width: 100%;
86+
padding: 0.5rem 1rem;
87+
border: 2px solid black;
88+
border-radius: 4px;
89+
background-color: var(--color-success);
90+
box-shadow: 3px 3px 0px black;
91+
transition:
92+
transform 0.1s ease-in-out,
93+
box-shadow 0.1s ease-in-out;
94+
}
95+
96+
.save-field-btn:hover {
97+
cursor: pointer;
98+
transform: translate(2px, 2px);
99+
box-shadow: none;
100+
}
101+
</style>

frontend/src/components/modal/AddFieldModal.vue

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,29 @@
1616
<option value="DateTime">DateTime</option>
1717
<option value="Boolean">Boolean</option>
1818
<option value="Float">Float</option>
19+
<option value="Enum">Enum</option>
20+
</select>
21+
</div>
22+
23+
<div class="input-group" v-if="type === 'Enum'">
24+
<label class="field-label">Select Enum</label>
25+
<select class="field-select" v-model="selectedEnum">
26+
<option disabled value="">-- Select Enum --</option>
27+
<option v-for="e in projectStore.enums" :key="e.name" :value="e">
28+
{{ e.name }}
29+
</option>
1930
</select>
2031
</div>
2132

2233
<div class="input-group">
2334
<label class="field-label">Default value</label>
24-
<input class="field-input" v-model="defaultValue" type="text" />
35+
<select class="field-select" v-model="defaultValue" v-if="type === 'Enum'">
36+
<option value="" />
37+
<option v-for="v in selectedEnum?.values" :key="v.name" :value="v.name">
38+
{{ v.name }}
39+
</option>
40+
</select>
41+
<input class="field-input" v-model="defaultValue" type="text" v-else />
2542
</div>
2643
</div>
2744

@@ -42,6 +59,7 @@
4259
import { ref } from "vue"
4360
import { useProjectStore } from "@/stores/useProjectStore"
4461
import { useModalStore } from "@/stores/useModalStore"
62+
import type { EnumT, FieldType } from "@/types/types"
4563
4664
const props = defineProps<{
4765
id: string
@@ -50,6 +68,8 @@ const props = defineProps<{
5068
const projectStore = useProjectStore()
5169
const modalStore = useModalStore()
5270
71+
const selectedEnum = ref<EnumT | undefined>()
72+
5373
const fieldName = ref("")
5474
const type = ref("")
5575
const defaultValue = ref("")
@@ -62,12 +82,13 @@ const saveField = () => {
6282
if (!fieldName.value || !type.value) return
6383
projectStore.addField(props.id, {
6484
name: fieldName.value,
65-
type: type.value,
66-
default: defaultValue.value || undefined,
85+
type: type.value as FieldType,
86+
typeEnum: selectedEnum.value?.name,
6787
isPrimaryKey: isPrimaryKey.value,
6888
isNullable: isNullable.value,
6989
isUnique: isUnique.value,
7090
isIndex: isIndex.value,
91+
defaultValue: defaultValue.value || undefined,
7192
})
7293
modalStore.close()
7394
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<template>
2+
<main class="field-modal-container">
3+
<div class="input-container">
4+
<div class="input-group">
5+
<label class="field-label">Name</label>
6+
<input class="field-input" v-model="name" type="text" />
7+
</div>
8+
9+
<div class="input-group">
10+
<label class="field-label">Value</label>
11+
<input class="field-input" v-model="value" type="text" />
12+
</div>
13+
</div>
14+
15+
<div class="action-group">
16+
<button class="save-field-btn" @click="saveEnumValue">Save</button>
17+
</div>
18+
</main>
19+
</template>
20+
21+
<script setup lang="ts">
22+
import { ref } from "vue"
23+
import { useProjectStore } from "@/stores/useProjectStore"
24+
import { useModalStore } from "@/stores/useModalStore"
25+
import type { EnumValue } from "@/types/types"
26+
27+
const props = defineProps<{
28+
enumName: string
29+
enumValue: EnumValue
30+
}>()
31+
32+
const projectStore = useProjectStore()
33+
const modalStore = useModalStore()
34+
35+
const name = ref(props.enumValue.name)
36+
const value = ref(props.enumValue.value)
37+
38+
const saveEnumValue = () => {
39+
projectStore.updateEnumValue(props.enumName, props.enumValue.name, {
40+
name: name.value,
41+
value: value.value,
42+
})
43+
modalStore.close()
44+
}
45+
</script>
46+
47+
<style scoped>
48+
.field-modal-container {
49+
display: flex;
50+
flex-direction: column;
51+
gap: 1rem;
52+
padding: 1rem;
53+
}
54+
55+
.input-container {
56+
display: flex;
57+
flex-direction: column;
58+
gap: 1rem;
59+
}
60+
61+
.input-group {
62+
display: flex;
63+
flex-direction: column;
64+
gap: 0.15rem;
65+
}
66+
67+
.field-label {
68+
font-weight: bold;
69+
margin-bottom: 5px;
70+
}
71+
72+
.field-input {
73+
border: 2px solid black;
74+
border-radius: 6px;
75+
padding: 0.6rem;
76+
background-color: white;
77+
}
78+
79+
.action-group {
80+
gap: 0.5rem;
81+
margin-top: 2rem;
82+
display: flex;
83+
flex-direction: column;
84+
}
85+
86+
.save-field-btn {
87+
width: 100%;
88+
padding: 0.5rem 1rem;
89+
border: 2px solid black;
90+
border-radius: 4px;
91+
background-color: var(--color-success);
92+
box-shadow: 3px 3px 0px black;
93+
transition:
94+
transform 0.1s ease-in-out,
95+
box-shadow 0.1s ease-in-out;
96+
}
97+
98+
.save-field-btn:hover {
99+
cursor: pointer;
100+
transform: translate(2px, 2px);
101+
box-shadow: none;
102+
}
103+
</style>

frontend/src/components/modal/EditFieldModal.vue

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,29 @@
1616
<option value="DateTime">DateTime</option>
1717
<option value="Boolean">Boolean</option>
1818
<option value="Float">Float</option>
19+
<option value="Enum">Enum</option>
20+
</select>
21+
</div>
22+
23+
<div class="input-group" v-if="type === 'Enum'">
24+
<label class="field-label">Select Enum</label>
25+
<select class="field-select" v-model="selectedEnum">
26+
<option disabled value="">-- Select Enum --</option>
27+
<option v-for="e in projectStore.enums" :key="e.name" :value="e">
28+
{{ e.name }}
29+
</option>
1930
</select>
2031
</div>
2132

2233
<div class="input-group">
2334
<label class="field-label">Default value</label>
24-
<input class="field-input" v-model="defaultValue" type="text" />
35+
<select class="field-select" v-model="defaultValue" v-if="type === 'Enum'">
36+
<option value="" />
37+
<option v-for="v in selectedEnum?.values" :key="v.name" :value="v.name">
38+
{{ v.name }}
39+
</option>
40+
</select>
41+
<input class="field-input" v-model="defaultValue" type="text" v-else />
2542
</div>
2643
</div>
2744

@@ -40,32 +57,41 @@
4057
</template>
4158

4259
<script setup lang="ts">
43-
import { ref } from "vue"
60+
import { ref, onMounted } from "vue"
4461
import { useProjectStore } from "@/stores/useProjectStore"
4562
import { useModalStore } from "@/stores/useModalStore"
46-
import type { Field } from "@/types/types"
63+
import type { EnumT, RelationalField } from "@/types/types"
4764
4865
const props = defineProps<{
4966
id: string
50-
field: Field
67+
field: RelationalField
5168
}>()
5269
5370
const projectStore = useProjectStore()
5471
const modalStore = useModalStore()
5572
73+
const selectedEnum = ref<EnumT | undefined>()
74+
onMounted(() => {
75+
if (props.field.type !== "Enum" || !props.field.typeEnum) return
76+
selectedEnum.value = projectStore.findEnumByName(props.field.typeEnum)
77+
})
78+
5679
const fieldName = ref(props.field.name)
5780
const type = ref(props.field.type)
58-
const defaultValue = ref(props.field.default || "")
81+
const defaultValue = ref(props.field.defaultValue || "")
5982
const isPrimaryKey = ref(props.field.isPrimaryKey || false)
6083
const isNullable = ref(props.field.isNullable || false)
6184
const isUnique = ref(props.field.isUnique || false)
6285
const isIndex = ref(props.field.isIndex || false)
6386
87+
console.log(defaultValue.value)
88+
6489
const saveField = () => {
6590
projectStore.updateField(props.id, props.field.name, {
6691
name: fieldName.value,
6792
type: type.value,
68-
default: defaultValue.value || undefined,
93+
typeEnum: selectedEnum.value?.name,
94+
defaultValue: defaultValue.value || undefined,
6995
isPrimaryKey: isPrimaryKey.value,
7096
isNullable: isNullable.value,
7197
isUnique: isUnique.value,

frontend/src/components/schema_editor/CustomNode.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
@click="$emit('open-edit-field-modal', props.id, field)"
4242
>
4343
<div class="custom-node-field-name">{{ field.name }}</div>
44-
<div class="custom-node-field-type">{{ field.type }}</div>
44+
<div class="custom-node-field-type" v-if="field.type !== 'Enum'">{{ field.type }}</div>
45+
<div class="custom-node-field-type" v-else>{{ field.type }}({{ field.typeEnum }})</div>
4546
</div>
4647
<div
4748
v-for="relation in data.relations"
@@ -58,7 +59,6 @@
5859

5960
<script setup lang="ts">
6061
import { ref } from "vue"
61-
import type { Position2D } from "@/types/types"
6262
const props = defineProps<{
6363
id: string
6464
data: object

0 commit comments

Comments
 (0)