feat: add AI assistant SVG icon and integrate it into the header with a toggle button

This commit is contained in:
Marvin Zhang
2025-05-30 23:27:47 +08:00
parent 1cb5133fe0
commit 2aefdd3ee1
4 changed files with 39 additions and 44 deletions

View File

@@ -0,0 +1,8 @@
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
width="200" height="200">
<g transform="translate(-80, -80) scale(1.2, 1.2)">
<path
d="M536.96 65.194667c99.306667 0 190.805333 38.890667 258.581333 109.973333 66.730667 69.248 104.192 163.904 105.664 265.706667V447.957333L814.762667 448l0.064-6.336c-1.984-163.136-118.293333-286.677333-271.189334-290.261333l-6.677333-0.085334h-4.117333c-76.714667 0.597333-147.029333 32-198.101334 88.170667-50.858667 55.914667-78.997333 125.909333-77.632 205.034667 0 0.704 0.042667 1.28 0.32 4.16 0.277333 2.986667 0.384 4.885333 0.384 7.061333 0 18.346667-2.773333 28.16-12.693333 38.058667-4.992 5.013333-28.16 33.066667-69.568 84.202666a17.706667 17.706667 0 0 0 8.469333 28.053334l2.154667 0.533333 5.845333 1.024a1444.266667 1444.266667 0 0 0 47.765334 7.893333c7.168 0 12.736 4.330667 17.322666 10.602667 2.197333 3.114667 3.477333 6.890667 4.309334 11.370667 0.64 3.434667 0.917333 6.762667 1.002666 9.216l0.042667 1.664 10.090667 203.84c56.32-9.216 153.130667-23.146667 196.8-29.248v89.130666c-63.402667 11.157333-194.410667 27.776-198.997334 27.776-42.538667 0-78.485333-33.92-81.493333-76.181333l-0.192-4.266667-8.042667-168.512-22.186666-4.650666c-59.050667-13.013333-88.512-34.090667-89.216-81.152-0.341333-16.725333 7.808-34.56 22.997333-54.293334 10.176-13.205333 78.101333-103.04 79.914667-104.810666-1.664-208.768 147.093333-373.376 339.370666-380.586667l6.741334-0.213333h18.709333zM730.176 512L853.333333 874.666667h-71.872l-25.301333-85.973334h-126.570667L604.288 874.666667H533.333333l122.666667-362.666667h74.176zM938.666667 512v362.666667h-64V512h64z m-246.250667 64c-1.002667 4.288-14.848 54.08-41.536 149.333333h83.968c-27.285333-95.253333-41.429333-145.045333-42.432-149.333333z"
fill="currentColor"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -44,9 +44,9 @@ const updateIconSvgSrc = async () => {
if (isSvg.value) {
const { icon } = props;
if (!Array.isArray(icon) || !icon[1]) return;
const res = await import(`@/assets/svg/icons/${icon[1]}.svg?url`);
const res = await import(`@/assets/svg/icons/${icon[1]}.svg`);
if (res) {
iconSvgSrc.value = res.default;
iconSvgSrc.value = decodeURIComponent(res.default).replace('data:image/svg+xml,', '');
}
}
};
@@ -72,13 +72,7 @@ defineOptions({ name: 'ClIcon' });
/>
</template>
<template v-else-if="isSvg">
<img
:class="[icon, ...cls]"
class="icon"
:src="iconSvgSrc"
:alt="alt"
@click="event => emit('click', event)"
/>
<div :class="[icon, ...cls]" class="icon" v-html="iconSvgSrc"/>
</template>
<template v-else>
<i
@@ -92,9 +86,14 @@ defineOptions({ name: 'ClIcon' });
</template>
<style scoped>
img {
.icon {
display: inline-block;
height: 1em;
vertical-align: -0.125em;
&:deep(svg) {
height: 100%;
width: 100%;
}
}
</style>

View File

@@ -12,6 +12,7 @@ import {
isAllowedRoutePath,
} from '@/utils';
import { getUserFullName } from '@/utils/user';
import ClIconButton from '@/components/ui/button/IconButton.vue';
// i18n
const { t, locale } = useI18n();
@@ -153,6 +154,13 @@ defineOptions({ name: 'ClHeader' });
</template>
</el-dropdown>
</div>
<div class="item action" @click="toggleChatbotSidebar">
<el-tooltip :content="t('components.ai.chatbot.button')">
<div class="chat-toggle">
<cl-icon :icon="getIconByRouteConcept('ai')" size="normal" />
</div>
</el-tooltip>
</div>
<div v-if="me" class="item action">
<el-dropdown trigger="click" popper-class="me-dropdown">
<div class="me">
@@ -205,19 +213,6 @@ defineOptions({ name: 'ClHeader' });
</template>
</el-dropdown>
</div>
<div class="item action" v-if="!sidebarVisible">
<el-button
type="primary"
@click="toggleChatbotSidebar"
class="chat-toggle-btn"
>
<cl-icon :icon="['fa', 'comment-dots']" />
<span class="button-text">{{
t('components.ai.chatbot.button')
}}</span>
<cl-icon :icon="['fa', 'angles-left']" class="toggle-indicator" />
</el-button>
</div>
</div>
</el-header>
</div>
@@ -252,9 +247,9 @@ defineOptions({ name: 'ClHeader' });
.right {
display: flex;
align-items: center;
gap: 12px;
.item {
margin-left: 20px;
display: flex;
align-items: center;
@@ -269,6 +264,7 @@ defineOptions({ name: 'ClHeader' });
.lang {
display: flex;
align-items: center;
margin-left: 16px;
&:hover {
color: var(--cl-primary-color);
@@ -279,27 +275,19 @@ defineOptions({ name: 'ClHeader' });
}
}
.chat-toggle-btn {
display: flex;
.chat-toggle {
display: inline-flex;
align-items: center;
border-radius: 20px;
padding: 8px 16px;
animation: fadeIn 0.3s ease-in-out;
background-color: var(--el-color-primary-dark-2);
justify-content: center;
transition: all 0.3s ease;
border-radius: 50%;
height: 36px;
width: 36px;
margin: 0 5px;
.button-text {
margin: 0 8px;
display: inline-block;
}
.toggle-indicator {
margin-left: 4px;
transition: transform 0.3s;
}
.robot-icon-badge {
display: flex;
align-items: center;
&:hover {
background-color: var(--el-color-primary-dark-2);
color: white;
}
}
}

View File

@@ -294,7 +294,7 @@ export const getIconByRouteConcept = (concept: RouteConcept): Icon => {
case 'permission':
return ['fa', 'user-check'];
case 'ai':
return ['fa', 'comment-dots'];
return ['svg', 'ai-assistant'];
case 'models':
return ['fa', 'hexagon-nodes'];
case 'system':