295 lines
17 KiB
HTML
295 lines
17 KiB
HTML
|
|
{% macro stat(title, value, desc="", accent="") %}
|
||
|
|
<div class="stat">
|
||
|
|
<div class="stat-title">{{ title }}</div>
|
||
|
|
<div class="stat-value {% if accent %}text-{{ accent }}{% endif %}">{{ value }}</div>
|
||
|
|
{% if desc %}<div class="stat-desc">{{ desc }}</div>{% endif %}
|
||
|
|
</div>
|
||
|
|
{% endmacro stat %}
|
||
|
|
|
||
|
|
{% macro badge(text, kind="neutral") %}
|
||
|
|
<span class="badge badge-{{ kind }} badge-sm font-mono">{{ text }}</span>
|
||
|
|
{% endmacro badge %}
|
||
|
|
|
||
|
|
{% macro category_badge(cat) %}
|
||
|
|
{% if cat == "Read" %}
|
||
|
|
<span class="badge badge-info badge-xs">read</span>
|
||
|
|
{% elif cat == "Mutation" %}
|
||
|
|
<span class="badge badge-warning badge-xs">mutation</span>
|
||
|
|
{% elif cat == "Destructive" %}
|
||
|
|
<span class="badge badge-error badge-xs">destructive</span>
|
||
|
|
{% elif cat == "Admin" %}
|
||
|
|
<span class="badge badge-secondary badge-xs">admin</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge badge-ghost badge-xs">{{ cat }}</span>
|
||
|
|
{% endif %}
|
||
|
|
{% endmacro category_badge %}
|
||
|
|
|
||
|
|
{% macro outcome_badge(record) %}
|
||
|
|
{% if record.outcome.status == "ok" %}
|
||
|
|
<span class="badge badge-success badge-xs">ok</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge badge-error badge-xs">err {{ record.outcome.code }}</span>
|
||
|
|
{% endif %}
|
||
|
|
{% endmacro outcome_badge %}
|
||
|
|
|
||
|
|
{% macro server_status(status) %}
|
||
|
|
{% if status == "running" %}
|
||
|
|
<span class="badge badge-success badge-sm gap-1"><span class="inline-block w-1.5 h-1.5 rounded-full bg-success-content"></span>running</span>
|
||
|
|
{% elif status == "off" %}
|
||
|
|
<span class="badge badge-ghost badge-sm">off</span>
|
||
|
|
{% elif status == "not_provisioned" %}
|
||
|
|
<span class="badge badge-ghost badge-sm text-base-content/30">declared</span>
|
||
|
|
{% elif status == "initializing" or status == "starting" %}
|
||
|
|
<span class="badge badge-warning badge-sm">{{ status }}</span>
|
||
|
|
{% elif status %}
|
||
|
|
<span class="badge badge-error badge-sm">{{ status }}</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="text-base-content/20">—</span>
|
||
|
|
{% endif %}
|
||
|
|
{% endmacro server_status %}
|
||
|
|
|
||
|
|
{% macro ws_tabs(ws_name, active, ws_envs, ws_has_clusters=false, ws_has_workflows=false, current_env="") %}
|
||
|
|
{#
|
||
|
|
Row 1 (.ws-nav): Overview | Infras▼ | [spacer] | Reflect▼ | Track▼ | Knowledge▼ | Dev▼
|
||
|
|
Row 2 (.ws-subnav): Servers | Components | Settings | [Workflow] (only when current_env set)
|
||
|
|
nav-icon / nav-label classes hook into the global html.nav-icons / html.nav-names CSS.
|
||
|
|
Mobile (<md): .ws-nav .nav-label is always hidden (icon-only enforced via CSS).
|
||
|
|
#}
|
||
|
|
<div class="ws-nav flex items-center gap-0.5 border-b border-base-300 bg-base-200/40 px-2 py-1 text-sm">
|
||
|
|
|
||
|
|
{# Overview #}
|
||
|
|
<a href="/ui/workspaces/{{ ws_name }}"
|
||
|
|
class="btn btn-ghost btn-xs gap-1 font-normal {% if active == 'overview' %}bg-base-300{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Overview</span>
|
||
|
|
</a>
|
||
|
|
|
||
|
|
{# Infras ▼ #}
|
||
|
|
{% if ws_envs %}
|
||
|
|
<div class="dropdown dropdown-hover">
|
||
|
|
<button tabindex="0" class="btn btn-ghost btn-sm h-7 min-h-0 gap-1 font-normal px-2
|
||
|
|
{% if active == 'servers' or active == 'components' or active == 'config' %}bg-base-300{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0 opacity-70" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label font-mono text-xs max-w-[12rem] truncate">{% if current_env %}{{ current_env }}{% else %}Infras{% endif %}</span>
|
||
|
|
<svg class="w-2.5 h-2.5 flex-shrink-0 opacity-40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
||
|
|
</svg>
|
||
|
|
</button>
|
||
|
|
<ul tabindex="0" class="dropdown-content menu bg-base-200 shadow-lg rounded-box z-50 w-72 p-1.5 mt-0.5">
|
||
|
|
{% for env in ws_envs %}
|
||
|
|
<li>
|
||
|
|
<details {% if current_env == env %}open{% endif %}>
|
||
|
|
<summary class="font-mono text-xs gap-1.5 {% if current_env == env %}text-primary{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5 flex-shrink-0 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2"/>
|
||
|
|
</svg>
|
||
|
|
{{ env }}
|
||
|
|
</summary>
|
||
|
|
<ul>
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/servers?env={{ env }}"
|
||
|
|
class="text-xs {% if active == 'servers' and current_env == env %}active{% endif %}">Servers</a></li>
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/components?env={{ env }}"
|
||
|
|
class="text-xs {% if active == 'components' and current_env == env %}active{% endif %}">Components</a></li>
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/config?env={{ env }}"
|
||
|
|
class="text-xs {% if active == 'config' and current_env == env %}active{% endif %}">Settings</a></li>
|
||
|
|
{% if ws_has_workflows %}
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/workflows?env={{ env }}"
|
||
|
|
class="text-xs {% if active == 'workflows' and current_env == env %}active{% endif %}">Workflow</a></li>
|
||
|
|
{% endif %}
|
||
|
|
</ul>
|
||
|
|
</details>
|
||
|
|
</li>
|
||
|
|
{% endfor %}
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
{% endif %}
|
||
|
|
|
||
|
|
<div class="flex-1"></div>
|
||
|
|
|
||
|
|
{# Reflect → Modes + Actions #}
|
||
|
|
<div class="dropdown dropdown-end dropdown-hover">
|
||
|
|
<button tabindex="0" class="btn btn-ghost btn-xs gap-1 font-normal
|
||
|
|
{% if active == 'modes' or active == 'actions' %}bg-base-300{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Reflect</span>
|
||
|
|
<svg class="w-2.5 h-2.5 opacity-40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
||
|
|
</svg>
|
||
|
|
</button>
|
||
|
|
<ul tabindex="0" class="dropdown-content menu bg-base-200 shadow-lg rounded-box z-50 w-44 p-1.5">
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/modes" class="gap-2 text-xs {% if active == 'modes' %}active{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664zM21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||
|
|
</svg>
|
||
|
|
Modes
|
||
|
|
</a></li>
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/actions" class="gap-2 text-xs {% if active == 'actions' %}active{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||
|
|
</svg>
|
||
|
|
Actions
|
||
|
|
</a></li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{# Track → Backlog + Notifications #}
|
||
|
|
<div class="dropdown dropdown-end dropdown-hover">
|
||
|
|
<button tabindex="0" class="btn btn-ghost btn-xs gap-1 font-normal
|
||
|
|
{% if active == 'backlog' or active == 'notifications' %}bg-base-300{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Track</span>
|
||
|
|
<svg class="w-2.5 h-2.5 opacity-40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
||
|
|
</svg>
|
||
|
|
</button>
|
||
|
|
<ul tabindex="0" class="dropdown-content menu bg-base-200 shadow-lg rounded-box z-50 w-44 p-1.5">
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/backlog" class="gap-2 text-xs {% if active == 'backlog' %}active{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
||
|
|
</svg>
|
||
|
|
Backlog
|
||
|
|
</a></li>
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/notifications" class="gap-2 text-xs {% if active == 'notifications' %}active{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
|
||
|
|
</svg>
|
||
|
|
Notifications
|
||
|
|
</a></li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{# Knowledge → Ontology + DAG #}
|
||
|
|
<div class="dropdown dropdown-end dropdown-hover">
|
||
|
|
<button tabindex="0" class="btn btn-ghost btn-xs gap-1 font-normal
|
||
|
|
{% if active == 'ontology' or active == 'dag' %}bg-base-300{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Knowledge</span>
|
||
|
|
<svg class="w-2.5 h-2.5 opacity-40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
||
|
|
</svg>
|
||
|
|
</button>
|
||
|
|
<ul tabindex="0" class="dropdown-content menu bg-base-200 shadow-lg rounded-box z-50 w-48 p-1.5">
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/ontology" class="gap-2 text-xs {% if active == 'ontology' %}active{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
|
||
|
|
</svg>
|
||
|
|
Ontology
|
||
|
|
</a></li>
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/dag" class="gap-2 text-xs {% if active == 'dag' %}active{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||
|
|
</svg>
|
||
|
|
Deployment DAG
|
||
|
|
</a></li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{# Dev → API tools + Config #}
|
||
|
|
<div class="dropdown dropdown-end dropdown-hover">
|
||
|
|
<button tabindex="0" class="btn btn-ghost btn-xs gap-1 font-normal
|
||
|
|
{% if active == 'config' and not current_env %}bg-base-300{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Dev</span>
|
||
|
|
<svg class="w-2.5 h-2.5 opacity-40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
||
|
|
</svg>
|
||
|
|
</button>
|
||
|
|
<ul tabindex="0" class="dropdown-content menu bg-base-200 shadow-lg rounded-box z-50 w-44 p-1.5">
|
||
|
|
<li><a href="/ui/tools" class="gap-2 text-xs">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
|
||
|
|
</svg>
|
||
|
|
API Tools
|
||
|
|
</a></li>
|
||
|
|
<li><a href="/ui/workspaces/{{ ws_name }}/config" class="gap-2 text-xs {% if active == 'config' and not current_env %}active{% endif %}">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||
|
|
</svg>
|
||
|
|
Config
|
||
|
|
</a></li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{# ── Infra sub-nav (appears when an env is selected) ─────────────────── #}
|
||
|
|
{% if current_env %}
|
||
|
|
<div class="ws-subnav flex items-center gap-0.5 border-b border-base-300 px-2 py-1 mb-4 bg-base-100/60 text-sm">
|
||
|
|
<span class="text-base-content/30 text-xs font-mono mr-1 hidden sm:inline">{{ current_env }}</span>
|
||
|
|
<span class="text-base-content/20 mr-1 hidden sm:inline">·</span>
|
||
|
|
<a href="/ui/workspaces/{{ ws_name }}/servers?env={{ current_env }}"
|
||
|
|
class="btn btn-ghost btn-xs gap-1 font-normal {% if active == 'servers' %}bg-base-300 text-primary{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Servers</span>
|
||
|
|
</a>
|
||
|
|
<a href="/ui/workspaces/{{ ws_name }}/components?env={{ current_env }}"
|
||
|
|
class="btn btn-ghost btn-xs gap-1 font-normal {% if active == 'components' %}bg-base-300 text-primary{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Components</span>
|
||
|
|
</a>
|
||
|
|
<a href="/ui/workspaces/{{ ws_name }}/config?env={{ current_env }}"
|
||
|
|
class="btn btn-ghost btn-xs gap-1 font-normal {% if active == 'config' %}bg-base-300 text-primary{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
|
|
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Settings</span>
|
||
|
|
</a>
|
||
|
|
{% if ws_has_workflows %}
|
||
|
|
<a href="/ui/workspaces/{{ ws_name }}/workflows?env={{ current_env }}"
|
||
|
|
class="btn btn-ghost btn-xs gap-1 font-normal {% if active == 'workflows' %}bg-base-300 text-primary{% endif %}">
|
||
|
|
<svg class="nav-icon w-3.5 h-3.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||
|
|
</svg>
|
||
|
|
<span class="nav-label">Workflow</span>
|
||
|
|
</a>
|
||
|
|
{% endif %}
|
||
|
|
</div>
|
||
|
|
{% else %}
|
||
|
|
<div class="mb-4"></div>
|
||
|
|
{% endif %}
|
||
|
|
{% endmacro ws_tabs %}
|
||
|
|
|
||
|
|
{% macro duration(ms) %}
|
||
|
|
{% if ms < 100 %}
|
||
|
|
<span class="text-success font-mono text-xs">{{ ms }}ms</span>
|
||
|
|
{% elif ms < 1000 %}
|
||
|
|
<span class="text-warning font-mono text-xs">{{ ms }}ms</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="text-error font-mono text-xs">{{ ms }}ms</span>
|
||
|
|
{% endif %}
|
||
|
|
{% endmacro duration %}
|