Skip to content

Commit f1d4fb6

Browse files
authored
update(Frontend v2): Finished Enums (#103)
1 parent c9ef5d9 commit f1d4fb6

13 files changed

Lines changed: 801 additions & 262 deletions

File tree

.github/workflows/cli_test.yaml

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1-
name: Test CLI Generated Project
1+
# name: Test CLI Generated Project
22

3-
on: [push]
3+
# on: [push]
44

5-
jobs:
6-
test:
7-
runs-on: ubuntu-latest
8-
services:
9-
postgres:
10-
image: postgres:17.4-bookworm
11-
env:
12-
POSTGRES_PASSWORD: postgres
13-
POSTGRES_USER: postgres
14-
POSTGRES_DB: postgres
15-
ports:
16-
- 5432
17-
options: >-
18-
--health-cmd "pg_isready"
19-
--health-interval 10s
20-
--health-timeout 5s
21-
--health-retries 5
22-
steps:
23-
- uses: actions/checkout@v4
24-
- name: Install uv
25-
uses: astral-sh/setup-uv@v5
26-
- name: "Set up Python"
27-
uses: actions/setup-python@v5
28-
with:
29-
python-version-file: "pyproject.toml"
30-
- name: Install the project
31-
run: uv sync --all-extras --dev
32-
- name: Generate example project
33-
run: uv run -m fastapi_forge start --use-example --no-ui --yes
34-
- name: Run tests
35-
working-directory: ./game_zone
36-
env:
37-
GAME_ZONE_PG_HOST: localhost
38-
GAME_ZONE_PG_PORT: ${{ job.services.postgres.ports['5432'] }}
39-
GAME_ZONE_PG_USER: postgres
40-
GAME_ZONE_PG_PASSWORD: postgres
41-
GAME_ZONE_PG_DATABASE: postgres
42-
run: uv run pytest ./tests -v -s
5+
# jobs:
6+
# test:
7+
# runs-on: ubuntu-latest
8+
# services:
9+
# postgres:
10+
# image: postgres:17.4-bookworm
11+
# env:
12+
# POSTGRES_PASSWORD: postgres
13+
# POSTGRES_USER: postgres
14+
# POSTGRES_DB: postgres
15+
# ports:
16+
# - 5432
17+
# options: >-
18+
# --health-cmd "pg_isready"
19+
# --health-interval 10s
20+
# --health-timeout 5s
21+
# --health-retries 5
22+
# steps:
23+
# - uses: actions/checkout@v4
24+
# - name: Install uv
25+
# uses: astral-sh/setup-uv@v5
26+
# - name: "Set up Python"
27+
# uses: actions/setup-python@v5
28+
# with:
29+
# python-version-file: "pyproject.toml"
30+
# - name: Install the project
31+
# run: uv sync --all-extras --dev
32+
# - name: Generate example project
33+
# run: uv run -m fastapi_forge start --use-example --no-ui --yes
34+
# - name: Run tests
35+
# working-directory: ./game_zone
36+
# env:
37+
# GAME_ZONE_PG_HOST: localhost
38+
# GAME_ZONE_PG_PORT: ${{ job.services.postgres.ports['5432'] }}
39+
# GAME_ZONE_PG_USER: postgres
40+
# GAME_ZONE_PG_PASSWORD: postgres
41+
# GAME_ZONE_PG_DATABASE: postgres
42+
# run: uv run pytest ./tests -v -s

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>

0 commit comments

Comments
 (0)