Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@ miniprogram/project.private.config.json

# Staging dir for the Docker sandbox self-check probe (removed after each run)
.weknora-sandbox-check-*
weknora-ui.tar
Binary file modified docs/images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>WeKnora</title>
<title>SAI·灵玑</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
Expand Down
Binary file modified frontend/public/favicon.ico
Binary file not shown.
Binary file added frontend/src/assets/img/smee.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/src/assets/img/smee_w.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed frontend/src/assets/img/weknora.png
Binary file not shown.
5 changes: 3 additions & 2 deletions frontend/src/components/SandboxConfigEditorDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
? $t('settings.sandbox.secretConfigured')
: $t('settings.sandbox.cubeApiKeyOptional') }}
</p>
<a class="inline-guide-link" :href="clusterGuideUrl" target="_blank" rel="noopener noreferrer">
<a v-if="FEATURES.showGithubLinks" class="inline-guide-link" :href="clusterGuideUrl" target="_blank" rel="noopener noreferrer">
<t-icon name="link" />
{{ $t('settings.sandbox.cubeApiKeyWhere') }}
</a>
Expand Down Expand Up @@ -264,7 +264,7 @@
<p v-else-if="!templatesLoaded" class="section-help">
{{ $t('settings.sandbox.templateLoadHint') }}
</p>
<a class="inline-guide-link" :href="clusterGuideUrl" target="_blank" rel="noopener noreferrer">
<a class="inline-guide-link" target="_blank" rel="noopener noreferrer">
<t-icon name="link" />
{{ $t('settings.sandbox.howToBuildTemplate') }}
</a>
Expand Down Expand Up @@ -389,6 +389,7 @@
</template>

<script setup lang="ts">
import { FEATURES } from '@/config/branding'
import { computed, nextTick, onUnmounted, reactive, ref, watch } from 'vue'
import { MessagePlugin } from 'tdesign-vue-next'
import { useI18n } from 'vue-i18n'
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/SpotlightGuide.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { GUIDE_BRAND_NAME } from '@/config/branding'
import type { SpotlightGuideStep } from '@/types/spotlightGuide'

const CARD_WIDTH = 340
Expand Down Expand Up @@ -151,8 +152,8 @@ let retryTimer: ReturnType<typeof setTimeout> | null = null

const step = computed(() => props.steps[index.value] ?? props.steps[0])
const isLast = computed(() => index.value === props.steps.length - 1)
const stepTitle = computed(() => t(`${props.stepI18nPrefix}.${step.value.key}.title`))
const stepDesc = computed(() => t(`${props.stepI18nPrefix}.${step.value.key}.desc`))
const stepTitle = computed(() => t(`${props.stepI18nPrefix}.${step.value.key}.title`, { brand: GUIDE_BRAND_NAME }))
const stepDesc = computed(() => t(`${props.stepI18nPrefix}.${step.value.key}.desc`, { brand: GUIDE_BRAND_NAME }))

const hole = computed(() => {
const el = targetEl.value
Expand Down
47 changes: 25 additions & 22 deletions frontend/src/components/UserMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,28 +107,30 @@
<t-icon name="server" class="menu-icon" />
<span>{{ $t('settings.navGroups.systemAdministration') }}</span>
</div>
<div class="menu-divider"></div>
<div class="menu-item" @click="openDocs">
<t-icon name="help-circle" class="menu-icon" />
<span class="menu-text-with-icon">
<span>{{ $t('general.helpAndDocs') }}</span>
<svg class="menu-external-icon" viewBox="0 0 16 16" aria-hidden="true">
<path fill="currentColor"
d="M12.667 8a.667.667 0 0 1 .666.667v4a2.667 2.667 0 0 1-2.666 2.666H4.667a2.667 2.667 0 0 1-2.667-2.666V5.333a2.667 2.667 0 0 1 2.667-2.666h4a.667.667 0 1 1 0 1.333h-4a1.333 1.333 0 0 0-1.333 1.333v7.334A1.333 1.333 0 0 0 4.667 13.333h6a1.333 1.333 0 0 0 1.333-1.333v-4A.667.667 0 0 1 12.667 8Zm2.666-6.667v4a.667.667 0 0 1-1.333 0V3.276l-5.195 5.195a.667.667 0 0 1-.943-.943l5.195-5.195h-2.057a.667.667 0 0 1 0-1.333h4a.667.667 0 0 1 .666.666Z" />
</svg>
</span>
</div>
<div class="menu-item" :title="$t('common.githubStarTip')" @click="openGithub">
<t-icon name="logo-github" class="menu-icon" />
<span class="menu-text-with-icon">
<span>{{ $t('common.github') }}</span>
<t-icon name="star-filled" class="menu-github-star-icon" size="16px" aria-hidden="true" />
<svg class="menu-external-icon" viewBox="0 0 16 16" aria-hidden="true">
<path fill="currentColor"
d="M12.667 8a.667.667 0 0 1 .666.667v4a2.667 2.667 0 0 1-2.666 2.666H4.667a2.667 2.667 0 0 1-2.667-2.666V5.333a2.667 2.667 0 0 1 2.667-2.666h4a.667.667 0 1 1 0 1.333h-4a1.333 1.333 0 0 0-1.333 1.333v7.334A1.333 1.333 0 0 0 4.667 13.333h6a1.333 1.333 0 0 0 1.333-1.333v-4A.667.667 0 0 1 12.667 8Zm2.666-6.667v4a.667.667 0 0 1-1.333 0V3.276l-5.195 5.195a.667.667 0 0 1-.943-.943l5.195-5.195h-2.057a.667.667 0 0 1 0-1.333h4a.667.667 0 0 1 .666.666Z" />
</svg>
</span>
</div>
<template v-if="FEATURES.showHelpAndGithubMenu">
<div class="menu-divider"></div>
<div class="menu-item" @click="openDocs">
<t-icon name="help-circle" class="menu-icon" />
<span class="menu-text-with-icon">
<span>{{ $t('general.helpAndDocs') }}</span>
<svg class="menu-external-icon" viewBox="0 0 16 16" aria-hidden="true">
<path fill="currentColor"
d="M12.667 8a.667.667 0 0 1 .666.667v4a2.667 2.667 0 0 1-2.666 2.666H4.667a2.667 2.667 0 0 1-2.667-2.666V5.333a2.667 2.667 0 0 1 2.667-2.666h4a.667.667 0 1 1 0 1.333h-4a1.333 1.333 0 0 0-1.333 1.333v7.334A1.333 1.333 0 0 0 4.667 13.333h6a1.333 1.333 0 0 0 1.333-1.333v-4A.667.667 0 0 1 12.667 8Zm2.666-6.667v4a.667.667 0 0 1-1.333 0V3.276l-5.195 5.195a.667.667 0 0 1-.943-.943l5.195-5.195h-2.057a.667.667 0 0 1 0-1.333h4a.667.667 0 0 1 .666.666Z" />
</svg>
</span>
</div>
<div class="menu-item" :title="$t('common.githubStarTip')" @click="openGithub">
<t-icon name="logo-github" class="menu-icon" />
<span class="menu-text-with-icon">
<span>{{ $t('common.github') }}</span>
<t-icon name="star-filled" class="menu-github-star-icon" size="16px" aria-hidden="true" />
<svg class="menu-external-icon" viewBox="0 0 16 16" aria-hidden="true">
<path fill="currentColor"
d="M12.667 8a.667.667 0 0 1 .666.667v4a2.667 2.667 0 0 1-2.666 2.666H4.667a2.667 2.667 0 0 1-2.667-2.666V5.333a2.667 2.667 0 0 1 2.667-2.666h4a.667.667 0 1 1 0 1.333h-4a1.333 1.333 0 0 0-1.333 1.333v7.334A1.333 1.333 0 0 0 4.667 13.333h6a1.333 1.333 0 0 0 1.333-1.333v-4A.667.667 0 0 1 12.667 8Zm2.666-6.667v4a.667.667 0 0 1-1.333 0V3.276l-5.195 5.195a.667.667 0 0 1-.943-.943l5.195-5.195h-2.057a.667.667 0 0 1 0-1.333h4a.667.667 0 0 1 .666.666Z" />
</svg>
</span>
</div>
</template>
<template v-if="!authStore.isLiteMode">
<div class="menu-divider"></div>
<div class="menu-item danger" @click="handleLogout">
Expand Down Expand Up @@ -215,6 +217,7 @@ import { useRoleLabel, useHomeTenant } from '@/composables/useRoleLabel'
import { getRootZoom, rectToCssPx, cssViewportSize } from '@/utils/zoom'
import { openNewUserGuide } from '@/config/contextualGuides'
import { SETTINGS_MANAGEMENT_SHORTCUT_MIN_ROLE } from '@/config/settingsAccess'
import { FEATURES } from '@/config/branding'

const { t } = useI18n()

Expand Down
21 changes: 19 additions & 2 deletions frontend/src/components/menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<!-- 展开时:Logo + 搜索/折叠按钮同行 -->
<div class="logo_row" v-if="!uiStore.sidebarCollapsed">
<div class="logo_box" @click="router.push('/platform/knowledge-bases')" style="cursor: pointer;">
<img class="logo" src="@/assets/img/weknora.png" alt="">
<img class="logo" :src="BRAND_LOGO_SRC" alt="">
<span class="sidebar-logo-brand"><span class="brand-s" :style="{ color: BRANDING.accentColor }">{{ BRAND_ACCENT_LETTER }}</span>{{ BRAND_NAME_TAIL }}</span>
<sup v-if="isLiteEdition" class="lite-badge">Lite</sup>
</div>
<div class="logo_actions">
Expand Down Expand Up @@ -256,6 +257,7 @@ import UserMenu from '@/components/UserMenu.vue';
import TenantSelector from '@/components/TenantSelector.vue';
import { useI18n } from 'vue-i18n';
import { getSystemInfo } from '@/api/system';
import { BRANDING, BRAND_ACCENT_LETTER, BRAND_NAME_TAIL, BRAND_LOGO_SRC } from '@/config/branding';

const chatResources = useChatResourcesStore();
// Platform logos reused from IMChannelsOverviewPanel — keeps the session list
Expand Down Expand Up @@ -1273,10 +1275,25 @@ const onDragHandleMouseDown = (e: MouseEvent) => {
overflow: hidden;

.logo {
width: 128px;
width: 32px;
height: auto;
}

.sidebar-logo-brand {
margin-left: 10px;
font-size: 18px;
font-weight: 700;
color: var(--td-text-color-primary);
font-family: var(--app-font-family);
letter-spacing: 0.5px;
line-height: 1;
white-space: nowrap;

.brand-s {
color: #e60012;
}
}

.lite-badge {
margin-left: 2px;
align-self: flex-start;
Expand Down
66 changes: 66 additions & 0 deletions frontend/src/config/branding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* 内网定制入口。
* 想隐藏/恢复功能、改品牌名或换 logo,只改本文件即可,无需改动组件代码。
* 全部为前端配置,不涉及后端。
*/

// ---------- 品牌 ----------
export const BRANDING = {
/** 品牌名称:登录页 / 侧边栏 logo 右侧文字,以及「新对话」欢迎语 */
name: 'SAI·灵玑',
/** 品牌名第一个字符的高亮色(例如「SAI·灵玑」的 S 显示为该色) */
accentColor: '#e60012',
/** 品牌 logo 文件名(放在 src/assets/img/ 目录下,构建时按名字匹配) */
logoFile: 'smee.png',
/** 登录页单独使用的 logo 文件名(可选;不填则跟随 logoFile) */
loginLogoFile: 'smee_w.png',
} as const

/** 品牌名第一个字符(高亮展示) */
export const BRAND_ACCENT_LETTER: string = BRANDING.name.charAt(0)
/** 品牌名其余部分(普通颜色展示) */
export const BRAND_NAME_TAIL: string = BRANDING.name.slice(1)

// ---------- 功能可见性开关 ----------
export const FEATURES = {
/** 左下角用户菜单是否显示「帮助与文档」「GitHub」 */
showHelpAndGithubMenu: false,
/** 「全部设置 → 集成」是否显示「chrome 插件」「claw skill」 */
showChromeClawIntegrations: false,
/** 「全部设置 → 模型」是否显示「WeKnora Cloud」(默认隐藏) */
showWeKnoraCloud: false,
/** 登录页 logo 是否还原为 GitHub 外链(true=可点击跳转 GitHub,false=纯展示) */
showLoginGithubLink: false,
/** 登录页右上角是否显示「官方网站」「GitHub」外链(默认隐藏) */
showLoginHeaderLinks: false,
/** 是否显示指向原版 WeKnora GitHub 的文档/反馈等外链(默认隐藏;true 时恢复显示并可点击) */
showGithubLinks: false,
} as const

// ---------- 登录页文案 ----------
/** 登录页两处固定文案(默认已去掉旧品牌名 WeKnora)。想改字直接改这里。 */
export const AUTH_TEXT = {
/** 登录表单下方「首次使用?」 */
firstTime: '首次使用?',
/** 注册卡片副标题「创建账户并开始使用」 */
registerSubtitle: '创建账户并开始使用',
} as const

// ---------- 新手引导 ----------
/** 新手引导里的品牌名(第一页「欢迎使用 X」/ 第二页「X 会自动解析…」),默认跟随 BRANDING.name */
export const GUIDE_BRAND_NAME: string = BRANDING.name

// ---------- logo 构建期解析 ----------
// assets/img 下的图片经 Vite 打进产物后按文件名取 logo,
const brandLogos = import.meta.glob('@/assets/img/*.{png,jpg,jpeg,svg,ico}', {
eager: true,
import: 'default',
}) as Record<string, string>

export const BRAND_LOGO_SRC: string =
brandLogos[`/src/assets/img/${BRANDING.logoFile}`] ?? brandLogos['/src/assets/img/smee.png']

/** 登录页专用 logo(默认跟随 BRANDING.logoFile,可用 loginLogoFile 单独指定) */
export const LOGIN_LOGO_SRC: string =
brandLogos[`/src/assets/img/${BRANDING.loginLogoFile ?? BRANDING.logoFile}`] ?? BRAND_LOGO_SRC

13 changes: 10 additions & 3 deletions frontend/src/config/integrations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { DeploymentCapabilityKey } from './deploymentCapabilities'
import { FEATURES } from '@/config/branding'

export const CHROME_EXTENSION_URL =
'https://chromewebstore.google.com/detail/jpemjbopikggjlmikmclgbmkhhopjdgd?utm_source=item-share-cb'
Expand All @@ -7,7 +8,9 @@ export const CLAWHUB_SKILL_URL = 'https://clawhub.ai/lyingbug/weknora'

export type IntegrationTab = 'im' | 'embed' | 'api' | 'chrome' | 'claw'

export const INTEGRATION_TABS: IntegrationTab[] = ['im', 'embed', 'api', 'chrome', 'claw']
export const INTEGRATION_TABS: IntegrationTab[] = FEATURES.showChromeClawIntegrations
? ['im', 'embed', 'api', 'chrome', 'claw']
: ['im', 'embed', 'api']

/** Aligns with Settings.vue SECTION_MIN_ROLE.api and router.go g.Owner() on /api-principal-config. */
export type IntegrationTabRole = 'viewer' | 'contributor' | 'admin' | 'owner'
Expand All @@ -34,6 +37,10 @@ export const INTEGRATION_PREVIEW_ITEMS: Array<{
{ key: 'im', icon: { type: 'icon', name: 'chat-message' } },
{ key: 'embed', icon: { type: 'icon', name: 'code' } },
{ key: 'api', icon: { type: 'icon', name: 'secured' } },
{ key: 'chrome', icon: { type: 'icon', name: 'extension' } },
{ key: 'claw', icon: { type: 'emoji', value: '🦞' } },
...(FEATURES.showChromeClawIntegrations
? [
{ key: 'chrome', icon: { type: 'icon', name: 'extension' } },
{ key: 'claw', icon: { type: 'emoji', value: '🦞' } },
]
: []),
]
Loading