diff --git a/eai_agentplatform/PROJECT_STATE.md b/eai_agentplatform/PROJECT_STATE.md index 860863a..95a9b86 100644 --- a/eai_agentplatform/PROJECT_STATE.md +++ b/eai_agentplatform/PROJECT_STATE.md @@ -62,6 +62,9 @@ | D18 | 突破原「极致极简/杜绝学情分析」边界:新增学员成长体系 = 学习积分+排行榜(游戏化)+ 考试证书(认证)+ 学习档案/能力雷达(学情,学员自助视角);积分规则集中常量可调 | 已定(V1.6 落地) | | D19 | 部门组织架构(department 字典表,用户以 department 字符串归属、改名同步)+ 按部门学情统计;站内消息通知(考试发布/通过发证/设岗三事件);**社交社区/讨论区定死不做** | 已定(V1.7 落地) | | D20 | 当前阶段产品路线收口为「先通用、后定制」:先做标准化通用数字员工产品包,不直接追 WorkBuddy 的高自由度路线;第一批优先沉淀知识运营、培训考试、内容生成、任务推进 4 个通用数字员工,后续再长行业包与企业半定制 | 已定(见 `docs/01_System_Overall/SY19_Universal_Digital_Worker_Product_Planning.md`) | +| D21 | 前端建立「冻结归档」机制:停用代码不删除,集中到 `frontend/src/_frozen/`(统一 `.frozen` 后缀 + `FROZEN.md` 登记表,逐条记录原位置/冻结原因/外部依赖/**解冻条件**/解冻步骤)。首批冻结:工作区胶囊条(外壳重构后成了冗余的第二套导航)及外壳重构遗留的四个孤儿文件。**D19 的站内通知只冻前端 UI** —— 后端四个接口保留,`store`/`api` 层保留(`BusinessAppPage` 仍在用),解冻为纯前端工作量 | 已定(见 `frontend/src/_frozen/FROZEN.md`) | +| D22 | 任务记录**延迟到发出第一条消息时创建**(对齐 WorkBuddy:新建任务只是导航动作,不落库)。「新建任务」只做「回到 /home 开场画布 + 清空当前任务」,任务标题由第一句话决定、专员取输入框 `+` 里先选的那个(`pendingSpecialistKey` 暂存,建任务时作为 `specialist_key` 一并提交,后端已支持)。**不允许存在没聊过天的空任务** —— 原实现点一次落一条 `新任务`,是「最近任务」堆满空行的根因 | 已定(V1.8 落地) | +| D23 | 侧边栏「最近任务」的行菜单(对齐 ChatGPT 悬停 `⋯` + WorkBuddy 任务卡「更多」):**重命名**(就地编辑,回车提交/Esc 取消)、**置顶**(新增 `worker_task.pinned`,排序 `pinned DESC, updated_at DESC`)、**删除**(新增 `DELETE /api/worker/my-tasks/:id`,硬删、无回收站,确认框写明「无法恢复」)。对照后**不做**:分享任务(纯内网无意义)、打开文件夹(Web 无此能力)、保存到工作空间(项目无 workspace 概念)、归档(没有「已归档」入口可找回,等于软删陷阱)。`el-dropdown` 加 `:persistent="false"` —— 默认每行留一份隐藏菜单在 DOM 里,50 条任务就是 50 份 | 已定 | ## 4. 文档索引 diff --git a/eai_agentplatform/backend-go/internal/api/my_task.go b/eai_agentplatform/backend-go/internal/api/my_task.go new file mode 100644 index 0000000..786b38e --- /dev/null +++ b/eai_agentplatform/backend-go/internal/api/my_task.go @@ -0,0 +1,208 @@ +package api + +import ( + "errors" + "io" + "strings" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" + + "eai_agentplatform/backend/internal/middleware" + "eai_agentplatform/backend/internal/model" + "eai_agentplatform/backend/internal/store" + "eai_agentplatform/backend/internal/web" +) + +// 通用智能助手:seed 里 state=system 的那条内置记录。「新建任务」时还没选专员, +// 任务就先落在它名下;之后用输入框的 + 选专员/工具,任务再改挂过去。 +const generalAssistantKey = "general-assistant" + +// 「新建任务」的占位标题。发出第一条消息后前端会把它改成消息内容。 +const myTaskPlaceholderTitle = "新任务" + +// myTaskOwners 是"这条任务算谁的"的判定依据。scopedWorkbenchTaskQuery 也是 +// 按这两个值找人,保持一致;只写 FullName 的话没填全名的用户会跟别人混在一起。 +func myTaskOwners(user *model.User) []string { + if user == nil { + return nil + } + owners := make([]string, 0, 2) + if name := strings.TrimSpace(user.FullName); name != "" { + owners = append(owners, name) + } + if name := strings.TrimSpace(user.Username); name != "" { + owners = append(owners, name) + } + return owners +} + +// myTaskOwnerName 一条新任务记在谁名下。空全名时退回登录名。 +func myTaskOwnerName(user *model.User) string { + owners := myTaskOwners(user) + if len(owners) == 0 { + return "" + } + return owners[0] +} + +// myTaskQuery 「我的任务」永远是"我自己的",管理员也只看自己的 —— +// 要看全公司的那是工作台总览,不是这里。 +func myTaskQuery(user *model.User) *gorm.DB { + owners := myTaskOwners(user) + query := store.DB.Model(&model.WorkerTask{}) + if len(owners) == 0 { + // 没有可用的归属标识,返回空集而不是全表 + return query.Where("1 = 0") + } + return query.Where("owner IN ?", owners) +} + +// ListMyTasks 当前用户的全部任务,跨专员,最近更新的在前。 +func ListMyTasks(c *gin.Context) { + user := middleware.CurrentUser(c) + if user == nil { + web.Fail(c, web.NewAuthError("未登录")) + return + } + + var items []model.WorkerTask + if err := myTaskQuery(user). + // 置顶的排在前面,其余按最近动过的排 —— 置顶只是一个排序偏好。 + Order("pinned DESC, updated_at DESC, id DESC"). + Limit(50). + Find(&items).Error; err != nil { + web.Fail(c, web.NewBadRequest("查询我的任务失败")) + return + } + web.OK(c, items) +} + +// DeleteMyTask 彻底删掉一条任务。worker_task 没有软删字段,删了就是删了 —— +// 前端那边因此必须在确认框里说清楚,不能拿它当「归档」用。 +func DeleteMyTask(c *gin.Context) { + user := middleware.CurrentUser(c) + if user == nil { + web.Fail(c, web.NewAuthError("未登录")) + return + } + id, ok := parseID(c, "id") + if !ok { + return + } + + var task model.WorkerTask + if err := myTaskQuery(user).Where("id = ?", id).First(&task).Error; err != nil { + web.Fail(c, web.NewNotFoundError("任务不存在")) + return + } + if err := store.DB.Delete(&task).Error; err != nil { + web.Fail(c, web.NewBadRequest("删除任务失败")) + return + } + web.OK(c, gin.H{"id": id}) +} + +// CreateMyTask 建一条属于当前用户的任务。没给专员就落在通用智能助手名下。 +func CreateMyTask(c *gin.Context) { + user := middleware.CurrentUser(c) + if user == nil { + web.Fail(c, web.NewAuthError("未登录")) + return + } + + // 允许空 body:点「新建任务」时前端什么都可以不带,全部走默认值。 + var req workerTaskReq + if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { + web.Fail(c, web.NewBadRequest("请求参数错误")) + return + } + + specialistKey := strings.TrimSpace(req.SpecialistKey) + if specialistKey == "" { + specialistKey = generalAssistantKey + } + var specialist model.Specialist + if err := store.DB.Where("key = ?", specialistKey).First(&specialist).Error; err != nil { + web.Fail(c, web.NewNotFoundError("专员不存在")) + return + } + + title := strings.TrimSpace(req.Title) + if title == "" { + title = myTaskPlaceholderTitle + } + + // 归属由服务端定死,不读请求里的 owner —— 否则任何人都能替别人建任务。 + req.SpecialistKey = specialist.Key + req.Title = title + req.Owner = myTaskOwnerName(user) + task, err := buildWorkerTaskFromReq(req, user) + if err != nil { + web.Fail(c, web.NewBadRequest(err.Error())) + return + } + task.SpecialistKey = specialist.Key + if task.Status == "" { + task.Status = workerTaskStatusPending + } + if task.Status == "" { + task.Status = "待处理" + } + + if err := store.DB.Create(&task).Error; err != nil { + web.Fail(c, web.NewBadRequest("创建任务失败")) + return + } + web.OK(c, task) +} + +// UpdateMyTask 改自己的任务:改标题,或者把它改挂到另一个专员名下 +// (输入框的 + 里选了专员就走这里)。 +func UpdateMyTask(c *gin.Context) { + user := middleware.CurrentUser(c) + if user == nil { + web.Fail(c, web.NewAuthError("未登录")) + return + } + id, ok := parseID(c, "id") + if !ok { + return + } + + var task model.WorkerTask + if err := myTaskQuery(user).Where("id = ?", id).First(&task).Error; err != nil { + web.Fail(c, web.NewNotFoundError("任务不存在")) + return + } + + var req workerTaskReq + if err := c.ShouldBindJSON(&req); err != nil { + web.Fail(c, web.NewBadRequest("请求参数错误")) + return + } + + if title := strings.TrimSpace(req.Title); title != "" { + task.Title = title + } + if key := strings.TrimSpace(req.SpecialistKey); key != "" && key != task.SpecialistKey { + var specialist model.Specialist + if err := store.DB.Where("key = ?", key).First(&specialist).Error; err != nil { + web.Fail(c, web.NewNotFoundError("目标专员不存在")) + return + } + task.SpecialistKey = specialist.Key + } + if summary := strings.TrimSpace(req.Summary); summary != "" { + task.Summary = summary + } + if req.Pinned != nil { + task.Pinned = *req.Pinned + } + + if err := store.DB.Save(&task).Error; err != nil { + web.Fail(c, web.NewBadRequest("更新任务失败")) + return + } + web.OK(c, task) +} diff --git a/eai_agentplatform/backend-go/internal/api/router.go b/eai_agentplatform/backend-go/internal/api/router.go index 6dcd6c8..3608add 100644 --- a/eai_agentplatform/backend-go/internal/api/router.go +++ b/eai_agentplatform/backend-go/internal/api/router.go @@ -46,6 +46,12 @@ func RegisterRoutes(r *gin.Engine, cfg *config.Config) { r.GET("/api/workbench/overview", middleware.Auth(cfg), WorkbenchOverview) r.GET("/api/worker/tasks", middleware.Auth(cfg), ListWorkerTasks) r.GET("/api/worker/tasks/:id", middleware.Auth(cfg), GetWorkerTaskDetail) + // 员工自己的工作区:「新建任务」和侧边栏的任务列表走这三个。 + // 归属由服务端按登录用户定,请求里的 owner 一律不读。 + r.GET("/api/worker/my-tasks", middleware.Auth(cfg), ListMyTasks) + r.POST("/api/worker/my-tasks", middleware.Auth(cfg), CreateMyTask) + r.PUT("/api/worker/my-tasks/:id", middleware.Auth(cfg), UpdateMyTask) + r.DELETE("/api/worker/my-tasks/:id", middleware.Auth(cfg), DeleteMyTask) r.GET("/api/worker/artifacts/:id", middleware.Auth(cfg), GetWorkerArtifactDetail) r.POST("/api/official-account/tasks", middleware.Auth(cfg), CreateOfficialAccountTask) r.GET("/api/official-account/tasks/:id/workflow", middleware.Auth(cfg), GetOfficialAccountWorkflow) diff --git a/eai_agentplatform/backend-go/internal/api/specialist.go b/eai_agentplatform/backend-go/internal/api/specialist.go index bfec3ca..03119ef 100644 --- a/eai_agentplatform/backend-go/internal/api/specialist.go +++ b/eai_agentplatform/backend-go/internal/api/specialist.go @@ -29,9 +29,16 @@ func ListSpecialists(c *gin.Context) { if !isAdmin { q = q.Where("state = ?", "active") } + case "system": + q = q.Where("state = ?", "system") default: q = q.Where("state = ?", state) } + // state = system 的内置记录(通用智能助手)是任务的默认归属,不是可安装的专员, + // 任何常规列表都不该带出它 —— 只有显式 state=system 才查得到。 + if c.Query("state") != "system" { + q = q.Where("state <> ?", "system") + } var items []model.Specialist if err := q.Order("sort_order ASC, id ASC").Find(&items).Error; err != nil { diff --git a/eai_agentplatform/backend-go/internal/api/worker_task.go b/eai_agentplatform/backend-go/internal/api/worker_task.go index 1d41f3a..8289824 100644 --- a/eai_agentplatform/backend-go/internal/api/worker_task.go +++ b/eai_agentplatform/backend-go/internal/api/worker_task.go @@ -28,6 +28,9 @@ type workerTaskReq struct { Status string `json:"status"` DueAt string `json:"due_at"` Context map[string]any `json:"context"` + // Pinned 用指针:要区分「没传这个字段」和「传了 false 要取消置顶」, + // 值类型的话取消置顶会被当成没传,永远取消不掉。 + Pinned *bool `json:"pinned"` } type workerActionReq struct { diff --git a/eai_agentplatform/backend-go/internal/model/worker_task.go b/eai_agentplatform/backend-go/internal/model/worker_task.go index 1f483e9..c016b32 100644 --- a/eai_agentplatform/backend-go/internal/model/worker_task.go +++ b/eai_agentplatform/backend-go/internal/model/worker_task.go @@ -17,8 +17,10 @@ type WorkerTask struct { DueAt *time.Time `json:"due_at"` CreatedBy *uint `gorm:"index" json:"created_by"` LastTriggeredAt *time.Time `json:"last_triggered_at"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + // Pinned 置顶:只影响「我的任务」列表的排序,不改变任务本身的状态。 + Pinned bool `gorm:"not null;default:false" json:"pinned"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } func (WorkerTask) TableName() string { return "worker_task" } diff --git a/eai_agentplatform/backend-go/internal/store/seed.go b/eai_agentplatform/backend-go/internal/store/seed.go index cb6bb16..101324a 100644 --- a/eai_agentplatform/backend-go/internal/store/seed.go +++ b/eai_agentplatform/backend-go/internal/store/seed.go @@ -285,6 +285,24 @@ func seedTrainingMedia() error { func seedSpecialists() error { items := []model.Specialist{ + { + // 「新建任务」在还没选专员/工具之前,任务先落在这里。 + // state = system:它不是一个能装到工作区的专员,只是任务的默认归属, + // 所以不出现在专员市场、我的专员和 + 菜单里(ListSpecialists 会挡掉)。 + Key: "general-assistant", + Label: "通用智能助手", + Tier: "generic", + WorkerType: "dw", + Route: "/home", + Summary: "还没指定专员的任务默认落在这里,用输入框的 + 挂上专员或工具", + Stage: "待处理", + Color: "#409eff", + MarketTag: "内置", + Version: "v1.0", + BaseSkills: "对话、任务拆解、按 + 选定的专员或工具继续", + State: "system", + SortOrder: 0, + }, { Key: "training-delivery", Label: "培训交付专员", diff --git a/eai_agentplatform/frontend/src/_frozen/FROZEN.md b/eai_agentplatform/frontend/src/_frozen/FROZEN.md new file mode 100644 index 0000000..de6fcc1 --- /dev/null +++ b/eai_agentplatform/frontend/src/_frozen/FROZEN.md @@ -0,0 +1,38 @@ +# 冻结件登记表(FROZEN) + +本目录存放**已停用但完整保留**的代码:不参与构建、不被任何存活代码引用,但随时可回收。 + +冻结不是删除。删掉的东西要靠记忆和 git log 才能找回来;冻结的东西保持可读、可搜索、 +并在此处登记它的来龙去脉。**「解冻条件」这一列是核心** —— 没有它,这批代码半年后没人 +敢动,就从资产变成了负债。 + +## 约定 + +- 目录 `src/_frozen/`,所有冻结文件统一加 `.frozen` 后缀 +- 冻结件**不 import 存活代码以外的路径**;冻结件之间用相对引用,自成封闭单元 +- 冻结件保留原有注释与代码原貌,只在文件头加一段「原位置 / 冻结日期」说明 +- 冻结件内引用的 store / api **未必也冻结**(见下表「外部依赖」列),解冻前先核对 + +## 登记表 + +| 冻结物 | 原位置 | 为什么冻 | 外部依赖 | 解冻条件 | 解冻步骤 | +|---|---|---|---|---|---| +| `WorkspaceTabs.frozen.vue`
工作区胶囊条 + 通知铃铛 | `src/layout/MainLayout.vue` 模板 101-128 行、`isTabActive()` 314-318、`closeTab()` 375-388、通知轮询 240-241/248、样式 727-802 | 外壳重构后一级导航移到侧边栏、二级导航移到内容区 `components/SectionTabs.vue`,这行胶囊成了冗余的第二套导航;且铃铛指向未注册的 `/notifications`,是点了没反应的死按钮 | ✅ 存活:`@/store/workbench`、`@/store/notification`、`@/config/nav`、`vue-router`、`@element-plus/icons-vue` | 需要「跨一级项快速切换任务」这一交互时;或恢复通知功能时(铃铛含在内) | 在 `MainLayout.vue` 的 `.wb-main` 内、`` 之前挂 `` 并 import。组件已自包含,无需改动内部代码 | +| `SectionTabs.frozen.vue`
旧二级导航(`el-tabs` 形态) | `src/layout/SectionTabs.vue` | 被 `src/components/SectionTabs.vue` 取代(新的由 `config/nav.js` 驱动,改为原生 button + 下划线)。**注意与存活的那个同名,勿混淆** | ✅ 存活:`@/store/auth`、`@/store/notification`
🔒 冻结:`./navigation.frozen.js` | 想要 `el-tabs` 形态的二级导航时(旧版自带 el-badge,与 Element 风格更统一) | 1. 放回 `src/layout/`;2. 把 import 改回 `@/config/navigation`,并将 `navigation.frozen.js` 放回 `src/config/`;3. 在 `MainLayout.vue` 挂载 | +| `SideNav.frozen.vue`
旧侧边栏 | `src/layout/SideNav.vue` | 被 `MainLayout.vue` 内联的新侧边栏取代 | ✅ 存活:`@/store/auth`、`@/store/notification`
🔒 冻结:`./navigation.frozen.js` | 想把侧边栏从 `MainLayout.vue` 里拆成独立组件时 —— 旧版结构上比现在的内联写法更清晰 | 同 `SectionTabs.frozen.vue`:放回 `src/layout/`,import 改回 `@/config/navigation` 并还原 `navigation.frozen.js` | +| `navigation.frozen.js`
旧导航配置 | `src/config/navigation.js` | 被 `src/config/nav.js` 取代(`nav.js` 收敛了原先 `sidebarGroups` / `LibraryTabs` / `ExamTabs` 三份重复清单) | 无 | 随上面两个组件一起解冻 | 放回 `src/config/` 并去掉文件名里的 `.frozen` | +| `Notification.frozen.vue`
站内通知页面(175 行,实现完整) | `src/views/Notification.vue` | `router/index.js` 里没有 `/notifications` 路由,页面无入口,已成孤儿 | ✅ 存活:`@/api/notification`、`@/store/notification`
✅ 后端四个接口仍在(`backend-go/internal/api/router.go:90-93`) | 要恢复站内通知时。**是纯前端工作量** —— 后端接口从未下线 | 1. 放回 `src/views/`;2. 在 `router/index.js` 注册 `/notifications`;3. 补导航入口(`config/nav.js` 里没有它,需新增);4. 参考 `WorkspaceTabs.frozen.vue` 把铃铛加回 | + +## 已知遗留(本次未修,改动存活代码时注意) + +铃铛冻结后,`store/notification.js` 的 `unread` 在前端**已无任何 UI 消费者**, +但 `src/views/workbench/BusinessAppPage.vue`(825 / 855 / 892 行)仍会调用 +`notificationStore.refresh()`。属于既有死端,本次一并冻掉铃铛后更明显。 +若将来确认通知不再恢复,可连同 `store/notification.js`、`api/notification.js` +的引用一起清理。 + +## 冻结记录 + +| 日期 | 动作 | +|---|---| +| 2026-09-14 | 建立本目录与约定。冻结工作区胶囊条(`WorkspaceTabs.frozen.vue`,新抽出);收拢外壳重构遗留的四个孤儿(`SectionTabs` / `SideNav` / `navigation` / `Notification`) | diff --git a/eai_agentplatform/frontend/src/views/Notification.vue b/eai_agentplatform/frontend/src/_frozen/Notification.frozen.vue similarity index 100% rename from eai_agentplatform/frontend/src/views/Notification.vue rename to eai_agentplatform/frontend/src/_frozen/Notification.frozen.vue diff --git a/eai_agentplatform/frontend/src/layout/SectionTabs.vue b/eai_agentplatform/frontend/src/_frozen/SectionTabs.frozen.vue similarity index 93% rename from eai_agentplatform/frontend/src/layout/SectionTabs.vue rename to eai_agentplatform/frontend/src/_frozen/SectionTabs.frozen.vue index 7b8d6ed..a6e2a2f 100644 --- a/eai_agentplatform/frontend/src/layout/SectionTabs.vue +++ b/eai_agentplatform/frontend/src/_frozen/SectionTabs.frozen.vue @@ -33,7 +33,8 @@ import { computed } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useAuthStore } from '@/store/auth' import { useNotificationStore } from '@/store/notification' -import { resolveSection, resolveTab } from '@/config/navigation' +// 冻结件之间用相对引用,让这批归档自成一个封闭单元(原为 @/config/navigation) +import { resolveSection, resolveTab } from './navigation.frozen.js' const route = useRoute() const router = useRouter() diff --git a/eai_agentplatform/frontend/src/layout/SideNav.vue b/eai_agentplatform/frontend/src/_frozen/SideNav.frozen.vue similarity index 96% rename from eai_agentplatform/frontend/src/layout/SideNav.vue rename to eai_agentplatform/frontend/src/_frozen/SideNav.frozen.vue index 6ca1a83..b66c087 100644 --- a/eai_agentplatform/frontend/src/layout/SideNav.vue +++ b/eai_agentplatform/frontend/src/_frozen/SideNav.frozen.vue @@ -65,7 +65,8 @@ import { } from '@element-plus/icons-vue' import { useAuthStore } from '@/store/auth' import { useNotificationStore } from '@/store/notification' -import { getVisibleSections, resolveSection } from '@/config/navigation' +// 冻结件之间用相对引用,让这批归档自成一个封闭单元(原为 @/config/navigation) +import { getVisibleSections, resolveSection } from './navigation.frozen.js' const route = useRoute() const router = useRouter() diff --git a/eai_agentplatform/frontend/src/_frozen/WorkspaceTabs.frozen.vue b/eai_agentplatform/frontend/src/_frozen/WorkspaceTabs.frozen.vue new file mode 100644 index 0000000..831cf62 --- /dev/null +++ b/eai_agentplatform/frontend/src/_frozen/WorkspaceTabs.frozen.vue @@ -0,0 +1,179 @@ + + + + + + diff --git a/eai_agentplatform/frontend/src/config/navigation.js b/eai_agentplatform/frontend/src/_frozen/navigation.frozen.js similarity index 100% rename from eai_agentplatform/frontend/src/config/navigation.js rename to eai_agentplatform/frontend/src/_frozen/navigation.frozen.js diff --git a/eai_agentplatform/frontend/src/api/worker.js b/eai_agentplatform/frontend/src/api/worker.js index b51371c..919d49b 100644 --- a/eai_agentplatform/frontend/src/api/worker.js +++ b/eai_agentplatform/frontend/src/api/worker.js @@ -4,6 +4,23 @@ export function listWorkerTasks(params) { return http.get('/worker/tasks', { params }) } +// 「我的任务」:跨专员,归属由后端按登录用户定,前端不传 owner。 +export function listMyTasks() { + return http.get('/worker/my-tasks') +} + +export function createMyTask(data = {}) { + return http.post('/worker/my-tasks', data) +} + +export function updateMyTask(id, data) { + return http.put(`/worker/my-tasks/${id}`, data) +} + +export function deleteMyTask(id) { + return http.delete(`/worker/my-tasks/${id}`) +} + export function getWorkerTaskDetail(id) { return http.get(`/worker/tasks/${id}`) } diff --git a/eai_agentplatform/frontend/src/components/LibraryTabs.vue b/eai_agentplatform/frontend/src/components/LibraryTabs.vue deleted file mode 100644 index c489d17..0000000 --- a/eai_agentplatform/frontend/src/components/LibraryTabs.vue +++ /dev/null @@ -1,80 +0,0 @@ - - - - - diff --git a/eai_agentplatform/frontend/src/components/NavSearch.vue b/eai_agentplatform/frontend/src/components/NavSearch.vue new file mode 100644 index 0000000..9b4040f --- /dev/null +++ b/eai_agentplatform/frontend/src/components/NavSearch.vue @@ -0,0 +1,253 @@ + + + + + diff --git a/eai_agentplatform/frontend/src/components/SectionTabs.vue b/eai_agentplatform/frontend/src/components/SectionTabs.vue new file mode 100644 index 0000000..9bdee04 --- /dev/null +++ b/eai_agentplatform/frontend/src/components/SectionTabs.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/eai_agentplatform/frontend/src/components/chat/ChatInputBar.vue b/eai_agentplatform/frontend/src/components/chat/ChatInputBar.vue index 4af4da8..ff041f5 100644 --- a/eai_agentplatform/frontend/src/components/chat/ChatInputBar.vue +++ b/eai_agentplatform/frontend/src/components/chat/ChatInputBar.vue @@ -1,5 +1,5 @@