fix: light refactor, add code quality tooling

This commit is contained in:
Tyler Matteson 2025-07-25 15:12:15 -04:00
parent 4e60535f86
commit 0e9fdcb0a3
10 changed files with 127 additions and 1689 deletions

View file

@ -63,6 +63,26 @@ repos:
dashboard/public/js/lib/.*
)$
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
additional_dependencies:
- tomli
args: ['-L', '']
- repo: https://github.com/agritheory/test_utils/
rev: v0.17.0
hooks:
- id: update_pre_commit_config
- id: validate_customizations
always_run: true
- id: validate_copyright
files: '\.(js|ts|py|md)$'
args: ['--app', 'dashboard']
- id: clean_customized_doctypes
args: ['--app', 'dashboard']
ci:
autoupdate_schedule: weekly
skip: []

View file

@ -46,7 +46,7 @@
"modified_by": "Administrator",
"module": "Dashboard",
"name": "Dashboard Icon",
"owner": "adam@seahavenind.com",
"owner": "Administrator",
"permissions": [
{
"create": 1,

View file

@ -0,0 +1,11 @@
# Copyright (c) 2025, Adam Moussa and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
from frappe.website.utils import clear_cache
class DashboardIcon(Document):
def validate(self):
clear_cache("/dashboard")

View file

@ -1 +0,0 @@
[]

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,6 @@
# Copyright (c) 2025, Adam Moussa and contributors
# For license information, please see license.txt
app_name = "dashboard"
app_title = "Dashboard"
app_publisher = "Adam Moussa"
@ -243,23 +246,5 @@ app_license = "mit"
# }
fixtures = [
{
"dt": "Custom Field",
"filters": [
["dt", "in", ["Dashboard Icon"]]
]
},
{
"dt": "Property Setter"
},
"Dashboard Icon" # export the entire custom DocType
"Dashboard Icon",
]
doc_events = {
"Dashboard Icon": {
"after_insert": "dashboard.utils.cache.clear_dashboard_cache",
"on_update": "dashboard.utils.cache.clear_dashboard_cache",
"on_trash": "dashboard.utils.cache.clear_dashboard_cache",
}
}

View file

@ -0,0 +1,3 @@
# Copyright (c) 2025, Adam Moussa and contributors
# For license information, please see license.txt

View file

@ -1,57 +1,74 @@
<div class="portal-wrapper">
<h1>Sea Haven Portal</h1>
<div class="grid">
{% for icon in icons %}
<a href="{{ icon.url }}" class="app-link">
<i class="fas {{ icon.icon }}"></i>
<div class="app-label">{{ icon.label }}</div>
</a>
{% endfor %}
</div>
</div>
<style>
.portal-wrapper {
text-align: center;
padding: 40px;
font-family: "Segoe UI", sans-serif;
background-color: #f9f9f9;
}
h1 {
margin-bottom: 40px;
font-size: 2.5rem;
color: #333;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 30px;
max-width: 800px;
margin: 0 auto;
}
.app-link {
background: #fff;
padding: 30px 20px;
border-radius: 10px;
text-decoration: none;
color: #333;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
}
.app-link:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.app-link i {
font-size: 2.5rem;
margin-bottom: 10px;
color: #007bff;
}
.app-label {
font-size: 1rem;
font-weight: 600;
margin-top: 10px;
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
{% extends "templates/web.html" %}
{% block content %}
<div class="portal-wrapper">
<h1>Sea Haven Portal</h1>
<div class="grid">
{% for icon in icons %}
<a href="{{ icon.url }}" class="app-link">
<i class="fas {{ icon.icon }}"></i>
<div class="app-label">{{ icon.label }}</div>
</a>
{% endfor %}
</div>
</div>
<script>
window.csrf_token = '{{ csrf_token }}'
frappe.user = '{{ user }}'
</script>
{% endblock %}
{%- block style -%}
<style>
.portal-wrapper {
text-align: center;
padding: 40px;
font-family: "Segoe UI", sans-serif;
background-color: #f9f9f9;
}
h1 {
margin-bottom: 40px;
font-size: 2.5rem;
color: #333;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 30px;
max-width: 800px;
margin: 0 auto;
}
.app-link {
background: #fff;
padding: 30px 20px;
border-radius: 10px;
text-decoration: none;
color: #333;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
}
.app-link:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.app-link i {
font-size: 2.5rem;
margin-bottom: 10px;
color: #007bff;
}
.app-label {
font-size: 1rem;
font-weight: 600;
margin-top: 10px;
}
.web-footer {
display: none;
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
{% endblock %}

View file

@ -1,17 +1,22 @@
# Copyright (c) 2025, Adam Moussa and contributors
# For license information, please see license.txt
import frappe
no_cache = 1
def get_context(context):
user = frappe.session.user
user_roles = frappe.get_roles(user)
user = frappe.session.user
user_roles = frappe.get_roles(user)
icons = frappe.get_all("Dashboard Icon", fields=["label", "icon", "url", "role"])
visible_icons = []
icons = frappe.get_all("Dashboard Icon", fields=["label", "icon", "url", "role"])
print(icons)
visible_icons = []
for icon in icons:
if not icon.role or icon.role in user_roles:
visible_icons.append(icon)
for icon in icons:
if not icon.role or icon.role in user_roles:
visible_icons.append(icon)
context.icons = visible_icons
return context
context.icons = visible_icons
return context