127 lines
6.1 KiB
XML
127 lines
6.1 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
Copyright 2026 Nexa Systems Inc.
|
|
License OPL-1 (Odoo Proprietary License v1.0)
|
|
-->
|
|
<templates xml:space="preserve">
|
|
|
|
<t t-name="fusion_clock_ai.AISystray">
|
|
<Dropdown position="'bottom-end'" state="dropdown"
|
|
menuClass="'fclk-ai-systray-dropdown p-0'">
|
|
<button class="fclk-ai-systray-btn" title="AI Assistant">
|
|
<img src="/fusion_clock_ai/static/src/img/ai_icon.png" alt="AI" class="fclk-ai-systray-img"/>
|
|
</button>
|
|
<t t-set-slot="content">
|
|
<div class="fclk-ai-panel" t-on-click.stop="">
|
|
|
|
<!-- Header -->
|
|
<div class="fclk-ai-panel-header">
|
|
<span class="fclk-ai-panel-title">AI Assistant</span>
|
|
<div class="fclk-ai-tabs">
|
|
<button t-attf-class="fclk-ai-tab {{ state.activeTab === 'chat' ? 'active' : '' }}"
|
|
t-on-click="() => this.switchTab('chat')">Chat</button>
|
|
<button t-attf-class="fclk-ai-tab {{ state.activeTab === 'tools' ? 'active' : '' }}"
|
|
t-on-click="() => this.switchTab('tools')">Tools</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Chat Body -->
|
|
<div t-if="state.activeTab === 'chat'" class="fclk-ai-chat-body" t-ref="chatBody">
|
|
|
|
<!-- Empty state -->
|
|
<t t-if="!hasMessages and !state.loading">
|
|
<div class="fclk-ai-empty">
|
|
<i class="fa fa-magic fclk-ai-empty-icon"/>
|
|
<div>
|
|
<strong>Ask me anything</strong><br/>
|
|
about your team's attendance
|
|
</div>
|
|
<div class="fclk-ai-suggestions">
|
|
<t t-foreach="suggestions" t-as="s" t-key="s_index">
|
|
<button class="fclk-ai-suggestion"
|
|
t-on-click="() => this.onSuggestionClick(s)">
|
|
<t t-esc="s"/>
|
|
</button>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
|
|
<!-- Messages -->
|
|
<t t-foreach="state.messages" t-as="msg" t-key="msg_index">
|
|
<div t-attf-class="fclk-ai-msg fclk-ai-msg--{{ msg.role }}">
|
|
<div class="fclk-ai-msg-avatar">
|
|
<i t-if="msg.role === 'user'" class="fa fa-user"/>
|
|
<i t-else="" class="fa fa-magic"/>
|
|
</div>
|
|
<div class="fclk-ai-msg-content">
|
|
<t t-esc="msg.content"/>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
|
|
<!-- Typing indicator -->
|
|
<t t-if="state.loading">
|
|
<div class="fclk-ai-msg fclk-ai-msg--assistant">
|
|
<div class="fclk-ai-msg-avatar">
|
|
<i class="fa fa-magic"/>
|
|
</div>
|
|
<div class="fclk-ai-msg-content fclk-ai-typing">
|
|
<span/><span/><span/>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
|
|
<!-- Tools Body -->
|
|
<div t-if="state.activeTab === 'tools'" class="fclk-ai-tools-body">
|
|
<div class="fclk-ai-tool-grid">
|
|
<t t-foreach="tools" t-as="tool" t-key="tool.key">
|
|
<button class="fclk-ai-tool-btn"
|
|
t-on-click="() => this.runTool(tool.key)"
|
|
t-att-disabled="state.toolLoading">
|
|
<i t-attf-class="fa {{ tool.icon }}"/>
|
|
<span t-esc="tool.label"/>
|
|
</button>
|
|
</t>
|
|
</div>
|
|
|
|
<!-- Tool loading -->
|
|
<div t-if="state.toolLoading" class="fclk-ai-analysis-loading">
|
|
<i class="fa fa-circle-o-notch fa-spin"/>
|
|
Running analysis...
|
|
</div>
|
|
|
|
<!-- Tool result -->
|
|
<div t-if="state.toolResult" class="fclk-ai-analysis-result">
|
|
<pre t-esc="state.toolResult.text"/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Input Area (chat tab only) -->
|
|
<div t-if="state.activeTab === 'chat'" class="fclk-ai-chat-input">
|
|
<button class="fclk-ai-new-chat" t-on-click="newConversation"
|
|
title="New conversation">
|
|
<i class="fa fa-plus"/>
|
|
</button>
|
|
<textarea rows="1"
|
|
placeholder="Ask about attendance..."
|
|
t-on-input="onInput"
|
|
t-on-keydown="onKeydown"
|
|
t-att-value="state.inputText"
|
|
t-att-disabled="state.loading"/>
|
|
<button class="fclk-ai-send"
|
|
t-on-click="sendMessage"
|
|
t-att-disabled="!canSend"
|
|
title="Send">
|
|
<i class="fa fa-paper-plane"/>
|
|
</button>
|
|
</div>
|
|
|
|
</div>
|
|
</t>
|
|
</Dropdown>
|
|
</t>
|
|
|
|
</templates>
|