{"version":3,"file":"proj-BD1A5rAl.js","sources":["../../src/api/experiment.ts","../../src/stores/proj.ts"],"sourcesContent":["import ajax from '@/lib/ajax'\nimport type { Experiment, ExperimentConfig, ExperimentInfo, ExpSummary } from '@/types/exp'\nimport type { Pagination } from '@/types/global'\n\n// 每页实验数量\nexport const expSize = 20 as const\n\n// 最大显示实验数量\nexport const maxShowExps = 8 as const\n\n// 默认页数\nexport const defaultPage = 1 as const\n\n// 获取项目下的实验\nexport async function getExperiments(\n username: string,\n projname: string,\n { page, search }: { page?: number; search?: string }\n) {\n return await ajax\n .get<{ list: Experiment[] } & Pagination>(`/project/${username}/${projname}/runs`, {\n params: { page, size: expSize, search: search || undefined }\n })\n .then((res) => res.data)\n}\n\n// 获取项目下前八个睁着眼睛的实验\nexport async function getShowExps(username: string, projname: string) {\n return await ajax.get(`/project/${username}/${projname}/runs/shows`).then((res) => res.data)\n}\n\n// 更新show状态\nexport async function updateShow(username: string, projname: string, expId: ExperimentInfo['cuid'], show: boolean) {\n return await ajax.put(`/project/${username}/${projname}/runs/${expId}`, { show })\n}\n\n// 更新实验颜色\nexport async function updateColors(\n username: string,\n projname: string,\n expId: ExperimentInfo['cuid'],\n colors: ExpSummary['colors']\n) {\n return await ajax.put(`/project/${username}/${projname}/runs/${expId}`, { colors })\n}\n\n// 获取实验详情,在进入实验页面时调用\nexport const getExperiment = async (username: string, projname: string, expId: ExperimentInfo['cuid']) => {\n return await ajax.get(`/project/${username}/${projname}/runs/${expId}`).then((res) => res.data)\n}\n\n// 获取实验状态\nexport const getExperimentState = async (username: string, projname: string, expId: ExperimentInfo['cuid']) => {\n return await ajax\n .get<{\n state: ExperimentInfo['state']\n finishedAt: ExperimentInfo['finishedAt']\n }>(`/project/${username}/${projname}/runs/${expId}/state`)\n .then((res) => res.data)\n}\n\n// 删除实验\nexport const deleteExperiments = async (username: string, projname: string, cuids: Experiment['cuid'][]) => {\n const promises = cuids.map((cuid) => ajax.delete(`/project/${username}/${projname}/runs/${cuid}`))\n return Promise.all(promises)\n}\n\n// 修改实验简介\nexport const updateExperimentDesc = async (username: string, projname: string, cuid: string, description: string) => {\n return await ajax.put(`/project/${username}/${projname}/runs/${cuid}`, {\n description\n })\n}\n\n// 获取实验日志\nexport const getExperimentLogs = async (exp: Experiment, projectId: string, epoch: number | null = null) => {\n return (\n await ajax.get('/house/metrics/log', {\n params: {\n projectId,\n experimentId: exp.cuid,\n rootProId: exp.rootProId,\n rootExpId: exp.rootExpId,\n epoch\n }\n })\n ).data\n}\n\n// 更新实验配置\nexport const updateExperimentConfig = async (\n username: string,\n projname: string,\n expId: string,\n config: Partial\n) => {\n return await ajax.put(`/project/${username}/${projname}/runs/${expId}/config`, config)\n}\n","import { computed, ref, shallowRef } from 'vue'\nimport { defineStore } from 'pinia'\nimport type { Project } from '@/types/project'\nimport type { ExperimentConfig, ExpState, ExpSummary } from '@/types/exp'\nimport { expSize, maxShowExps } from '@/api/experiment'\n\nexport const useProjStore = defineStore('proj', () => {\n const proj = ref()\n // 项目所属用户/组织\n const username = ref('')\n const projname = computed(() => proj.value?.name || '')\n const summaryId = computed(() => proj.value?.summary.cuid || '')\n const cuid = computed(() => proj.value?.cuid || '')\n const role = computed(() => {\n if (!proj.value) throw new Error('proj is not ready when use role')\n return proj.value.role\n })\n // 项目url,/@:username/:projname\n const projUrl = computed(() => `/@${username.value}/${projname.value}`)\n // 项目可见性\n const visibility = computed(() => {\n if (!proj.value) throw new Error('proj is not ready when use visibility')\n return proj.value.visibility\n })\n\n // 当前搜索关键字\n const search = ref('')\n // 数据是否已经准备好\n const isReady = computed(() => !!proj.value && !!username.value && !!shows.value)\n // 是否显示快速开始\n const isShowQuickStart = ref(false)\n // 是否可编辑\n const isEditable = computed(() => proj.value?.role === 'MEMBER' || proj.value?.role === 'OWNER')\n // 是否是访客\n const isVisitor = computed(() => proj.value?.role === 'VISITOR')\n // 侧边栏显示的所有实验,非递归响应式,因为可能会有点多\n const shows = shallowRef()\n // 当前项目状态,加载中、空项目、正常\n const status = computed<'LOADING' | 'EMPTY' | 'NORMAL'>(() => {\n if (!isReady.value) return 'LOADING'\n if (shows.value === undefined) throw new Error('shows is not ready when use status')\n // 项目为空\n if (shows.value.length === 0) return 'EMPTY'\n return 'NORMAL'\n })\n\n // 当前页数\n const page = ref(1)\n // 当前总页数\n const pages = computed(() => Math.ceil((nowShows.value?.length || 0) / expSize))\n // 当前搜索条件下的实验\n const nowShows = computed(() => {\n if (!shows.value) return []\n if (!nowSearch.value) return shows.value\n return shows.value.filter((exp) => exp.name.toLowerCase().includes(nowSearch.value.toLocaleLowerCase()))\n })\n // 当前页的实验\n const nowPageShows = computed(() => {\n const start = (page.value - 1) * expSize\n return nowShows.value.slice(start, start + expSize)\n })\n // 当前搜索关键字,计算属性,搜索关键字只能通过\n const nowSearch = computed(() => search.value)\n // 是否可以操作资源\n const canManage = computed(() => role.value === 'OWNER' || role.value === 'MEMBER')\n\n // 获取当前显示在多实验图表的实验信息,会被截断\n const getShows = (): { colors: ExpSummary['colors']; expId: ExpSummary['cuid'] }[] => {\n // 返回前几个show为true的实验\n const exps = []\n for (const exp of shows.value || []) {\n if (exp.show) exps.push({ expId: exp.cuid, colors: exp.colors })\n if (exps.length >= maxShowExps + 1) break\n }\n return exps\n }\n\n // 更新多实验图表对应实验的配置\n const reconfig = (config: Partial) => {\n if (!proj.value) throw new Error('proj is not ready')\n proj.value.summary.config = { ...proj.value.summary.config, ...config } as ExperimentConfig\n }\n\n // 设置实验列表,整个设置\n // 如果设置时实验列表不为空,则将设置的实验列表中不存在于原实验列表的实验添加到原实验列表中\n // 约定:实验列表按照创建时间降序排列,因此不存在的实验一定在列表的最前面\n const setShows = (nowShows: ExpSummary[]) => {\n if (!shows.value) {\n shows.value = nowShows\n return\n }\n // 将新的实验列表中不存在于原实验列表的实验添加到原实验列表中,直接赋值\n // 同时解决全局实验状态轮询\n shows.value = nowShows\n }\n\n // 删除某个实验\n const removeShow = (cuid: string | string[]) => {\n shows.value = shows.value?.filter((show) => {\n return !Array.isArray(cuid) ? show.cuid !== cuid : !cuid.includes(show.cuid)\n })\n }\n\n function updateShowsByIndex(cuid: string, callback: (show: ExpSummary) => ExpSummary) {\n if (!shows.value) throw new Error('shows is not ready when use updateShowsByIndex')\n shows.value = shows.value.map((s) => (s.cuid === cuid ? callback(s) : s))\n }\n\n // 更新某个实验的show状态\n const updateShow = (cuid: string, show: boolean) => {\n return updateShowsByIndex(cuid, (s) => {\n s.show = show\n return s\n })\n }\n\n // 更新某个实验的运行状态\n const updateState = (cuid: string, state: ExpState) => {\n return updateShowsByIndex(cuid, (show) => {\n show.state = state\n return show\n })\n }\n\n // 更新某个实验的名称\n const updateName = (cuid: string, name: string) => {\n return updateShowsByIndex(cuid, (show) => {\n show.name = name\n return show\n })\n }\n\n // 更新某个实验的颜色\n const updateColor = (cuid: string, color: string) => {\n return updateShowsByIndex(cuid, (show) => {\n show.colors = [color, show.colors[1]]\n return show\n })\n }\n\n // 更新搜索关键字,清空页数\n const updateSearch = (nowSearch: string) => {\n page.value = 1\n search.value = nowSearch\n }\n\n function $reset() {\n proj.value = undefined\n username.value = ''\n search.value = ''\n shows.value = undefined\n isShowQuickStart.value = false\n page.value = 1\n }\n\n return {\n proj,\n role,\n username,\n projname,\n projUrl,\n visibility,\n nowSearch,\n nowShows,\n nowPageShows,\n isReady,\n status,\n isShowQuickStart,\n page,\n pages,\n isEditable,\n isVisitor,\n summaryId,\n cuid,\n canManage,\n getShows,\n reconfig,\n setShows,\n removeShow,\n updateShow,\n updateState,\n updateColor,\n updateSearch,\n updateName,\n $reset\n }\n})\n"],"names":["expSize","maxShowExps","defaultPage","async","getExperiments","username","projname","page","search","ajax","get","params","size","then","res","data","getShowExps","updateShow","expId","show","put","updateColors","colors","getExperiment","getExperimentState","deleteExperiments","cuids","promises","map","cuid","delete","Promise","all","updateExperimentDesc","description","getExperimentLogs","exp","projectId","epoch","experimentId","rootProId","rootExpId","updateExperimentConfig","config","useProjStore","defineStore","proj","ref","computed","_a","value","name","summaryId","summary","role","Error","projUrl","visibility","isReady","shows","isShowQuickStart","isEditable","_b","isVisitor","shallowRef","status","length","pages","Math","ceil","nowShows","nowSearch","filter","toLowerCase","includes","toLocaleLowerCase","nowPageShows","start","slice","canManage","updateShowsByIndex","callback","s","getShows","exps","push","reconfig","setShows","removeShow","Array","isArray","updateState","state","updateColor","color","updateSearch","updateName","$reset"],"mappings":"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"}