Skip to content

Commit 0956064

Browse files
committed
feat(Frontend v2): Add Enums view
1 parent 5000b49 commit 0956064

6 files changed

Lines changed: 272 additions & 65 deletions

File tree

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<template>
2+
<div class="enum-sidebar">
3+
<div class="sidebar-header">
4+
<div class="create-enum-wrapper">
5+
<input
6+
class="create-enum-input"
7+
type="text"
8+
placeholder="New Enum Name"
9+
v-model="newEnumName"
10+
@keyup.enter="createEnum"
11+
/>
12+
<button class="create-enum-btn" @click="createEnum">+</button>
13+
</div>
14+
</div>
15+
<div class="enum-list">
16+
<div
17+
v-for="enumItem in enums"
18+
:key="enumItem.name"
19+
class="enum-item"
20+
:class="{ active: selectedEnumName === enumItem.name }"
21+
@click="selectEnum(enumItem)"
22+
>
23+
{{ enumItem.name }}
24+
<button class="delete-enum-btn" @click.stop="deleteEnum(enumItem.name)">×</button>
25+
</div>
26+
</div>
27+
</div>
28+
</template>
29+
30+
<script setup lang="ts">
31+
import { ref } from "vue"
32+
import type { Enum, EnumsArray } from "@/types/types.ts"
33+
34+
const enums = ref<EnumsArray>([
35+
{
36+
name: "UserRole",
37+
values: [
38+
{ name: "ADMIN", value: "admin" },
39+
{ name: "USER", value: "auto()" },
40+
],
41+
},
42+
])
43+
44+
const newEnumName = ref("")
45+
const selectedEnumName = ref<string | null>(null)
46+
47+
const emit = defineEmits(["enum-selected"])
48+
49+
const selectEnum = (enumItem: Enum) => {
50+
selectedEnumName.value = enumItem.name
51+
emit("enum-selected", enumItem)
52+
}
53+
54+
const createEnum = () => {
55+
if (newEnumName.value.trim() === "") return
56+
57+
const newEnum: Enum = {
58+
name: newEnumName.value.trim(),
59+
values: [],
60+
}
61+
62+
enums.value.push(newEnum)
63+
newEnumName.value = ""
64+
selectEnum(newEnum)
65+
}
66+
67+
const deleteEnum = (name: string) => {
68+
enums.value = enums.value.filter((e: Enum) => e.name !== name)
69+
if (selectedEnumName.value === name) {
70+
selectedEnumName.value = null
71+
}
72+
}
73+
</script>
74+
75+
<style scoped>
76+
.enum-sidebar {
77+
width: 250px;
78+
height: 100%;
79+
border-right: 2px solid black;
80+
display: flex;
81+
flex-direction: column;
82+
background-color: white;
83+
}
84+
85+
.sidebar-header {
86+
height: 32px;
87+
padding: 10px;
88+
border-bottom: 2px solid black;
89+
}
90+
91+
.create-enum-wrapper {
92+
display: flex;
93+
gap: 5px;
94+
height: 100%;
95+
}
96+
97+
.create-enum-input {
98+
flex: 1;
99+
border: 2px solid black;
100+
border-radius: 6px;
101+
padding: 0 10px;
102+
}
103+
104+
.create-enum-btn {
105+
width: 32px;
106+
border: 2px solid black;
107+
border-radius: 6px;
108+
background-color: white;
109+
font-weight: bold;
110+
cursor: pointer;
111+
}
112+
113+
.create-enum-btn:hover {
114+
background-color: var(--color-success);
115+
}
116+
117+
.enum-list {
118+
flex: 1;
119+
padding: 5px;
120+
overflow-y: auto;
121+
}
122+
123+
.enum-item {
124+
padding: 10px 15px;
125+
cursor: pointer;
126+
display: flex;
127+
justify-content: space-between;
128+
align-items: center;
129+
border-radius: 8px;
130+
border: 2px solid transparent;
131+
height: 15px;
132+
}
133+
134+
.enum-item.active,
135+
.enum-item:hover {
136+
background-color: var(--color-primary);
137+
font-weight: bold;
138+
border-color: black;
139+
}
140+
141+
.delete-enum-btn {
142+
background: none;
143+
border: none;
144+
font-size: 18px;
145+
cursor: pointer;
146+
padding: 0 5px;
147+
}
148+
149+
.delete-enum-btn:hover {
150+
color: red;
151+
}
152+
</style>

frontend/src/components/schema_editor/SchemaEditor.vue

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
<template>
2-
<main class="container">
3-
<div class="vue-flow-container">
4-
<div class="vue-flow-header">
5-
<div class="header-section" @click="() => console.log('Models clicked')">Models</div>
6-
<div class="header-divider" />
7-
<div class="header-section" @click="() => console.log('Enums clicked')">Enums</div>
8-
</div>
9-
10-
<div class="vue-flow-viewport">
2+
<div class="vue-flow-container">
3+
<div class="vue-flow-viewport">
4+
<div class="viewport-wrapper">
115
<div class="toggle-grid-button" @click="showGrid = !showGrid">#</div>
12-
136
<VueFlow
147
v-model:nodes="projectStore.nodes"
158
v-model:edges="projectStore.edges"
@@ -46,7 +39,6 @@
4639
/>
4740
<button class="create-model-btn" @click="handleCreateClick">Create</button>
4841
</div>
49-
5042
<div v-if="!showInput" class="create-circle" @click="showInput = true">+</div>
5143
</div>
5244

@@ -64,7 +56,7 @@
6456
</VueFlow>
6557
</div>
6658
</div>
67-
</main>
59+
</div>
6860
</template>
6961

7062
<script setup lang="ts">
@@ -87,7 +79,7 @@ const modalStore = useModalStore()
8779
8880
const modelName = ref("")
8981
const showInput = ref(false)
90-
const showGrid = ref(false)
82+
const showGrid = ref(true)
9183
9284
const handleCreateClick = () => {
9385
if (modelName.value.trim() === "") return
@@ -122,49 +114,20 @@ const openEditRelationModal = (id: string, relation: RelationalRelationField) =>
122114
</script>
123115

124116
<style scoped>
125-
.container {
126-
width: 100%;
127-
height: 100%;
128-
}
129-
130117
.vue-flow-container {
131-
width: 1000px;
132-
height: 500px;
133-
background-color: #ffffff;
134-
border: 2px solid black;
135-
}
136-
137-
.vue-flow-header {
138-
height: 40px;
118+
height: 100%;
139119
display: flex;
140-
align-items: center;
141-
background-color: var(--color-primary);
142-
width: 100%;
143-
border-bottom: 2px solid black;
144-
box-sizing: border-box;
145120
}
146121
147-
.header-section {
122+
.vue-flow-viewport {
123+
position: relative;
148124
flex: 1;
149-
text-align: center;
150-
cursor: pointer;
151-
font-weight: bold;
152125
display: flex;
153-
align-items: center;
154-
justify-content: center;
155-
height: 100%;
156126
}
157127
158-
.header-divider {
159-
width: 2px;
160-
height: 100%;
161-
background-color: black;
162-
}
163-
164-
.vue-flow-viewport {
165-
position: relative;
128+
.viewport-wrapper {
166129
width: 100%;
167-
height: calc(100% - 42px);
130+
height: 100%;
168131
}
169132
170133
.toggle-grid-button {
@@ -181,9 +144,6 @@ const openEditRelationModal = (id: string, relation: RelationalRelationField) =>
181144
cursor: pointer;
182145
z-index: 10;
183146
box-shadow: 2px 2px 0px rgba(0, 0, 0, 1);
184-
transition:
185-
transform 0.1s ease-out,
186-
box-shadow 0.1s;
187147
}
188148
189149
.toggle-grid-button:hover {
@@ -215,9 +175,6 @@ const openEditRelationModal = (id: string, relation: RelationalRelationField) =>
215175
font-weight: bold;
216176
z-index: 10;
217177
box-shadow: 2px 2px 0px rgba(0, 0, 0, 1);
218-
transition:
219-
transform 0.1s ease-out,
220-
box-shadow 0.1s;
221178
}
222179
223180
.create-circle:hover {
@@ -270,9 +227,21 @@ const openEditRelationModal = (id: string, relation: RelationalRelationField) =>
270227
border-radius: 6px;
271228
cursor: pointer;
272229
font-weight: bold;
230+
background-color: var(--color-secondary);
231+
margin-right: 5px;
273232
}
274233
275234
.create-model-btn:hover {
276235
background-color: var(--color-success);
277236
}
237+
238+
.enums-view {
239+
width: 100%;
240+
height: 100%;
241+
display: flex;
242+
justify-content: center;
243+
align-items: center;
244+
font-size: 24px;
245+
font-weight: bold;
246+
}
278247
</style>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<template>
2+
<main class="container">
3+
<div class="editor-container">
4+
<div class="editor-header">
5+
<div
6+
class="header-section"
7+
:class="{ active: activeTab === 'models' }"
8+
@click="activeTab = 'models'"
9+
>
10+
Models
11+
</div>
12+
<div class="header-divider" />
13+
<div
14+
class="header-section"
15+
:class="{ active: activeTab === 'enums' }"
16+
@click="activeTab = 'enums'"
17+
>
18+
Enums
19+
</div>
20+
</div>
21+
22+
<div class="editor-content">
23+
<SchemaEditor v-if="activeTab === 'models'" />
24+
<EnumEditor v-if="activeTab === 'enums'" />
25+
</div>
26+
</div>
27+
</main>
28+
</template>
29+
30+
<script setup lang="ts">
31+
import { ref } from "vue"
32+
import SchemaEditor from "@/components/schema_editor/SchemaEditor.vue"
33+
import EnumEditor from "@/components/schema_editor/EnumEditor.vue"
34+
35+
const activeTab = ref<"models" | "enums">("models")
36+
</script>
37+
38+
<style scoped>
39+
.container {
40+
width: 100%;
41+
height: 100vh;
42+
display: flex;
43+
justify-content: center;
44+
align-items: center;
45+
background-color: white;
46+
}
47+
48+
.editor-container {
49+
width: 1000px;
50+
height: 500px;
51+
background-color: #ffffff;
52+
border: 2px solid black;
53+
display: flex;
54+
flex-direction: column;
55+
overflow: hidden;
56+
}
57+
58+
.editor-header {
59+
height: 40px;
60+
display: flex;
61+
align-items: center;
62+
background-color: var(--color-primary);
63+
width: 100%;
64+
border-bottom: 2px solid black;
65+
box-sizing: border-box;
66+
}
67+
68+
.header-section {
69+
flex: 1;
70+
text-align: center;
71+
cursor: pointer;
72+
font-weight: bold;
73+
display: flex;
74+
align-items: center;
75+
justify-content: center;
76+
height: 100%;
77+
user-select: none;
78+
}
79+
80+
.header-divider {
81+
width: 2px;
82+
height: 100%;
83+
background-color: black;
84+
}
85+
86+
.editor-content {
87+
position: relative;
88+
flex: 1;
89+
width: 100%;
90+
height: calc(100% - 40px);
91+
}
92+
</style>

0 commit comments

Comments
 (0)