Responsive main menu added, AGENTS updated.
All checks were successful
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/labhelper) (push) Successful in 15s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/labhelper-data-loader) (push) Successful in 4s
All checks were successful
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/labhelper) (push) Successful in 15s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/labhelper-data-loader) (push) Successful in 4s
This commit is contained in:
10
AGENTS.md
10
AGENTS.md
@@ -214,9 +214,10 @@ labhelper/
|
|||||||
│ │ ├── add_things.html # Form to add multiple things
|
│ │ ├── add_things.html # Form to add multiple things
|
||||||
│ │ ├── box_detail.html # Box contents view
|
│ │ ├── box_detail.html # Box contents view
|
||||||
│ │ ├── box_management.html # Box/BoxType CRUD management
|
│ │ ├── box_management.html # Box/BoxType CRUD management
|
||||||
|
│ │ ├── edit_thing.html # Edit thing page (name, description, picture, tags, files, links)
|
||||||
│ │ ├── index.html # Home page with boxes and tags
|
│ │ ├── index.html # Home page with boxes and tags
|
||||||
│ │ ├── search.html # Search page with AJAX
|
│ │ ├── search.html # Search page with AJAX
|
||||||
│ │ └── thing_detail.html # Thing details view with tags
|
│ │ └── thing_detail.html # Read-only thing details view
|
||||||
│ ├── templatetags/
|
│ ├── templatetags/
|
||||||
│ │ └── dict_extras.py # Custom template filters: get_item, render_markdown, truncate_markdown
|
│ │ └── dict_extras.py # Custom template filters: get_item, render_markdown, truncate_markdown
|
||||||
│ ├── admin.py # Admin configuration
|
│ ├── admin.py # Admin configuration
|
||||||
@@ -350,6 +351,7 @@ The project uses a base template system at `labhelper/templates/base.html`. All
|
|||||||
- Grid layouts with `repeat(auto-fill, minmax(250px, 1fr))`
|
- Grid layouts with `repeat(auto-fill, minmax(250px, 1fr))`
|
||||||
- Flexbox for component layouts
|
- Flexbox for component layouts
|
||||||
- Breakpoints handled by grid and flex-wrap
|
- Breakpoints handled by grid and flex-wrap
|
||||||
|
- **Navigation**: Responsive navbar with hamburger menu on mobile (≤768px) and full horizontal menu on desktop (≥769px)
|
||||||
|
|
||||||
### CSS Guidelines
|
### CSS Guidelines
|
||||||
|
|
||||||
@@ -384,7 +386,8 @@ The project uses a base template system at `labhelper/templates/base.html`. All
|
|||||||
| `edit_box` | `/box/<str:box_id>/edit/` | `edit_box` | Edit box |
|
| `edit_box` | `/box/<str:box_id>/edit/` | `edit_box` | Edit box |
|
||||||
| `delete_box` | `/box/<str:box_id>/delete/` | `delete_box` | Delete box |
|
| `delete_box` | `/box/<str:box_id>/delete/` | `delete_box` | Delete box |
|
||||||
| `box_detail` | `/box/<str:box_id>/` | `box_detail` | View box contents |
|
| `box_detail` | `/box/<str:box_id>/` | `box_detail` | View box contents |
|
||||||
| `thing_detail` | `/thing/<int:thing_id>/` | `thing_detail` | View/edit thing (move, picture, files, links, tags) |
|
| `thing_detail` | `/thing/<int:thing_id>/` | `thing_detail` | Read-only view of thing details |
|
||||||
|
| `edit_thing` | `/thing/<int:thing_id>/edit/` | `edit_thing` | Edit thing (name, description, picture, tags, files, links, move) |
|
||||||
| `add_things` | `/box/<str:box_id>/add/` | `add_things` | Add multiple things to a box |
|
| `add_things` | `/box/<str:box_id>/add/` | `add_things` | Add multiple things to a box |
|
||||||
| `search` | `/search/` | `search` | Search page |
|
| `search` | `/search/` | `search` | Search page |
|
||||||
| `search_api` | `/search/api/` | `search_api` | AJAX search endpoint |
|
| `search_api` | `/search/api/` | `search_api` | AJAX search endpoint |
|
||||||
@@ -482,7 +485,7 @@ The `Thing.description` field supports Markdown formatting with HTML sanitizatio
|
|||||||
|
|
||||||
| Form | Model | Purpose |
|
| Form | Model | Purpose |
|
||||||
|------|-------|---------|
|
|------|-------|---------|
|
||||||
| `ThingForm` | Thing | Add/edit a thing (name, description, picture, tags) |
|
| `ThingForm` | Thing | Add/edit a thing (name, description, picture) - tags managed separately |
|
||||||
| `ThingPictureForm` | Thing | Upload/change thing picture only |
|
| `ThingPictureForm` | Thing | Upload/change thing picture only |
|
||||||
| `ThingFileForm` | ThingFile | Add file attachment |
|
| `ThingFileForm` | ThingFile | Add file attachment |
|
||||||
| `ThingLinkForm` | ThingLink | Add link |
|
| `ThingLinkForm` | ThingLink | Add link |
|
||||||
@@ -547,6 +550,7 @@ Per `.gitignore`:
|
|||||||
5. **Templates in labhelper/templates/**: The base template and shared templates are in `labhelper/templates/`. App-specific templates remain in `app_name/templates/`.
|
5. **Templates in labhelper/templates/**: The base template and shared templates are in `labhelper/templates/`. App-specific templates remain in `app_name/templates/`.
|
||||||
6. **Use get_object_or_404** instead of bare `.get()` calls
|
6. **Use get_object_or_404** instead of bare `.get()` calls
|
||||||
7. **Never commit SECRET_KEY** - use environment variables in production
|
7. **Never commit SECRET_KEY** - use environment variables in production
|
||||||
|
8. **Be careful with process management**: Avoid blanket kills on ports (e.g., `lsof -ti:8000 | xargs kill -9`) as they can kill unintended processes like web browsers. Use specific process kills instead: `pkill -f "process_name"`
|
||||||
|
|
||||||
## Deployment Commands
|
## Deployment Commands
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ spec:
|
|||||||
mountPath: /data
|
mountPath: /data
|
||||||
containers:
|
containers:
|
||||||
- name: web
|
- name: web
|
||||||
image: git.baumann.gr/adebaumann/labhelper:0.051
|
image: git.baumann.gr/adebaumann/labhelper:0.052
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
|
|||||||
@@ -50,13 +50,31 @@
|
|||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navbar-toggle {
|
||||||
|
display: none;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #555;
|
||||||
|
font-size: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-toggle:hover {
|
||||||
|
background: #667eea;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar-nav {
|
.navbar-nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-nav a {
|
.navbar-nav a,
|
||||||
|
.navbar-nav form {
|
||||||
color: #555;
|
color: #555;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@@ -81,6 +99,68 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navbar-nav button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #555;
|
||||||
|
font: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.navbar {
|
||||||
|
padding: 15px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-toggle {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav {
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav a,
|
||||||
|
.navbar-nav form {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav a:first-child,
|
||||||
|
.navbar-nav form:first-child {
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav a:last-child,
|
||||||
|
.navbar-nav form:last-child {
|
||||||
|
border-radius: 0 0 8px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav button {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
@@ -226,15 +306,18 @@
|
|||||||
<i class="fas fa-flask"></i>
|
<i class="fas fa-flask"></i>
|
||||||
LabHelper
|
LabHelper
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-nav">
|
<button class="navbar-toggle" id="navbar-toggle">
|
||||||
|
<i class="fas fa-bars"></i>
|
||||||
|
</button>
|
||||||
|
<div class="navbar-nav" id="navbar-nav">
|
||||||
<a href="/"><i class="fas fa-home"></i> Home</a>
|
<a href="/"><i class="fas fa-home"></i> Home</a>
|
||||||
<a href="/box-management/"><i class="fas fa-boxes"></i> Box Management</a>
|
<a href="/box-management/"><i class="fas fa-boxes"></i> Box Management</a>
|
||||||
<a href="/search/"><i class="fas fa-search"></i> Search</a>
|
<a href="/search/"><i class="fas fa-search"></i> Search</a>
|
||||||
<a href="/admin/"><i class="fas fa-cog"></i> Admin</a>
|
<a href="/admin/"><i class="fas fa-cog"></i> Admin</a>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<form method="post" action="{% url 'logout' %}" style="display: inline;">
|
<form method="post" action="{% url 'logout' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<button type="submit" style="background: none; border: none; color: #555; font: inherit; cursor: pointer; padding: 8px 16px; border-radius: 8px; transition: all 0.3s ease; display: inline-flex; align-items: center; gap: 8px;">
|
<button type="submit">
|
||||||
<i class="fas fa-sign-out-alt"></i> Logout ({{ user.username }})
|
<i class="fas fa-sign-out-alt"></i> Logout ({{ user.username }})
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
@@ -255,5 +338,18 @@
|
|||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
{% block extra_js %}{% endblock %}
|
{% block extra_js %}{% endblock %}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#navbar-toggle').on('click', function() {
|
||||||
|
$('#navbar-nav').toggleClass('active');
|
||||||
|
const icon = $(this).find('i');
|
||||||
|
if ($('#navbar-nav').hasClass('active')) {
|
||||||
|
icon.removeClass('fa-bars').addClass('fa-times');
|
||||||
|
} else {
|
||||||
|
icon.removeClass('fa-times').addClass('fa-bars');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user