|
|
@@ -16,9 +16,7 @@ import { forMe, poolOverview, liveBoard, STAGES, sortOpportunities } from '../co
|
|
|
const sortByNewest = (rows) => sortOpportunities(rows, 'newest');
|
|
|
import { href } from '../utils/router.js';
|
|
|
import { t, VIEW_CSS, head } from './shared.js';
|
|
|
-import { cardFooter, reportCard, playCard, CARD_CSS } from './report-card.js';
|
|
|
-import { entryOfArtifact } from '../core/index.js';
|
|
|
-import '../components/kf-drawer.js';
|
|
|
+import { cardFooter, playCard, CARD_CSS } from './report-card.js';
|
|
|
import { icon } from '../components/icons.js';
|
|
|
|
|
|
const TONE = { S1: 'blue', S2: 'violet', S3: 'teal', S4: 'amber', S5: 'rose' };
|
|
|
@@ -38,8 +36,6 @@ export class ViewWorkbench extends LitElement {
|
|
|
static properties = {
|
|
|
db: { type: Object },
|
|
|
me: { type: String },
|
|
|
- /** 抽屉:{ id, title } —— 机会卡全貌(完整报告 + 评分 + 快捷决策) */
|
|
|
- drawer: { type: Object },
|
|
|
};
|
|
|
|
|
|
#mineLatest = null;
|
|
|
@@ -48,7 +44,6 @@ export class ViewWorkbench extends LitElement {
|
|
|
super();
|
|
|
this.db = null;
|
|
|
this.me = '';
|
|
|
- this.drawer = null;
|
|
|
}
|
|
|
|
|
|
connectedCallback() {
|
|
|
@@ -309,10 +304,6 @@ export class ViewWorkbench extends LitElement {
|
|
|
</kf-glass-card>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <kf-drawer .open=${Boolean(this.drawer)} .heading=${this.drawer?.title || '机会卡'} sub=${t('完整报告 · 评分 · 决策')} .width=${this.drawer ? "min(760px, 96vw)" : ""}
|
|
|
- @drawer-close=${() => { this.drawer = null; }}>
|
|
|
- ${this.drawer ? this.#drawerBody() : ''}
|
|
|
- </kf-drawer>
|
|
|
${cardFooter({ shown: play.length, all: pool.total, filtered: false, label: '张机会卡,最近 3 张列在上方', onTop: () => window.scrollTo({ top: 0, behavior: 'smooth' }) })}
|
|
|
<!-- 只有手机显示:证据台账从底部 Tab 移到工作台页脚(真实链接,部署前缀同源) -->
|
|
|
<nav class="foot-links" aria-label="更多入口">
|
|
|
@@ -322,29 +313,9 @@ export class ViewWorkbench extends LitElement {
|
|
|
}
|
|
|
|
|
|
/** A 卡:选了「我是」→ 我的进度;没选 → 全员进度(v12 定稿:空态也放真实内容,不摆空框) */
|
|
|
- /** 打开一张机会卡的抽屉(全貌:完整报告 + 给卡打分 + 决策) */
|
|
|
+ /** 打开机会卡全貌:交给 app 的抽屉(机会卡详情 = 决策 / 多人评分 / 来源 / 关联报告),与卡池点开是同一个 */
|
|
|
#openCard(id) {
|
|
|
- const o = this.db?.opportunityById?.[id];
|
|
|
- if (!o) return;
|
|
|
- this.drawer = { id, title: o.title };
|
|
|
- }
|
|
|
-
|
|
|
- /** 抽屉内容:所有关联成果的报告卡(同一套 .rc 卡片,不另造样式) */
|
|
|
- #drawerBody() {
|
|
|
- const o = this.db?.opportunityById?.[this.drawer?.id];
|
|
|
- if (!o) return '';
|
|
|
- /* 关联成果 = 机会卡上登记的 linkedArtifacts(正常化的 linkedArtifactIds),不猜别的字段 */
|
|
|
- const ids = new Set(o.linkedArtifactIds || []);
|
|
|
- const arts = (this.db.artifacts || []).filter((a) => ids.has(a.id)).slice(0, 4);
|
|
|
- return html`<div class="dr">
|
|
|
- <div class="act-row">
|
|
|
- <span class="lbl">${o.stageObj ? `${o.stageObj.code} · ${o.stageObj.name}` : ''} · ${o.upload?.uploadedBy || '上传人未记录'}</span>
|
|
|
- <span class="st" style="margin-left:auto">${o.status === 'approved' ? '已立项' : o.status === 'rejected' ? '已否决' : '候选'}</span>
|
|
|
- <a class="go" href=${href(`/pool/${o.id}`)} data-link>在卡池里打开 →</a>
|
|
|
- </div>
|
|
|
- ${arts.length ? arts.map((a) => reportCard({ e: entryOfArtifact(this.db, a, a.typeKey), fit: true }))
|
|
|
- : html`<div class="empty"><span>这张卡还没有关联成果报告</span></div>`}
|
|
|
- </div>`;
|
|
|
+ this.dispatchEvent(new CustomEvent('opportunity-open', { detail: { id }, bubbles: true, composed: true }));
|
|
|
}
|
|
|
|
|
|
/** 快捷决策:复用 app 的 status-change(带操作人校验与写入),与卡池同一路径 */
|