@takagaki/cortex-decisions-viewer 0.12.137 → 0.12.140
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/build.js +0 -2
- package/dist/pending-ops.js +35 -2
- package/dist/render.js +28 -106
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ cortex-decisions-viewer build [dir] [options]
|
|
|
55
55
|
| `title` | タイトル |
|
|
56
56
|
| `date` | 日付(`YYYY-MM-DD`)。一覧は日付降順。期間(月)フィルタの導出元 |
|
|
57
57
|
| `sprint` | フィルタ用(`sprint` を使っている案件のみフィルタ表示) |
|
|
58
|
-
| `category` |
|
|
58
|
+
| `category` | 画面には出さない(旧い記録の欄は読むだけ) |
|
|
59
59
|
| `deciders` | 決定者チップ |
|
|
60
60
|
| `summary` | 一覧・詳細の要約 |
|
|
61
61
|
| `references` | 参照リンク。`[label](url)` 形式・URL・リポジトリルート相対パスに対応(ローカルパスはGitHubのblobリンクに変換) |
|
package/dist/build.js
CHANGED
|
@@ -2573,7 +2573,6 @@ async function buildSite(opts, views) {
|
|
|
2573
2573
|
return a.date < b.date ? 1 : -1;
|
|
2574
2574
|
return a.id < b.id ? 1 : -1;
|
|
2575
2575
|
});
|
|
2576
|
-
const categories = uniqueSorted(decisions.map((d) => d.category).filter(Boolean));
|
|
2577
2576
|
// 期間フィルタ用の月(YYYY-MM)を日付から導出し、降順(新しい順)にする
|
|
2578
2577
|
const months = uniqueSorted(decisions.map((d) => d.date.slice(0, 7)).filter((m) => /^\d{4}-\d{2}$/.test(m))).reverse();
|
|
2579
2578
|
// **突き合わなかった提案の件数をビルドログに出す。** path が1文字違うだけで
|
|
@@ -2632,7 +2631,6 @@ async function buildSite(opts, views) {
|
|
|
2632
2631
|
...(memoryV2 ? { memoryV2: true } : {}),
|
|
2633
2632
|
sections,
|
|
2634
2633
|
graph,
|
|
2635
|
-
categories,
|
|
2636
2634
|
months,
|
|
2637
2635
|
intake: opts.intakeUrl && opts.projectKey && opts.intakeToken
|
|
2638
2636
|
? {
|
package/dist/pending-ops.js
CHANGED
|
@@ -22,6 +22,7 @@ exports.PENDING_OPS_LIMITS = void 0;
|
|
|
22
22
|
exports.pendingKindsTable = pendingKindsTable;
|
|
23
23
|
exports.pendingOpsKey = pendingOpsKey;
|
|
24
24
|
exports.pendingSlackChannelId = pendingSlackChannelId;
|
|
25
|
+
exports.pendingSlackUrl = pendingSlackUrl;
|
|
25
26
|
exports.pendingIsSpaceRef = pendingIsSpaceRef;
|
|
26
27
|
exports.pendingGoogleChatSpaceRef = pendingGoogleChatSpaceRef;
|
|
27
28
|
exports.pendingRepo = pendingRepo;
|
|
@@ -115,6 +116,18 @@ function pendingSlackChannelId(input) {
|
|
|
115
116
|
const client = s.match(/^https?:\/\/app\.slack\.com\/client\/[TE][A-Z0-9]{6,20}\/([CG][A-Z0-9]{6,})/);
|
|
116
117
|
return client ? client[1] : null;
|
|
117
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Slack のチャンネル URL(リンク用)。貼られた URL が `<ドメイン>.slack.com/archives/<ID>` で、ID が
|
|
121
|
+
* 対象のチャンネルと同じならそれを正規化して返す。取れなければ `https://slack.com/archives/<ID>`
|
|
122
|
+
* (夜のまとめ=サーバの logic.mjs と同じ形)。**夜のまとめの `url` が来たらそちらが正**で、これは仮置き用。
|
|
123
|
+
*/
|
|
124
|
+
function pendingSlackUrl(input, id) {
|
|
125
|
+
const cid = String(id == null ? "" : id);
|
|
126
|
+
const m = String(input == null ? "" : input).trim().match(/^https:\/\/([a-z0-9][a-z0-9-]*)\.slack\.com\/archives\/([CG][A-Z0-9]{6,})(?:[/?#]|$)/);
|
|
127
|
+
if (m && m[2] === cid && m[1] !== "app")
|
|
128
|
+
return "https://" + m[1] + ".slack.com/archives/" + cid;
|
|
129
|
+
return cid ? "https://slack.com/archives/" + cid : "";
|
|
130
|
+
}
|
|
118
131
|
/**
|
|
119
132
|
* スペース ref の形(サーバの `GOOGLE_CHAT_SPACE_REF` の写し)。ずれは parity テストが固定する。
|
|
120
133
|
*
|
|
@@ -269,6 +282,9 @@ function pendingOpOf(payload, ctx) {
|
|
|
269
282
|
case "add-channel": {
|
|
270
283
|
const id = pendingSlackChannelId(payload.url);
|
|
271
284
|
const data = { name: pendingLabel(payload.name) || id };
|
|
285
|
+
// 貼られた URL でリンクにする(追加直後・接続を確認する前から)。ドメインが取れなければ共通の形
|
|
286
|
+
if (id)
|
|
287
|
+
data.url = pendingSlackUrl(payload.url, id);
|
|
272
288
|
if (payload.workspace)
|
|
273
289
|
data.workspace = String(payload.workspace);
|
|
274
290
|
// **どの組織のチャンネルかは、サーバの実測を応答から受け取る(#391)。**
|
|
@@ -286,7 +302,14 @@ function pendingOpOf(payload, ctx) {
|
|
|
286
302
|
return make("slack", "remove", payload.ref);
|
|
287
303
|
case "refresh-channel-name": {
|
|
288
304
|
const name = pendingLabel(payload.name);
|
|
289
|
-
|
|
305
|
+
if (!name)
|
|
306
|
+
return null;
|
|
307
|
+
// 接続を確認できた行は、チャンネルの URL も揃える(行に url が無いときだけ効く・合成の項)
|
|
308
|
+
const data = { name: name };
|
|
309
|
+
const url = pendingSlackUrl(payload.url, payload.ref);
|
|
310
|
+
if (url)
|
|
311
|
+
data.url = url;
|
|
312
|
+
return make("slack", "update", payload.ref, data);
|
|
290
313
|
}
|
|
291
314
|
case "set-notify": {
|
|
292
315
|
if (typeof payload.value !== "boolean")
|
|
@@ -370,7 +393,7 @@ function sanitizePendingOps(raw, projectKey) {
|
|
|
370
393
|
const src = e.payload && typeof e.payload === "object" ? e.payload : {};
|
|
371
394
|
// 通してよい payload の欄(葉は文字列か、notify だけ真偽値)。関数の中に置くのは、
|
|
372
395
|
// クライアントへ toString() で流し込んだ先でも同じ一覧を参照できるようにするため
|
|
373
|
-
const fields = ["name", "workspace", "notify", "domain", "projectKey", "type", "slackOrg"];
|
|
396
|
+
const fields = ["name", "workspace", "notify", "domain", "projectKey", "type", "slackOrg", "url"];
|
|
374
397
|
for (const f of fields) {
|
|
375
398
|
if (!Object.prototype.hasOwnProperty.call(src, f))
|
|
376
399
|
continue;
|
|
@@ -378,6 +401,11 @@ function sanitizePendingOps(raw, projectKey) {
|
|
|
378
401
|
if (src[f] === true || src[f] === false)
|
|
379
402
|
payload[f] = src[f];
|
|
380
403
|
}
|
|
404
|
+
else if (f === "url") {
|
|
405
|
+
// href に入る値。localStorage から読み戻すので、Slack のチャンネル URL の形だけ通す
|
|
406
|
+
if (typeof src[f] === "string" && /^https:\/\/(?:[a-z0-9][a-z0-9-]*\.)?slack\.com\/archives\/[CG][A-Z0-9]{6,}$/.test(src[f]))
|
|
407
|
+
payload[f] = src[f];
|
|
408
|
+
}
|
|
381
409
|
else if (typeof src[f] === "string")
|
|
382
410
|
payload[f] = src[f];
|
|
383
411
|
}
|
|
@@ -735,6 +763,8 @@ function pendingExternalRow(e) {
|
|
|
735
763
|
row.type = "slack";
|
|
736
764
|
row.name = p.name || e.targetId;
|
|
737
765
|
row.ref = e.targetId;
|
|
766
|
+
if (typeof p.url === "string" && p.url)
|
|
767
|
+
row.url = p.url;
|
|
738
768
|
// channels.json に書いた行= derived(dev-sources 側の宣言ではない)
|
|
739
769
|
row.origin = "derived";
|
|
740
770
|
if (p.workspace)
|
|
@@ -859,6 +889,9 @@ function applyPendingOps(view, list) {
|
|
|
859
889
|
const patch = {};
|
|
860
890
|
if (e.kind === "slack" && typeof p.name === "string" && p.name)
|
|
861
891
|
patch.name = p.name;
|
|
892
|
+
// 夜のまとめの url が正。無い行にだけ仮置きの url を足す
|
|
893
|
+
if (e.kind === "slack" && typeof p.url === "string" && p.url && !externals[idx].url)
|
|
894
|
+
patch.url = p.url;
|
|
862
895
|
if (typeof p.notify === "boolean")
|
|
863
896
|
patch.notify = p.notify;
|
|
864
897
|
externals[idx] = Object.assign({}, externals[idx], patch);
|
package/dist/render.js
CHANGED
|
@@ -4986,12 +4986,6 @@ a.pager-btn:hover { text-decoration: none; }
|
|
|
4986
4986
|
font-size: 12px; font-weight: 600; line-height: 1.6;
|
|
4987
4987
|
background: #eceef1; color: #41474f;
|
|
4988
4988
|
}
|
|
4989
|
-
.badge.cat-技術選定 { background: #e8f0ff; color: #1d4ed8; }
|
|
4990
|
-
.badge.cat-設計方針 { background: #e9f7ef; color: #1f7a45; }
|
|
4991
|
-
.badge.cat-運用ルール { background: #fdf0e3; color: #b45309; }
|
|
4992
|
-
.badge.cat-インフラ { background: #efe9fb; color: #6d28d9; }
|
|
4993
|
-
.badge.cat-ビジネス { background: #fde9ef; color: #be185d; }
|
|
4994
|
-
.badge.cat-デザイン { background: #fce7f3; color: #a21caf; }
|
|
4995
4989
|
.badge.draft { background: #fef3c7; color: #92400e; border: 1px solid #fcd34d; }
|
|
4996
4990
|
/* 直近のGold昇格で作られたレコードの印。draft(黄・要対応)と区別できるよう、新着を示す緑系にする */
|
|
4997
4991
|
.badge.latest { background: #dcfce7; color: #166534; border: 1px solid #86efac; }
|
|
@@ -5022,7 +5016,6 @@ a.pager-btn:hover { text-decoration: none; }
|
|
|
5022
5016
|
.story-card {
|
|
5023
5017
|
border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 18px; background: var(--surface);
|
|
5024
5018
|
}
|
|
5025
|
-
.story-card-focus { border-color: #2563eb; box-shadow: 0 0 0 2px rgba(37,99,235,0.25); }
|
|
5026
5019
|
.story-quiet { margin: -6px 0; padding: 0 18px; font-size: 12.5px; color: var(--muted); }
|
|
5027
5020
|
.story-quiet-date { font-variant-numeric: tabular-nums; }
|
|
5028
5021
|
.story-card-heading { margin: 0 0 8px; font-size: 15px; }
|
|
@@ -5312,10 +5305,9 @@ a.pager-btn:hover { text-decoration: none; }
|
|
|
5312
5305
|
.followup-section { margin: 14px 0 4px; }
|
|
5313
5306
|
/* 置き換え(#699 F3) */
|
|
5314
5307
|
.badge.retired { background: #f5f5f4; color: #57534e; border: 1px solid #d6d3d1; }
|
|
5315
|
-
/*
|
|
5316
|
-
.badge.now { background: #1d4ed8; color: #fff; }
|
|
5317
|
-
.card.is-now { border-left: 3px solid #1d4ed8; }
|
|
5308
|
+
/* 取り下げ済みルールの薄い表示 */
|
|
5318
5309
|
.card.is-faded { opacity: .55; }
|
|
5310
|
+
/* 論点・固さ(#1094)。欄の無い記録には付かない */
|
|
5319
5311
|
.badge.topic { background: #f5f3ff; color: #5b21b6; border: 1px solid #ddd6fe; font-weight: 500; }
|
|
5320
5312
|
.badge.firmness-fixed { background: #ecfdf5; color: #047857; border: 1px solid #a7f3d0; }
|
|
5321
5313
|
.badge.firmness-tentative { background: #fffbeb; color: #92400e; border: 1px solid #fde68a; }
|
|
@@ -6388,6 +6380,7 @@ var PENDING_OPS_SETTLE_MS = ${JSON.stringify(pending_ops_1.PENDING_OPS_LIMITS.se
|
|
|
6388
6380
|
var PENDING_KINDS = ${JSON.stringify((0, pending_ops_1.pendingKindsTable)())};
|
|
6389
6381
|
${pending_ops_1.pendingOpsKey.toString()}
|
|
6390
6382
|
${pending_ops_1.pendingSlackChannelId.toString()}
|
|
6383
|
+
${pending_ops_1.pendingSlackUrl.toString()}
|
|
6391
6384
|
${pending_ops_1.pendingGoogleChatSpaceRef.toString()}
|
|
6392
6385
|
${pending_ops_1.pendingRepo.toString()}
|
|
6393
6386
|
${pending_ops_1.pendingFigmaKey.toString()}
|
|
@@ -6790,9 +6783,6 @@ ${calendarAddUrl.toString()}
|
|
|
6790
6783
|
});
|
|
6791
6784
|
return img;
|
|
6792
6785
|
}
|
|
6793
|
-
function catBadge(cat) {
|
|
6794
|
-
return el("span", { class: "badge cat-" + cat, text: cat || "未分類" });
|
|
6795
|
-
}
|
|
6796
6786
|
// 未確認(status: draft = AI生成・人間未確認)の印。Gold層の4型(決定事項・用語集・メンバー・ルール)共通で、active・status無しには何も出さない
|
|
6797
6787
|
function draftBadge(rec) {
|
|
6798
6788
|
return rec && unconfirmed(rec) ? el("span", { class: "badge draft", text: "AI生成・未確認" }) : null;
|
|
@@ -7155,7 +7145,7 @@ ${calendarAddUrl.toString()}
|
|
|
7155
7145
|
* -------------------------------------------------------------------------
|
|
7156
7146
|
* 欄(topic / firmness / decidedBy)は**ビルド側で語彙・形を確かめてある**。欄の無い記録では
|
|
7157
7147
|
* キーごと無いので、画面は有無だけを見る。🔴 **欄の無い記録だけの案件では要素を 1 つも作らない**
|
|
7158
|
-
*
|
|
7148
|
+
* (絞り込み・固さの札・決めた人の節が出ない=今と同じ DOM)。
|
|
7159
7149
|
* 「置き換えられた」の判定は isRetired(ビルドが supersedes.ts で組んだ答え)をそのまま使う。
|
|
7160
7150
|
*/
|
|
7161
7151
|
function hasTopic(rec) {
|
|
@@ -7181,27 +7171,6 @@ ${calendarAddUrl.toString()}
|
|
|
7181
7171
|
}
|
|
7182
7172
|
return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
|
|
7183
7173
|
}
|
|
7184
|
-
/**
|
|
7185
|
-
* 札ごとの「今」の決定(一番新しく、置き換えられていない 1 件)の ID の集合。
|
|
7186
|
-
* 削除済みは数えない(一覧と同じ材料)
|
|
7187
|
-
*/
|
|
7188
|
-
function nowDecisionIds() {
|
|
7189
|
-
var best = {};
|
|
7190
|
-
visibleRecords(SITE.decisions).forEach(function (d) {
|
|
7191
|
-
if (!hasTopic(d) || isRetired(d)) return;
|
|
7192
|
-
var cur = best[d.topic];
|
|
7193
|
-
if (!cur || newestDecisionFirst(d, cur) < 0) best[d.topic] = d;
|
|
7194
|
-
});
|
|
7195
|
-
var ids = {};
|
|
7196
|
-
Object.keys(best).forEach(function (t) { ids[best[t].id] = true; });
|
|
7197
|
-
return ids;
|
|
7198
|
-
}
|
|
7199
|
-
function isNowDecision(rec) {
|
|
7200
|
-
return !!(rec && rec._kind === "decision" && hasTopic(rec) && nowDecisionIds()[rec.id]);
|
|
7201
|
-
}
|
|
7202
|
-
function nowBadge(rec) {
|
|
7203
|
-
return isNowDecision(rec) ? el("span", { class: "badge now", title: "この論点で今有効な決定", text: "今" }) : null;
|
|
7204
|
-
}
|
|
7205
7174
|
/** 論点の札(一覧の行)。札が無ければ null */
|
|
7206
7175
|
function topicBadge(rec) {
|
|
7207
7176
|
return hasTopic(rec) ? el("span", { class: "badge topic", title: "論点", text: rec.topic }) : null;
|
|
@@ -7213,10 +7182,6 @@ ${calendarAddUrl.toString()}
|
|
|
7213
7182
|
if (typeof f !== "string" || !Object.prototype.hasOwnProperty.call(FIRMNESS_CLASS, f)) return null;
|
|
7214
7183
|
return el("span", { class: "badge firmness firmness-" + FIRMNESS_CLASS[f], title: "固さ", text: f });
|
|
7215
7184
|
}
|
|
7216
|
-
/** 置き換えられた決定を薄く出すか(論点の札を持つ決定だけ。欄の無い記録の見た目は変えない) */
|
|
7217
|
-
function fadedClass(rec) {
|
|
7218
|
-
return hasTopic(rec) && isRetired(rec) ? " is-faded" : "";
|
|
7219
|
-
}
|
|
7220
7185
|
/** 決めた人 1 人の札。関係者が名簿にあればそのページへ、{name, url} は url があれば元の URL へ */
|
|
7221
7186
|
function decidedByChip(who) {
|
|
7222
7187
|
if (!who || typeof who !== "object") return null;
|
|
@@ -8407,7 +8372,6 @@ ${calendarAddUrl.toString()}
|
|
|
8407
8372
|
// 文中のリンクは「押したら進む=戻れる」に見えるので、そちらだけ積む
|
|
8408
8373
|
function switchTab(tabKey, push) {
|
|
8409
8374
|
listState.tab = tabKey;
|
|
8410
|
-
storyFocus = null;
|
|
8411
8375
|
listState.page = 1;
|
|
8412
8376
|
if (push) history.pushState({}, "", tabUrl(tabKey));
|
|
8413
8377
|
else history.replaceState(null, "", tabUrl(tabKey));
|
|
@@ -8544,7 +8508,7 @@ ${calendarAddUrl.toString()}
|
|
|
8544
8508
|
}
|
|
8545
8509
|
}
|
|
8546
8510
|
|
|
8547
|
-
var listState = { tab: DEFAULT_TAB, q: "",
|
|
8511
|
+
var listState = { tab: DEFAULT_TAB, q: "", month: "", status: "", topic: "", page: 1 };
|
|
8548
8512
|
|
|
8549
8513
|
// 一覧のページネーション(描画コスト対策。1ページあたりの件数)
|
|
8550
8514
|
var PAGE_SIZE = 30;
|
|
@@ -8689,8 +8653,6 @@ ${calendarAddUrl.toString()}
|
|
|
8689
8653
|
var STORY_SUB_DEFAULT = "daily";
|
|
8690
8654
|
var STORY_SUBS = [["daily", "日次"], ["weekly", "週次"], ["monthly", "月次"]];
|
|
8691
8655
|
var storySub = STORY_SUB_DEFAULT;
|
|
8692
|
-
// 記録の詳細の「この日のストーリー」から着いたときに目立たせる日(日次)・週の月曜(週次)。URL の ?day= / ?week=(engine #551)
|
|
8693
|
-
var storyFocus = null;
|
|
8694
8656
|
|
|
8695
8657
|
function storySubUrl(sub) {
|
|
8696
8658
|
return sub === STORY_SUB_DEFAULT ? "?tab=story" : "?tab=story&sub=" + encodeURIComponent(sub);
|
|
@@ -8698,7 +8660,6 @@ ${calendarAddUrl.toString()}
|
|
|
8698
8660
|
function switchStorySub(sub) {
|
|
8699
8661
|
if (storySub === sub) return;
|
|
8700
8662
|
storySub = sub;
|
|
8701
|
-
storyFocus = null;
|
|
8702
8663
|
history.replaceState(null, "", storySubUrl(sub));
|
|
8703
8664
|
renderList();
|
|
8704
8665
|
}
|
|
@@ -8721,7 +8682,7 @@ ${calendarAddUrl.toString()}
|
|
|
8721
8682
|
]));
|
|
8722
8683
|
return;
|
|
8723
8684
|
}
|
|
8724
|
-
list.appendChild(el("section", { class: "story-card"
|
|
8685
|
+
list.appendChild(el("section", { class: "story-card" }, [
|
|
8725
8686
|
el("h3", { class: "story-card-heading", text: d.heading || d.date }),
|
|
8726
8687
|
d.bodyHtml ? el("div", { class: "body", html: d.bodyHtml }) : null,
|
|
8727
8688
|
// その日のファイルを GitHub で開く(表示の文字にファイル名を出さない)。URL が無い案件は出さない
|
|
@@ -8737,7 +8698,7 @@ ${calendarAddUrl.toString()}
|
|
|
8737
8698
|
el("h4", { text: "人の追記" }),
|
|
8738
8699
|
el("div", { class: "body", html: entry.humanHtml }),
|
|
8739
8700
|
]) : null;
|
|
8740
|
-
return el("section", { class: "story-card"
|
|
8701
|
+
return el("section", { class: "story-card" }, [
|
|
8741
8702
|
el("h3", { class: "story-card-heading", text: entry.heading }),
|
|
8742
8703
|
entry.phase ? el("p", { class: "story-phase" }, [
|
|
8743
8704
|
el("span", { class: "story-phase-label", text: phaseLabel }),
|
|
@@ -8839,53 +8800,6 @@ ${calendarAddUrl.toString()}
|
|
|
8839
8800
|
if (storySub === "weekly") renderStoryWeekly();
|
|
8840
8801
|
else if (storySub === "monthly") renderStoryMonthly();
|
|
8841
8802
|
else renderStoryDaily();
|
|
8842
|
-
// 記録の詳細から着いた日(週)のカードを目立たせて、そこまで送る
|
|
8843
|
-
if (storyFocus) {
|
|
8844
|
-
var focused = null;
|
|
8845
|
-
app.querySelectorAll(".story-card[data-story-key]").forEach(function (c) {
|
|
8846
|
-
if (!focused && c.getAttribute("data-story-key") === storyFocus) focused = c;
|
|
8847
|
-
});
|
|
8848
|
-
if (focused) {
|
|
8849
|
-
focused.classList.add("story-card-focus");
|
|
8850
|
-
if (typeof focused.scrollIntoView === "function") focused.scrollIntoView({ block: "start" });
|
|
8851
|
-
}
|
|
8852
|
-
}
|
|
8853
|
-
}
|
|
8854
|
-
|
|
8855
|
-
/**
|
|
8856
|
-
* 記録の日付から「その日のストーリー」の行き先を決める(engine #551・オーナー決定 10/1)。
|
|
8857
|
-
* その日の日次のカード(動きのあった日)があれば日次へ、無ければその日を含む週のあらすじへ。どちらも無ければ null(リンクを出さない)
|
|
8858
|
-
*/
|
|
8859
|
-
function storyTargetOf(date) {
|
|
8860
|
-
if (!date || !/^\\d{4}-\\d{2}-\\d{2}$/.test(date) || !hasTab("story")) return null;
|
|
8861
|
-
var days = SITE.story || [];
|
|
8862
|
-
for (var i = 0; i < days.length; i++) {
|
|
8863
|
-
if (!days[i].quiet && days[i].date === date) return { sub: "daily", key: date, href: "?tab=story&day=" + encodeURIComponent(date) };
|
|
8864
|
-
}
|
|
8865
|
-
var weeks = (SITE.storyDigest && SITE.storyDigest.weeks) || [];
|
|
8866
|
-
var monday = storyMondayOf(date);
|
|
8867
|
-
for (var j = 0; j < weeks.length; j++) {
|
|
8868
|
-
if (weeks[j].key === monday) return { sub: "weekly", key: monday, href: "?tab=story&sub=weekly&week=" + encodeURIComponent(monday) };
|
|
8869
|
-
}
|
|
8870
|
-
return null;
|
|
8871
|
-
}
|
|
8872
|
-
/** 記録の詳細の「この日のストーリー」(行き先が無ければ null) */
|
|
8873
|
-
function storyLinkFor(rec) {
|
|
8874
|
-
var target = storyTargetOf(rec && rec.date);
|
|
8875
|
-
if (!target) return null;
|
|
8876
|
-
var a = el("a", { class: "trace-btn story-link-btn", href: target.href, text: target.sub === "daily" ? "📖 この日のストーリー" : "📖 この週のストーリー" });
|
|
8877
|
-
a.addEventListener("click", function (ev) {
|
|
8878
|
-
// 新しいタブで開く操作(修飾キー・中ボタン)はブラウザに任せる(href は本物の URL)
|
|
8879
|
-
if (ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey || (typeof ev.button === "number" && ev.button !== 0)) return;
|
|
8880
|
-
ev.preventDefault();
|
|
8881
|
-
listState.tab = "story";
|
|
8882
|
-
storySub = target.sub;
|
|
8883
|
-
storyFocus = target.key;
|
|
8884
|
-
lastWasDetail = false;
|
|
8885
|
-
history.pushState({}, "", target.href);
|
|
8886
|
-
renderList();
|
|
8887
|
-
});
|
|
8888
|
-
return a;
|
|
8889
8803
|
}
|
|
8890
8804
|
|
|
8891
8805
|
// 導入経緯(overview.adoption)の表示情報。Home見出し横のチップに出すラベルだけを返す。
|
|
@@ -14187,7 +14101,7 @@ ${calendarAddUrl.toString()}
|
|
|
14187
14101
|
callIntake("config", payload).then(function (res) {
|
|
14188
14102
|
if (!res.ok) return;
|
|
14189
14103
|
// 仮置き(#388): リロードしても新しい名前で出る。送っていない name を判定用に添える
|
|
14190
|
-
notePendingOp({ op: "refresh-channel-name", ref: s.ref, name: r.name });
|
|
14104
|
+
notePendingOp({ op: "refresh-channel-name", ref: s.ref, name: r.name, url: s.url || "" });
|
|
14191
14105
|
// 一覧は夜間のスナップショットなので、その場では変わらない。行だけ追いつかせる
|
|
14192
14106
|
var nameEl = card.querySelector(".ds-name");
|
|
14193
14107
|
if (nameEl) nameEl.textContent = slackDisplayName(r.name);
|
|
@@ -14244,6 +14158,22 @@ ${calendarAddUrl.toString()}
|
|
|
14244
14158
|
var payload = { type: probeTypeOf(s.type), ref: s.ref };
|
|
14245
14159
|
if (s.workspace) payload.workspace = s.workspace;
|
|
14246
14160
|
try {
|
|
14161
|
+
// 🔴 **組織が分からない行は、確認の前に所属を判定し直す。** 表示のたびの自動判定
|
|
14162
|
+
// (requestOrgResolve)は 1 回きりで、アプリを招待したあとに押しても直らなかった。
|
|
14163
|
+
// 判定できたら、社内の鍵で測った結果(届かない)を出さず、反映したことと次の一手を伝える
|
|
14164
|
+
if (s.type === "slack" && s.orgUnknown === true) {
|
|
14165
|
+
try {
|
|
14166
|
+
var rr = await callIntake("slack-resolve", {});
|
|
14167
|
+
var rj = rr.ok ? await rr.json().catch(function () { return null; }) : null;
|
|
14168
|
+
if (rj && rj.resolved) {
|
|
14169
|
+
wrap.className = "ds-probe is-shown";
|
|
14170
|
+
msg.className = "ds-toggle-msg";
|
|
14171
|
+
msg.textContent = "✓ " + rj.resolved + "件の所属ワークスペースを反映しました。一覧の表示は次回の更新から正しくなります。";
|
|
14172
|
+
endBusy();
|
|
14173
|
+
return;
|
|
14174
|
+
}
|
|
14175
|
+
} catch (resolveErr) { /* 判定し直せなくても、そのまま確認へ進む */ }
|
|
14176
|
+
}
|
|
14247
14177
|
var res = await callIntake("probe", payload);
|
|
14248
14178
|
var j = await res.json().catch(function () { return {}; });
|
|
14249
14179
|
if (!res.ok) {
|
|
@@ -19727,7 +19657,6 @@ ${calendarAddUrl.toString()}
|
|
|
19727
19657
|
if (SITE.months && SITE.months.length) {
|
|
19728
19658
|
filters.appendChild(buildSelect("すべての期間", SITE.months, listState.month, function (v) { listState.month = v; listState.page = 1; drawCards(); }, monthLabel));
|
|
19729
19659
|
}
|
|
19730
|
-
filters.appendChild(buildSelect("すべてのカテゴリー", SITE.categories, listState.category, function (v) { listState.category = v; listState.page = 1; drawCards(); }));
|
|
19731
19660
|
var statusOptsD = statusFilterOptions(visibleRecords(SITE.decisions));
|
|
19732
19661
|
if (statusOptsD.length) {
|
|
19733
19662
|
filters.appendChild(buildSelect("すべての状態", statusOptsD, listState.status, function (v) { listState.status = v; listState.page = 1; drawCards(); }, statusLabel));
|
|
@@ -19762,7 +19691,7 @@ ${calendarAddUrl.toString()}
|
|
|
19762
19691
|
}
|
|
19763
19692
|
|
|
19764
19693
|
/**
|
|
19765
|
-
*
|
|
19694
|
+
* 今の絞り込み(検索語・期間・状態・論点)を当てた決定の一覧(並びは
|
|
19766
19695
|
* SITE.decisions の順=新しい順のまま)。drawCards と、詳細の「前へ/次へ」
|
|
19767
19696
|
* (#2)の両方がここを通る——一覧の並びと前後移動の並びがずれないように、口を1つにする。
|
|
19768
19697
|
*/
|
|
@@ -19772,7 +19701,6 @@ ${calendarAddUrl.toString()}
|
|
|
19772
19701
|
var all = visibleRecords(SITE.decisions);
|
|
19773
19702
|
var out = all.filter(function (d) {
|
|
19774
19703
|
if (listState.month && d.date.slice(0, 7) !== listState.month) return false;
|
|
19775
|
-
if (listState.category && d.category !== listState.category) return false;
|
|
19776
19704
|
if (!matchesStatusFilter(d)) return false;
|
|
19777
19705
|
if (!matchesTopicFilter(d)) return false;
|
|
19778
19706
|
if (q) {
|
|
@@ -19811,12 +19739,10 @@ ${calendarAddUrl.toString()}
|
|
|
19811
19739
|
|
|
19812
19740
|
pg.slice.forEach(function (d) {
|
|
19813
19741
|
var meta = el("div", { class: "card-meta" }, [
|
|
19814
|
-
nowBadge(d),
|
|
19815
19742
|
draftBadge(d),
|
|
19816
19743
|
retiredBadge(d),
|
|
19817
19744
|
latestBadge(d),
|
|
19818
19745
|
el("span", { class: "mono", text: d.date || "----" }),
|
|
19819
|
-
catBadge(d.category),
|
|
19820
19746
|
firmnessBadge(d),
|
|
19821
19747
|
topicBadge(d),
|
|
19822
19748
|
]);
|
|
@@ -19825,7 +19751,7 @@ ${calendarAddUrl.toString()}
|
|
|
19825
19751
|
var traceD = el("a", { class: "mc-trace", href: "?tab=graph", text: "🕸 つながり" });
|
|
19826
19752
|
traceD.addEventListener("click", function (ev) { ev.preventDefault(); ev.stopPropagation(); openExplorerFor(d); });
|
|
19827
19753
|
meta.appendChild(traceD);
|
|
19828
|
-
var card = el("div", { class: "card"
|
|
19754
|
+
var card = el("div", { class: "card", title: d.id, "data-record-id": d.id }, [
|
|
19829
19755
|
meta,
|
|
19830
19756
|
// 消したレコードは一覧でも取り消し線(次のビルドまで一覧には残る)
|
|
19831
19757
|
cardTitleLink(d, d.deleted ? " is-deleted" : ""),
|
|
@@ -20716,7 +20642,7 @@ ${calendarAddUrl.toString()}
|
|
|
20716
20642
|
// 警告帯が出ない記録の削除の口はここ(編集の行の末尾)。draft には出さない
|
|
20717
20643
|
var delMsgR = attachDeleteToEditRow(r, editRowR);
|
|
20718
20644
|
head.appendChild(el("div", { class: "detail-actions" }, [
|
|
20719
|
-
el("div", { class: "detail-actions-row" }, [ traceBtn2
|
|
20645
|
+
el("div", { class: "detail-actions-row" }, [ traceBtn2 ]),
|
|
20720
20646
|
editRowR.children.length ? editRowR : null,
|
|
20721
20647
|
delMsgR,
|
|
20722
20648
|
]));
|
|
@@ -21658,19 +21584,17 @@ ${calendarAddUrl.toString()}
|
|
|
21658
21584
|
// 警告帯が出ない記録の削除の口はここ(編集の行の末尾)。draft には出さない
|
|
21659
21585
|
var delMsgD = attachDeleteToEditRow(d, editRowD);
|
|
21660
21586
|
head.appendChild(el("div", { class: "detail-actions" }, [
|
|
21661
|
-
el("div", { class: "detail-actions-row" }, [ traceBtn
|
|
21587
|
+
el("div", { class: "detail-actions-row" }, [ traceBtn ]),
|
|
21662
21588
|
editRowD.children.length ? editRowD : null,
|
|
21663
21589
|
delMsgD,
|
|
21664
21590
|
]));
|
|
21665
21591
|
app.appendChild(head);
|
|
21666
21592
|
|
|
21667
21593
|
var meta = el("div", { class: "detail-meta" }, [
|
|
21668
|
-
nowBadge(d),
|
|
21669
21594
|
draftBadge(d),
|
|
21670
21595
|
retiredBadge(d),
|
|
21671
21596
|
latestBadge(d),
|
|
21672
21597
|
el("span", { class: "mono", text: d.date || "----" }),
|
|
21673
|
-
catBadge(d.category),
|
|
21674
21598
|
firmnessBadge(d),
|
|
21675
21599
|
]);
|
|
21676
21600
|
meta.title = d.id;
|
|
@@ -22188,8 +22112,6 @@ ${calendarAddUrl.toString()}
|
|
|
22188
22112
|
var validSub = false;
|
|
22189
22113
|
STORY_SUBS.forEach(function (s) { if (s[0] === sub) validSub = true; });
|
|
22190
22114
|
storySub = validSub ? sub : STORY_SUB_DEFAULT;
|
|
22191
|
-
var focusKey = storySub === "weekly" ? getParam("week") : storySub === "daily" ? getParam("day") : null;
|
|
22192
|
-
storyFocus = focusKey && /^\\d{4}-\\d{2}-\\d{2}$/.test(focusKey) ? focusKey : null;
|
|
22193
22115
|
}
|
|
22194
22116
|
renderList();
|
|
22195
22117
|
}
|
package/package.json
CHANGED