Add floating top navigation for workspace dashboards
This commit is contained in:
@@ -101,8 +101,25 @@
|
||||
{% set domain_context = get_domain_context(request) %}
|
||||
{% set is_system_admin_user = full_auth and ("System Admin" in ui_roles) %}
|
||||
{% set can_manage_local_storage_agent = full_auth and can_view_documents(current_user, ui_perms, ui_roles) and can_upload_documents(current_user, ui_perms, ui_roles) and (ui_roles|select("in", ["Firm Admin", "Partner", "Branch Manager"])|list|length > 0) %}
|
||||
{% set clean_workspace_paths = [
|
||||
'/system-admin/dashboard',
|
||||
'/firm-admin/dashboard',
|
||||
'/partner/dashboard',
|
||||
'/manager/dashboard',
|
||||
'/employee/dashboard',
|
||||
'/client/dashboard',
|
||||
'/consultant/dashboard',
|
||||
'/workspaces'
|
||||
] %}
|
||||
{% set clean_nav_state = namespace(enabled=False) %}
|
||||
{% for clean_path in clean_workspace_paths %}
|
||||
{% if current_path.startswith(clean_path) %}{% set clean_nav_state.enabled = True %}{% endif %}
|
||||
{% endfor %}
|
||||
{% set use_clean_top_nav = full_auth and clean_nav_state.enabled %}
|
||||
|
||||
<div class="min-h-screen lg:grid lg:grid-cols-[260px_minmax(0,1fr)]">
|
||||
|
||||
<div class="min-h-screen {% if not use_clean_top_nav %}lg:grid lg:grid-cols-[260px_minmax(0,1fr)]{% endif %}">
|
||||
{% if not use_clean_top_nav %}
|
||||
<aside class="border-b border-slate-200 bg-slate-900 text-slate-100 lg:min-h-screen lg:border-b-0 lg:border-r lg:border-slate-800">
|
||||
<div class="flex items-center gap-3 px-5 py-5">
|
||||
{% if firm_branding.logo_url %}<img src="{{ firm_branding.logo_url }}" alt="{{ current_firm_name }} logo" class="h-11 w-11 rounded-2xl bg-white object-contain p-1 shadow-soft" />{% else %}<div class="flex h-11 w-11 items-center justify-center rounded-2xl bg-brand-500 font-bold text-white shadow-soft">{{ (current_firm_name[:2] if current_firm_name else 'AF')|upper }}</div>{% endif %}
|
||||
@@ -386,7 +403,12 @@
|
||||
{% endif %}
|
||||
</aside>
|
||||
|
||||
{% endif %}
|
||||
|
||||
<div class="min-h-screen">
|
||||
{% if use_clean_top_nav %}
|
||||
{% include "ui/templates/components/top_workspace_bar.html" %}
|
||||
{% else %}
|
||||
<header class="border-b border-slate-200 bg-white/90 backdrop-blur">
|
||||
<div class="mx-auto max-w-7xl px-4 py-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
@@ -482,6 +504,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</header>
|
||||
{% endif %}
|
||||
|
||||
<main class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
|
||||
{% if flash %}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<header class="sticky top-0 z-40 border-b border-slate-200/70 bg-slate-100/85 backdrop-blur-xl">
|
||||
<div class="mx-auto max-w-[1500px] px-4 py-3 sm:px-6 lg:px-8">
|
||||
<div class="rounded-3xl border border-slate-200 bg-white/95 px-4 py-3 shadow-soft">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<a href="/workspaces" class="flex min-w-[220px] items-center gap-3 rounded-2xl px-2 py-1 transition hover:bg-slate-50">
|
||||
{% if firm_branding.logo_url %}
|
||||
<img src="{{ firm_branding.logo_url }}" alt="{{ current_firm_name }} logo" class="h-11 w-11 rounded-2xl border border-slate-100 bg-white object-contain p-1 shadow-soft" />
|
||||
{% else %}
|
||||
<div class="flex h-11 w-11 items-center justify-center rounded-2xl bg-brand-600 text-sm font-bold text-white shadow-soft">{{ (current_firm_name[:2] if current_firm_name else 'AF')|upper }}</div>
|
||||
{% endif %}
|
||||
<div class="min-w-0">
|
||||
<div class="truncate text-sm font-bold text-slate-900">{{ current_firm_name }}</div>
|
||||
<div class="truncate text-xs text-slate-500">{{ current_branch_name if active_branch_id else 'All Branches' }}{% if active_financial_year %} • FY {{ active_financial_year }}{% endif %}</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="flex min-w-0 flex-1 flex-wrap items-center gap-2">
|
||||
{% include "ui/templates/components/workspace_switcher.html" %}
|
||||
|
||||
{% if full_auth and (can_switch_service_tenant(current_user, ui_perms, ui_roles) or can_switch_service_branch(current_user, ui_perms, ui_roles) or can_switch_employee_tenant(current_user, ui_perms, ui_roles) or can_switch_employee_branch(current_user, ui_perms, ui_roles) or can_view_settings(current_user, ui_perms, ui_roles)) %}
|
||||
{% if can_switch_service_tenant(current_user, ui_perms, ui_roles) or can_switch_employee_tenant(current_user, ui_perms, ui_roles) %}
|
||||
{% set context_tenants = get_context_tenants(request, current_user, ui_perms, ui_roles) %}
|
||||
<select title="Active Audit Firm" onchange="if(this.value){window.location.href=this.value;}" class="max-w-[210px] rounded-2xl border border-slate-200 bg-white px-3 py-2 text-xs font-semibold text-slate-700 shadow-sm outline-none hover:border-brand-200 focus:ring-2 focus:ring-brand-100">
|
||||
{% for tenant in context_tenants %}
|
||||
<option value="/system-settings/context/tenant/{{ tenant.id }}" {% if tenant.id == active_tenant_id %}selected{% endif %}>{{ tenant.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
|
||||
{% if can_switch_service_branch(current_user, ui_perms, ui_roles) or can_switch_employee_branch(current_user, ui_perms, ui_roles) %}
|
||||
{% set context_branches = get_context_branches(request, current_user, ui_perms, ui_roles) %}
|
||||
<select title="Active Branch" onchange="if(this.value){window.location.href=this.value;}" class="max-w-[190px] rounded-2xl border border-slate-200 bg-white px-3 py-2 text-xs font-semibold text-slate-700 shadow-sm outline-none hover:border-brand-200 focus:ring-2 focus:ring-brand-100">
|
||||
<option value="/system-settings/context/branch/0" {% if not active_branch_id %}selected{% endif %}>All Branches</option>
|
||||
{% for branch in context_branches %}
|
||||
<option value="/system-settings/context/branch/{{ branch.id }}" {% if branch.id == active_branch_id %}selected{% endif %}>{{ branch.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
|
||||
{% if can_view_settings(current_user, ui_perms, ui_roles) %}
|
||||
{% set context_financial_years = get_context_financial_years(request, current_user, ui_perms, ui_roles) %}
|
||||
<select title="Active Financial Year" data-testid="active-fy-select" aria-label="Active Financial Year" onchange="if(this.value){window.location.href=this.value;}" class="max-w-[170px] rounded-2xl border border-slate-200 bg-white px-3 py-2 text-xs font-semibold text-slate-700 shadow-sm outline-none hover:border-brand-200 focus:ring-2 focus:ring-brand-100">
|
||||
{% for fy in context_financial_years %}
|
||||
<option value="/system-settings/context/financial-year/{{ fy.year_code }}" {% if fy.year_code == active_financial_year %}selected{% endif %}>FY {{ fy.year_code }}{% if fy.is_current %} (Current){% endif %}{% if fy.is_locked %} - Locked{% endif %}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
<a href="/alerts" class="relative inline-flex h-10 items-center justify-center rounded-2xl border border-slate-200 bg-white px-3 text-xs font-semibold text-slate-700 shadow-sm hover:border-brand-200 hover:text-brand-700">
|
||||
Alerts
|
||||
{% if unread_alert_count %}<span class="ml-2 rounded-full bg-brand-600 px-2 py-0.5 text-[10px] font-bold text-white">{{ unread_alert_count }}</span>{% endif %}
|
||||
</a>
|
||||
|
||||
<details class="group relative">
|
||||
<summary class="flex cursor-pointer list-none items-center gap-2 rounded-2xl border border-slate-200 bg-white px-2 py-2 shadow-sm hover:border-brand-200">
|
||||
{% if current_user_photo_url %}
|
||||
<img src="{{ current_user_photo_url }}" alt="Profile photo" class="h-8 w-8 rounded-xl object-cover" />
|
||||
{% else %}
|
||||
<div class="flex h-8 w-8 items-center justify-center rounded-xl bg-brand-600 text-xs font-bold text-white">{{ current_user_initials }}</div>
|
||||
{% endif %}
|
||||
<div class="hidden text-left sm:block">
|
||||
<div class="max-w-[150px] truncate text-xs font-bold text-slate-900">{{ current_user.full_name or current_user.email }}</div>
|
||||
<div class="max-w-[150px] truncate text-[11px] text-slate-500">{{ current_user.email }}</div>
|
||||
</div>
|
||||
</summary>
|
||||
<div class="absolute right-0 z-50 mt-2 w-56 rounded-2xl border border-slate-200 bg-white p-2 text-sm shadow-card">
|
||||
{% if "Consultant" in ui_roles %}
|
||||
<a class="block rounded-xl px-3 py-2 text-slate-700 hover:bg-slate-50" href="/consultant/profile">My Profile</a>
|
||||
{% elif "Client" in ui_roles %}
|
||||
<a class="block rounded-xl px-3 py-2 text-slate-700 hover:bg-slate-50" href="/client/profile">My Profile</a>
|
||||
{% else %}
|
||||
<a class="block rounded-xl px-3 py-2 text-slate-700 hover:bg-slate-50" href="/employee/profile">My Profile</a>
|
||||
{% endif %}
|
||||
<a class="block rounded-xl px-3 py-2 text-slate-700 hover:bg-slate-50" href="/change-password">Change Password</a>
|
||||
<a class="block rounded-xl px-3 py-2 text-red-600 hover:bg-red-50" href="/logout">Logout</a>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -3,19 +3,18 @@
|
||||
{% set perms = ui_perms if ui_perms is defined else [] %}
|
||||
{% set current = current_path if current_path is defined else request.url.path %}
|
||||
{% set can_employee = ('Staff' in roles) or ('Employee' in roles) or ('employees.ess.view' in perms) or ('employees.work.view_self' in perms) or ('employees.attendance.view_self' in perms) or ('employees.leave.view_self' in perms) or ('employees.documents.view_self' in perms) or ('employees.payroll.view_self' in perms) %}
|
||||
<div class="mt-2 flex flex-wrap justify-end gap-2">
|
||||
<div class="flex flex-wrap items-center justify-end gap-2">
|
||||
<label class="sr-only" for="workspace_switcher">Workspace</label>
|
||||
<select id="workspace_switcher" onchange="if(this.value){window.location.href=this.value;}" class="min-w-[230px] max-w-xs rounded-xl border border-brand-200 bg-brand-50 px-3 py-1.5 text-xs font-semibold text-brand-900 shadow-sm outline-none transition hover:bg-brand-100 focus:border-brand-400 focus:ring-2 focus:ring-brand-200">
|
||||
<select id="workspace_switcher" onchange="if(this.value){window.location.href=this.value;}" class="min-w-[210px] max-w-xs rounded-2xl border border-brand-200 bg-brand-50 px-3 py-2 text-xs font-semibold text-brand-900 shadow-sm outline-none transition hover:bg-brand-100 focus:border-brand-400 focus:ring-2 focus:ring-brand-200">
|
||||
<option value="/workspaces" {% if current.startswith('/workspaces') %}selected{% endif %}>Workspace Centre</option>
|
||||
{% if 'System Admin' in roles %}<option value="/system-admin/dashboard" {% if current.startswith('/system-admin') %}selected{% endif %}>System Admin - Platform Control</option>{% endif %}
|
||||
{% if 'System Admin' in roles %}<option value="/system-admin/dashboard" {% if current.startswith('/system-admin') %}selected{% endif %}>System Admin</option>{% endif %}
|
||||
{% if 'Partner' in roles %}<option value="/partner/dashboard" {% if current.startswith('/partner') %}selected{% endif %}>Partner Operations</option>{% endif %}
|
||||
{% if 'Firm Admin' in roles %}<option value="/firm-admin/dashboard" {% if current.startswith('/firm-admin') %}selected{% endif %}>Firm Administration</option>{% endif %}
|
||||
{% if 'Manager' in roles or 'Branch Manager' in roles %}<option value="/manager/dashboard" {% if current.startswith('/manager') %}selected{% endif %}>Manager Workspace</option>{% endif %}
|
||||
{% if can_employee %}<option value="/employee/dashboard" {% if current.startswith('/employee') or current.startswith('/employees') %}selected{% endif %}>Employee Portal</option>{% endif %}
|
||||
{% if 'Client' in roles %}<option value="/client/dashboard" {% if current.startswith('/client') %}selected{% endif %}>Client Portal</option>{% endif %}
|
||||
{% if 'Consultant' in roles %}<option value="/consultant/dashboard" {% if current.startswith('/consultant') %}selected{% endif %}>Consultant Workspace</option>{% endif %}
|
||||
<option value="/reports" {% if current.startswith('/reports') %}selected{% endif %}>Reports Centre</option>
|
||||
</select>
|
||||
<a href="/workspaces" class="inline-flex items-center rounded-xl border border-slate-200 bg-white px-3 py-1.5 text-xs font-semibold text-slate-600 shadow-sm hover:border-brand-200 hover:text-brand-700">All workspaces</a>
|
||||
<a href="/workspaces" class="inline-flex items-center rounded-2xl border border-slate-200 bg-white px-3 py-2 text-xs font-semibold text-slate-600 shadow-sm hover:border-brand-200 hover:text-brand-700">All workspaces</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user