Skip to content

Commit a2bdbfb

Browse files
committed
Init
1 parent b9861de commit a2bdbfb

7 files changed

Lines changed: 71 additions & 27 deletions

File tree

fastapi_forge/frontend/components/model_row.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,24 @@ def __init__(
1212
):
1313
super().__init__(wrap=False)
1414
self.model = model
15-
self.is_editing = False
15+
self.is_selected_row = model == state.selected_model
1616
self.color = color
17+
self.is_editing = False
1718
self._build()
1819

1920
def _build(self) -> None:
20-
with self.classes("w-full flex items-center justify-between cursor-pointer"):
21-
self.name_label = ui.label(text=self.model.name).classes("self-center")
21+
base_classes = "w-full flex items-center justify-between cursor-pointer p-2 rounded transition-all"
22+
if self.is_selected_row:
23+
base_classes += " bg-blue-100 dark:bg-blue-900 border-l-4 border-blue-500"
24+
else:
25+
base_classes += " hover:bg-gray-100 dark:hover:bg-gray-800"
26+
27+
with self.classes(base_classes):
28+
self.name_label = (
29+
ui.label(text=self.model.name)
30+
.classes("self-center")
31+
.on("click", lambda: state.select_model(self.model))
32+
)
2233
if self.color:
2334
self.name_label.classes(add=self.color)
2435
self.name_input = (
@@ -28,7 +39,7 @@ def _build(self) -> None:
2839
)
2940
self.name_label.bind_visibility_from(self, "is_editing", lambda x: not x)
3041

31-
self.on("click", lambda: state.select_model(self.model))
42+
# self.on("click", lambda: state.select_model(self.model))
3243

3344
with ui.row().classes("gap-2"):
3445
self.edit_button = ui.button(
@@ -39,16 +50,16 @@ def _build(self) -> None:
3950
icon="save",
4051
on_click=self._save_model,
4152
).bind_visibility_from(self, "is_editing")
42-
ui.button(icon="delete", on_click=self._delete_model)
53+
ui.button(
54+
icon="delete", on_click=lambda _: state.delete_model(self.model)
55+
)
4356

4457
def _toggle_edit(self) -> None:
58+
print("editing")
4559
self.is_editing = not self.is_editing
4660

4761
def _save_model(self) -> None:
4862
new_name = self.name_input.value.strip()
4963
if new_name:
5064
state.update_model_name(self.model, new_name)
5165
self.is_editing = False
52-
53-
def _delete_model(self) -> None:
54-
state.delete_model(self.model)

fastapi_forge/frontend/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import Any
22

3+
SELECTED_MODEL_TEXT_COLOR = "text-black-500 dark:text-amber-300"
4+
35
FIELD_COLUMNS: list[dict[str, Any]] = [
46
{
57
"name": "name",

fastapi_forge/frontend/main.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ def load_initial_project(path: Path) -> p.ProjectSpec:
3838
def create_ui_components() -> None:
3939
"""Create all UI components"""
4040
with ui.column().classes("w-full h-full items-center justify-center mt-4"):
41-
ModelEditorPanel().classes("no-shadow min-w-[600px]")
41+
ModelEditorPanel().classes(
42+
"shadow-2xl dark:shadow-none min-w-[700px] max-w-[800px]"
43+
)
4244

43-
ModelPanel()
44-
ProjectConfigPanel()
45+
ModelPanel().classes("shadow-xl dark:shadow-none")
46+
ProjectConfigPanel().classes("shadow-xl dark:shadow-none")
4547

4648

4749
def run_ui(reload: bool) -> None:

fastapi_forge/frontend/panels/model_editor_panel.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ def __init__(self):
2323
self.visible = False
2424

2525
state.select_model_fn = self.set_selected_model
26+
state.deselect_model_fn = self.deselect_model
27+
state.render_model_editor_fn = self.refresh
2628

2729
self.add_field_modal: AddFieldModal = AddFieldModal(
2830
on_add_field=self._handle_modal_add_field,
@@ -298,6 +300,10 @@ def _validate_field_input(
298300
return False
299301
return True
300302

303+
def refresh(self) -> None:
304+
self._refresh_table(state.selected_model.fields)
305+
self._refresh_relationship_table(state.selected_model.relationships)
306+
301307
def _refresh_table(self, fields: list[ModelField]) -> None:
302308
if state.selected_model is None:
303309
return
@@ -513,3 +519,6 @@ def set_selected_model(self, model: Model) -> None:
513519
self._refresh_table(model.fields)
514520
self._refresh_relationship_table(model.relationships)
515521
self.visible = True
522+
523+
def deselect_model(self) -> None:
524+
self.visible = False

fastapi_forge/frontend/panels/model_panel.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from pydantic import ValidationError
55

66
from fastapi_forge.frontend import ModelCreate, ModelRow
7+
from fastapi_forge.frontend.constants import SELECTED_MODEL_TEXT_COLOR
78
from fastapi_forge.frontend.notifications import notify_validation_error
89
from fastapi_forge.frontend.state import state
910
from fastapi_forge.project_io import ProjectExporter
@@ -12,7 +13,6 @@
1213
class ModelPanel(ui.left_drawer):
1314
def __init__(self):
1415
super().__init__(value=True, elevated=False, bottom_corner=True)
15-
self.classes("border-right[1px]")
1616

1717
state.render_models_fn = self._render_models
1818

@@ -58,9 +58,11 @@ def _render_models(self) -> None:
5858

5959
with self.model_list:
6060
for model in state.models:
61-
is_auth_user = model.name == "auth_user"
62-
color = "text-green-500" if is_auth_user else None
6361
ModelRow(
6462
model,
65-
color=color,
63+
color=(
64+
SELECTED_MODEL_TEXT_COLOR
65+
if model == state.selected_model
66+
else None
67+
),
6668
)

fastapi_forge/frontend/state.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ class ProjectState(BaseModel):
2020
selected_relation: ModelRelationship | None = None
2121

2222
render_models_fn: Callable | None = None
23+
render_model_editor_fn: Callable | None = None
2324
select_model_fn: Callable | None = None
25+
deselect_model_fn: Callable | None = None
2426

2527
project_name: str = ""
2628
use_postgres: bool = False
@@ -70,16 +72,22 @@ def add_model(self, model_name: str) -> None:
7072
n.notify_validation_error(exc)
7173

7274
def delete_model(self, model: Model) -> None:
73-
if model not in self.models:
75+
if (
76+
model not in self.models
77+
or self.deselect_model_fn is None
78+
or self.render_models_fn is None
79+
):
7480
ui.notify("Something went wrong...", type="warning")
7581
return
82+
7683
self.models.remove(model)
77-
if self.selected_model == model:
78-
self.selected_model = None
79-
if self.render_models_fn:
80-
self.render_models_fn()
84+
self.deselect_model_fn()
85+
self.render_models_fn()
8186

8287
def update_model_name(self, model: Model, new_name: str) -> None:
88+
if model.name == new_name:
89+
return
90+
8391
if any(m.name == new_name for m in self.models if m != model):
8492
n.notify_model_exists(new_name)
8593
return
@@ -88,16 +96,31 @@ def update_model_name(self, model: Model, new_name: str) -> None:
8896
model.name = new_name
8997
self._update_relationships_for_rename(old_name, new_name)
9098

99+
if self.select_model_fn and model == self.selected_model:
100+
self.select_model_fn(model)
101+
91102
if self.render_models_fn:
92103
self.render_models_fn()
93104

105+
self.render_model_editor_fn()
106+
94107
def select_model(self, model: Model) -> None:
95-
if self.select_model_fn is None:
108+
print("selecting")
109+
if (
110+
self.select_model_fn is None
111+
or self.render_models_fn is None
112+
or self.deselect_model_fn is None
113+
):
96114
n.notify_something_went_wrong()
97115
return
98116
self.selected_model = model
99117
self.select_model_fn(model)
100118

119+
if model not in self.models:
120+
self.deselect_model_fn()
121+
122+
self.render_models_fn()
123+
101124
def get_project_spec(self) -> ProjectSpec:
102125
return ProjectSpec(
103126
project_name=self.project_name,

fastapi_forge/template/hooks/post_gen_project.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ def _get_delete_flagged() -> tuple[list[str], list[str]]:
5555
def delete_empty_init_folders(root_dir: str = "src") -> None:
5656
"""Delete folders that only contain empty __init__.py files."""
5757
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=False):
58-
# Skip the root directory itself
5958
if dirpath == root_dir:
6059
continue
6160

@@ -69,10 +68,6 @@ def delete_empty_init_folders(root_dir: str = "src") -> None:
6968
line.strip() and not line.strip().startswith("#")
7069
for line in content.splitlines()
7170
)
72-
if "__all__ = []" in content:
73-
print(45747457745)
74-
else:
75-
print(123123123)
7671
if not has_code:
7772
os.remove(init_file)
7873
os.rmdir(dirpath)
@@ -108,4 +103,4 @@ def cleanup():
108103
uv_init()
109104
make_env()
110105
lint()
111-
git_init()
106+
# git_init()

0 commit comments

Comments
 (0)