starting admin work
This commit is contained in:
@ -26,6 +26,8 @@ services:
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
networks:
|
||||
- appnet
|
||||
|
||||
db:
|
||||
image: mysql:8
|
||||
@ -39,12 +41,18 @@ services:
|
||||
- "42000:3306"
|
||||
volumes:
|
||||
- ./mysql_data:/var/lib/mysql
|
||||
entrypoint: ["sh", "-c", "mkdir -p /var/lib/mysql && chown -R 1000:998 /var/lib/mysql && chmod -R 770 /var/lib/mysql && exec docker-entrypoint.sh mysqld"]
|
||||
entrypoint: >
|
||||
sh -c "mkdir -p /var/lib/mysql &&
|
||||
chown -R 1000:998 /var/lib/mysql &&
|
||||
chmod -R 770 /var/lib/mysql &&
|
||||
exec docker-entrypoint.sh mysqld"
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- appnet
|
||||
|
||||
adminer:
|
||||
image: adminer
|
||||
@ -55,6 +63,8 @@ services:
|
||||
- ADMINER_DEFAULT_SERVER=db
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- appnet
|
||||
|
||||
neo4j:
|
||||
image: neo4j:5.18
|
||||
@ -66,6 +76,12 @@ services:
|
||||
- NEO4J_AUTH=neo4j/your_secure_password
|
||||
volumes:
|
||||
- neo4j_data:/data
|
||||
networks:
|
||||
- appnet
|
||||
|
||||
volumes:
|
||||
neo4j_data:
|
||||
|
||||
networks:
|
||||
appnet:
|
||||
driver: bridge
|
||||
|
28
migrations/versions/19e2a1b15b5e_auto_migrate.py
Normal file
28
migrations/versions/19e2a1b15b5e_auto_migrate.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""auto-migrate
|
||||
|
||||
Revision ID: 19e2a1b15b5e
|
||||
Revises: f00a9585a348
|
||||
Create Date: 2025-06-27 22:59:54.162560
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '19e2a1b15b5e'
|
||||
down_revision = 'f00a9585a348'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
pass
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
pass
|
||||
# ### end Alembic commands ###
|
28
migrations/versions/85b7ca21ec19_auto_migrate.py
Normal file
28
migrations/versions/85b7ca21ec19_auto_migrate.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""auto-migrate
|
||||
|
||||
Revision ID: 85b7ca21ec19
|
||||
Revises: 8c1e8db7b3cb
|
||||
Create Date: 2025-06-27 23:34:04.669553
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '85b7ca21ec19'
|
||||
down_revision = '8c1e8db7b3cb'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
pass
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
pass
|
||||
# ### end Alembic commands ###
|
28
migrations/versions/8c1e8db7b3cb_auto_migrate.py
Normal file
28
migrations/versions/8c1e8db7b3cb_auto_migrate.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""auto-migrate
|
||||
|
||||
Revision ID: 8c1e8db7b3cb
|
||||
Revises: 19e2a1b15b5e
|
||||
Create Date: 2025-06-27 23:21:19.031362
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '8c1e8db7b3cb'
|
||||
down_revision = '19e2a1b15b5e'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
pass
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
pass
|
||||
# ### end Alembic commands ###
|
@ -16,107 +16,123 @@
|
||||
|
||||
<h2 class="mb-4">View Entries</h2>
|
||||
|
||||
{# ── Import / Export, Stats, Filters & View Toggle ─────────────────────── #}
|
||||
<div class="mb-3 d-flex flex-wrap justify-content-between align-items-center">
|
||||
<!-- Left: import/export & stats toggle -->
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<button class="btn btn-primary me-2" data-bs-toggle="modal" data-bs-target="#importModal">
|
||||
Import CSV
|
||||
</button>
|
||||
<a href="{{ url_for('utility.export_data') }}" class="btn btn-secondary me-2">
|
||||
Export My Data
|
||||
</a>
|
||||
<button
|
||||
class="btn btn-secondary me-2 d-inline-block d-md-none"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#statsModal">
|
||||
Stats
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary me-2 d-none d-md-inline-block"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#statsBox"
|
||||
aria-expanded="false"
|
||||
aria-controls="statsBox"
|
||||
id="statsToggle">
|
||||
Stats <i class="bi bi-chevron-down"></i>
|
||||
</button>
|
||||
{# ── Import / Export / Stats & Filters / View Toggle ───────────────────── #}
|
||||
<div class="mb-3 d-flex flex-wrap justify-content-between align-items-start">
|
||||
{# LEFT: Import/Export + Stats toggles #}
|
||||
<div class="btn-toolbar mb-2" role="toolbar">
|
||||
<div class="btn-group me-2" role="group">
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#importModal">
|
||||
Import CSV
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="btn-group me-2" role="group">
|
||||
<a href="{{ url_for('utility.export_data') }}" class="btn btn-secondary">
|
||||
Export My Data
|
||||
</a>
|
||||
<button
|
||||
class="btn btn-secondary d-inline-block d-md-none"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#statsModal">
|
||||
Stats
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary d-none d-md-inline-block"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#statsBox"
|
||||
aria-expanded="false"
|
||||
aria-controls="statsBox"
|
||||
id="statsToggle">
|
||||
Stats <i class="bi bi-chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right: filter form + view toggle -->
|
||||
{# RIGHT: filter form + view toggle #}
|
||||
<form
|
||||
method="get"
|
||||
action="{{ url_for('plant.index') }}"
|
||||
class="d-flex flex-wrap align-items-center mb-2"
|
||||
class="row gx-2 gy-2 align-items-center mb-2"
|
||||
>
|
||||
<div class="input-group me-2" style="min-width:200px;">
|
||||
<span class="input-group-text">Search</span>
|
||||
<input
|
||||
type="search"
|
||||
name="q"
|
||||
value="{{ q }}"
|
||||
class="form-control"
|
||||
placeholder="by name…"
|
||||
/>
|
||||
<div class="col-auto">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Search</span>
|
||||
<input
|
||||
type="search"
|
||||
name="q"
|
||||
value="{{ q }}"
|
||||
class="form-control"
|
||||
placeholder="by name…"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<select
|
||||
name="type"
|
||||
class="form-select me-2"
|
||||
style="min-width:140px;"
|
||||
onchange="this.form.submit()"
|
||||
>
|
||||
<option value="">All Types</option>
|
||||
{% for t in plant_types %}
|
||||
<option
|
||||
value="{{ t|lower }}"
|
||||
{% if t|lower == type_filter %}selected{% endif %}
|
||||
>{{ t }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="col-auto">
|
||||
<select
|
||||
name="type"
|
||||
class="form-select"
|
||||
style="min-width:140px;"
|
||||
onchange="this.form.submit()"
|
||||
>
|
||||
<option value="">All Types</option>
|
||||
{% for t in plant_types %}
|
||||
<option
|
||||
value="{{ t|lower }}"
|
||||
{% if t|lower == type_filter %}selected{% endif %}
|
||||
>{{ t }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<select
|
||||
name="per_page"
|
||||
class="form-select me-2"
|
||||
style="min-width:140px;"
|
||||
onchange="this.form.submit()"
|
||||
>
|
||||
{% for size in [6,12,18,24] %}
|
||||
<option value="{{ size }}" {% if per_page == size %}selected{% endif %}>
|
||||
{{ size }} per page
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="col-auto">
|
||||
<select
|
||||
name="per_page"
|
||||
class="form-select"
|
||||
style="min-width:140px;"
|
||||
onchange="this.form.submit()"
|
||||
>
|
||||
{% for size in [6,12,18,24] %}
|
||||
<option value="{{ size }}" {% if per_page == size %}selected{% endif %}>
|
||||
{{ size }} per page
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{# keep the current view so Apply doesn’t reset it #}
|
||||
{# preserve current view so Apply doesn’t reset it #}
|
||||
<input type="hidden" name="view" value="{{ view_mode }}" />
|
||||
|
||||
<button type="submit" class="btn btn-primary me-2">Apply</button>
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary">Apply</button>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" role="group" aria-label="View mode">
|
||||
<a
|
||||
href="{{ url_for('plant.index',
|
||||
page=pagination.page,
|
||||
per_page=per_page,
|
||||
q=q,
|
||||
type=type_filter,
|
||||
view='grid'
|
||||
) }}"
|
||||
class="btn btn-outline-secondary {% if view_mode=='grid' %}active{% endif %}"
|
||||
title="Card View"
|
||||
><i class="bi bi-grid-3x3-gap-fill"></i></a>
|
||||
|
||||
<a
|
||||
href="{{ url_for('plant.index',
|
||||
page=pagination.page,
|
||||
per_page=per_page,
|
||||
q=q,
|
||||
type=type_filter,
|
||||
view='list'
|
||||
) }}"
|
||||
class="btn btn-outline-secondary {% if view_mode=='list' %}active{% endif %}"
|
||||
title="List View"
|
||||
><i class="bi bi-list-ul"></i></a>
|
||||
<div class="col-auto">
|
||||
<div class="btn-group" role="group" aria-label="View mode">
|
||||
<a
|
||||
href="{{ url_for('plant.index',
|
||||
page=pagination.page,
|
||||
per_page=per_page,
|
||||
q=q,
|
||||
type=type_filter,
|
||||
view='grid') }}"
|
||||
class="btn btn-outline-secondary {% if view_mode=='grid' %}active{% endif %}"
|
||||
title="Card View"
|
||||
>
|
||||
<i class="bi bi-grid-3x3-gap-fill"></i>
|
||||
</a>
|
||||
<a
|
||||
href="{{ url_for('plant.index',
|
||||
page=pagination.page,
|
||||
per_page=per_page,
|
||||
q=q,
|
||||
type=type_filter,
|
||||
view='list') }}"
|
||||
class="btn btn-outline-secondary {% if view_mode=='list' %}active{% endif %}"
|
||||
title="List View"
|
||||
>
|
||||
<i class="bi bi-list-ul"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user