@takagaki/cortex-decisions-viewer 0.12.55 → 0.12.56
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/dist/render.js +215 -9
- package/package.json +1 -1
package/dist/render.js
CHANGED
|
@@ -37,6 +37,10 @@ exports.sanitizeCapabilitiesNow = sanitizeCapabilitiesNow;
|
|
|
37
37
|
exports.sanitizeGithubOwnersNow = sanitizeGithubOwnersNow;
|
|
38
38
|
exports.splitNeededParts = splitNeededParts;
|
|
39
39
|
exports.ingestedAtOf = ingestedAtOf;
|
|
40
|
+
exports.ingestedRowOf = ingestedRowOf;
|
|
41
|
+
exports.runLogUrlOf = runLogUrlOf;
|
|
42
|
+
exports.lastSyncRunUrlOf = lastSyncRunUrlOf;
|
|
43
|
+
exports.runSourceWordOf = runSourceWordOf;
|
|
40
44
|
exports.fleetLastSyncOf = fleetLastSyncOf;
|
|
41
45
|
exports.stateRefKey = stateRefKey;
|
|
42
46
|
exports.registeredRefKeys = registeredRefKeys;
|
|
@@ -977,7 +981,23 @@ const STATE_STATUSES = {
|
|
|
977
981
|
// 「作成済み」の行が overlay に届く前に落ちて、画面は永久に「作成中」のまま
|
|
978
982
|
calendar: ["requested", "ok", "failed"],
|
|
979
983
|
};
|
|
980
|
-
const STATE_ROW_FIELDS = ["cap", "ref", "workspace", "question", "status", "at", "by", "needed", "detail", "lastOkAt", "lastFailAt"];
|
|
984
|
+
const STATE_ROW_FIELDS = ["cap", "ref", "workspace", "question", "status", "at", "by", "needed", "detail", "lastOkAt", "lastFailAt", "runUrl"];
|
|
985
|
+
/**
|
|
986
|
+
* 行の `runUrl`(その行を書いた GitHub Actions の run・#560)に許す形。**原本は
|
|
987
|
+
* `infra/lambda/shared/connection-state-keys.mjs` の `RUN_URL_RE`**で、これはその写し
|
|
988
|
+
* (画面は `href` にそのまま置くので、intake が篩ったあとでも画面側でもう一度縛る)。
|
|
989
|
+
* 埋め込み JS には `var RUN_URL_RE` として注入する(export すると `exports.` 参照が客先へ
|
|
990
|
+
* 渡って画面が死ぬ——`state-vocab-parity.test.mjs` 冒頭の実害)。
|
|
991
|
+
*/
|
|
992
|
+
const RUN_URL_RE = /^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/actions\/runs\/[0-9]+$/;
|
|
993
|
+
/** `runUrl` を持てる書き手(Actions の run の中で動く engine の書き手)。ほかの書き手の値は出さない */
|
|
994
|
+
const RUN_URL_WRITERS = ["ingest", "gold", "nightly"];
|
|
995
|
+
/**
|
|
996
|
+
* `runUrl` が無い行の出どころの語(#560)。run が無い書き手だけ。**`ingest` / `gold` は
|
|
997
|
+
* 載せない**——`runUrl` が無いのは古い engine か固定 IP の CodeBuild で、行からは区別できない
|
|
998
|
+
* (「Webhook」と断定すると嘘になる)
|
|
999
|
+
*/
|
|
1000
|
+
const RUN_SOURCE_WORDS = { central: "中央の処理", button: "その場で確認", auto: "保存時に確認" };
|
|
981
1001
|
/** stateNow はライブ専用キーで build.ts の網にかからない。画面側でも許可リストを通す */
|
|
982
1002
|
function sanitizeStateNow(v) {
|
|
983
1003
|
if (!Array.isArray(v))
|
|
@@ -999,6 +1019,9 @@ function sanitizeStateNow(v) {
|
|
|
999
1019
|
continue; // 知らない語は「不明」に化けさせず落とす
|
|
1000
1020
|
if (!item.cap || !item.ref || !item.at)
|
|
1001
1021
|
continue;
|
|
1022
|
+
// `runUrl` は run ページの形だけ(#560)。形が違えば**欄だけ落として行は残す**
|
|
1023
|
+
if (item.runUrl && !RUN_URL_RE.test(item.runUrl))
|
|
1024
|
+
delete item.runUrl;
|
|
1002
1025
|
out.push(item);
|
|
1003
1026
|
}
|
|
1004
1027
|
return out.length ? out : null;
|
|
@@ -1079,6 +1102,8 @@ function overlayStateOnFleet(view, rows) {
|
|
|
1079
1102
|
gateBy: hit.by,
|
|
1080
1103
|
needed: hit.needed || "",
|
|
1081
1104
|
detail: hit.detail || "",
|
|
1105
|
+
// その行を書いた run(#560)。無ければ空
|
|
1106
|
+
gateRunUrl: hit.runUrl || "",
|
|
1082
1107
|
});
|
|
1083
1108
|
});
|
|
1084
1109
|
return changed ? Object.assign({}, v, { externalSources: externals }) : v;
|
|
@@ -1922,6 +1947,75 @@ function ingestedAtOf(rows, capId, refs) {
|
|
|
1922
1947
|
}
|
|
1923
1948
|
return best;
|
|
1924
1949
|
}
|
|
1950
|
+
/**
|
|
1951
|
+
* `ingestedAtOf` と**同じ選び方**で、時刻ではなく**その行**を返す(#560)。「最終同期」の横に
|
|
1952
|
+
* 「実行ログ」を出すために要る。選び方をここに書き写さず、同じ規則で行を選ぶ
|
|
1953
|
+
* (分かれると「最終同期の時刻」と「そのリンク先の run」が別の行のものになる)。
|
|
1954
|
+
*
|
|
1955
|
+
* **クロージャを持たない純関数に保つこと**(`.toString()` でクライアントへ渡す)。
|
|
1956
|
+
* @returns 選んだ行。1件も無ければ null
|
|
1957
|
+
*/
|
|
1958
|
+
function ingestedRowOf(rows, capId, refs) {
|
|
1959
|
+
if (!Array.isArray(rows) || !capId)
|
|
1960
|
+
return null;
|
|
1961
|
+
let best = "";
|
|
1962
|
+
let bestRow = null;
|
|
1963
|
+
for (const r of rows) {
|
|
1964
|
+
if (!r || r.cap !== capId || r.question !== "ingested")
|
|
1965
|
+
continue;
|
|
1966
|
+
if (refs && !refs[stateRefKey(capId, r.ref, r.workspace)])
|
|
1967
|
+
continue;
|
|
1968
|
+
const at = r.lastOkAt || (r.status === "ok" ? r.at : "");
|
|
1969
|
+
if (typeof at === "string" && at > best) {
|
|
1970
|
+
best = at;
|
|
1971
|
+
bestRow = r;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
return bestRow;
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* 行の横に出す「実行ログ」のリンク先(#560)。**無ければ空文字。**
|
|
1978
|
+
*
|
|
1979
|
+
* 出すのは Actions の run の中で動く書き手(`RUN_URL_WRITERS`)の行だけ。ボタン・中央の
|
|
1980
|
+
* 書き手は intake が `runUrl` を消して書くが、画面側でも二重の網にする——残っていると
|
|
1981
|
+
* 「いま測った結果」の横に別の run のログが出る。形は `RUN_URL_RE`(`href` にそのまま置く)。
|
|
1982
|
+
*
|
|
1983
|
+
* **クロージャを持たない純関数に保つこと**(`.toString()` でクライアントへ渡す)。
|
|
1984
|
+
*/
|
|
1985
|
+
function runLogUrlOf(row) {
|
|
1986
|
+
if (!row || typeof row.runUrl !== "string" || !RUN_URL_RE.test(row.runUrl))
|
|
1987
|
+
return "";
|
|
1988
|
+
if (RUN_URL_WRITERS.indexOf(String(row.by || "")) < 0)
|
|
1989
|
+
return "";
|
|
1990
|
+
return row.runUrl;
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* 「最終同期: …」の横に出すリンク先(#560)。**その時刻を書いた run のときだけ。**
|
|
1994
|
+
*
|
|
1995
|
+
* 「最終同期」は `lastOkAt`(最後に取り込めた時刻)で、行の `runUrl` は**いまの status を
|
|
1996
|
+
* 書いた run**のもの。いま `failed` の行の `lastOkAt` が最大なら、その `runUrl` は失敗した run
|
|
1997
|
+
* を指すので出さない(間違った run へ送るより、無いほうがよい)。`ok` の行でも `lastOkAt` と
|
|
1998
|
+
* `statusAt` が違う(履歴だけ先に進んだ)回は出さない。
|
|
1999
|
+
*
|
|
2000
|
+
* **クロージャを持たない純関数に保つこと**(`.toString()` でクライアントへ渡す)。
|
|
2001
|
+
*/
|
|
2002
|
+
function lastSyncRunUrlOf(row) {
|
|
2003
|
+
if (!row || row.status !== "ok")
|
|
2004
|
+
return "";
|
|
2005
|
+
if (row.lastOkAt && row.lastOkAt !== row.at)
|
|
2006
|
+
return "";
|
|
2007
|
+
return runLogUrlOf(row);
|
|
2008
|
+
}
|
|
2009
|
+
/**
|
|
2010
|
+
* `runUrl` の無い行に添える出どころの語(#560)。リンクが出る行・語の無い書き手は空文字。
|
|
2011
|
+
*
|
|
2012
|
+
* **クロージャを持たない純関数に保つこと**(`.toString()` でクライアントへ渡す)。
|
|
2013
|
+
*/
|
|
2014
|
+
function runSourceWordOf(row) {
|
|
2015
|
+
if (!row || runLogUrlOf(row))
|
|
2016
|
+
return "";
|
|
2017
|
+
return RUN_SOURCE_WORDS[String(row.by || "")] || "";
|
|
2018
|
+
}
|
|
1925
2019
|
/**
|
|
1926
2020
|
* まとめ表(fleet-status.json)の「最終同期」を、画面に出してよい形で取る(#523 決定1)。
|
|
1927
2021
|
*
|
|
@@ -3926,6 +4020,12 @@ a.ds-tile:hover { text-decoration: none; }
|
|
|
3926
4020
|
.ds-all-connected { color: var(--muted); }
|
|
3927
4021
|
.ds-gate { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 600; flex: 0 0 auto; }
|
|
3928
4022
|
.ds-gate-at { font-size: 11px; color: var(--muted); flex: 0 0 auto; }
|
|
4023
|
+
/* 実行ログへの導線(#560)。時刻の横の添え物なので .ds-gate-at と同じ弱さ。押せることだけ
|
|
4024
|
+
点線の下線で示す(目立たせない——案件リポジトリに入っていない人には開けない) */
|
|
4025
|
+
.ds-run-link { font-size: 11px; color: var(--muted); flex: 0 0 auto; text-decoration: underline dotted; text-underline-offset: 2px; }
|
|
4026
|
+
.ds-run-link:hover { color: var(--text); }
|
|
4027
|
+
/* run の無い書き手の行の出どころ(「中央の処理」「その場で確認」)。同じ弱さの文字 */
|
|
4028
|
+
.ds-run-src { font-size: 11px; color: var(--muted); flex: 0 0 auto; }
|
|
3929
4029
|
/* 接続先1件ごとの「取り込み」(段C・2026-08-24)。**「最終同期」(.ds-sync・run単位)とは
|
|
3930
4030
|
別の行に並ぶ**ので、同じ強さにしない——run の時刻より弱い添え物として読ませる。
|
|
3931
4031
|
失敗だけは .ds-gate-warn と同じ色にする(同じ画面で警告の色が2種類あると、
|
|
@@ -4490,6 +4590,12 @@ ${pending_ops_1.pendingCountDelta.toString()}
|
|
|
4490
4590
|
${pending_ops_1.pendingIssuesRef.toString()}
|
|
4491
4591
|
var STATE_STATUSES = ${JSON.stringify(STATE_STATUSES)};
|
|
4492
4592
|
var STATE_ROW_FIELDS = ${JSON.stringify(STATE_ROW_FIELDS)};
|
|
4593
|
+
// 行の runUrl の形と、出どころの語(#560)。**正規表現は JSON にできない**ので
|
|
4594
|
+
// source から組み立てる。この定数行を落とすと sanitizeStateNow が未定義を参照して
|
|
4595
|
+
// ライブ取得が丸ごと死ぬ
|
|
4596
|
+
var RUN_URL_RE = new RegExp(${JSON.stringify(RUN_URL_RE.source)});
|
|
4597
|
+
var RUN_URL_WRITERS = ${JSON.stringify(RUN_URL_WRITERS)};
|
|
4598
|
+
var RUN_SOURCE_WORDS = ${JSON.stringify(RUN_SOURCE_WORDS)};
|
|
4493
4599
|
${sanitizeStateNow.toString()}
|
|
4494
4600
|
${overlayStateOnFleet.toString()}
|
|
4495
4601
|
// Home の「使用ツール」(#275)。**判定と表示語の実体はビルド時の定義**——
|
|
@@ -4522,6 +4628,10 @@ ${stateRefKey.toString()}
|
|
|
4522
4628
|
${registeredRefKeys.toString()}
|
|
4523
4629
|
${fleetLastSyncOf.toString()}
|
|
4524
4630
|
${ingestedAtOf.toString()}
|
|
4631
|
+
${ingestedRowOf.toString()}
|
|
4632
|
+
${runLogUrlOf.toString()}
|
|
4633
|
+
${lastSyncRunUrlOf.toString()}
|
|
4634
|
+
${runSourceWordOf.toString()}
|
|
4525
4635
|
var TILE_CAPS = ${JSON.stringify(TILE_CAPS)};
|
|
4526
4636
|
var BAD_STATE_STATUSES = ${JSON.stringify(BAD_STATE_STATUSES)};
|
|
4527
4637
|
// 登録直後の一時表示(#523 決定6)。**この定数行を落とすと、流し込んだ deriveCapTile が
|
|
@@ -8998,9 +9108,18 @@ ${calendarAddUrl.toString()}
|
|
|
8998
9108
|
function capBlockSyncEl(s, inactive) {
|
|
8999
9109
|
if (inactive || !s || !s.kind) return null;
|
|
9000
9110
|
var capId = capIdOf(s.kind);
|
|
9001
|
-
var
|
|
9111
|
+
var refs = capId ? refKeysOf(derCapOf(s.kind, "")) : null;
|
|
9112
|
+
var at = capId ? ingestedAtOf(LIVE_STATE, capId, refs) : "";
|
|
9002
9113
|
var t = dsFmtTime(at || fleetSyncFallback(s) || "");
|
|
9003
|
-
|
|
9114
|
+
if (!t) return null;
|
|
9115
|
+
var sync = el("span", { class: "ds-sync", text: "最終同期: " + t });
|
|
9116
|
+
// その時刻を書いた run へ(#560)。**ストア由来の時刻のときだけ**——まとめ表の後詰めに
|
|
9117
|
+
// run は無い。行は「ingestedAtOf」 と同じ選び方(「ingestedRowOf」)で取る。
|
|
9118
|
+
// run の無い書き手(中央 Apps Script の会議・資料の取り込み)は出どころの語
|
|
9119
|
+
var row = at ? ingestedRowOf(LIVE_STATE, capId, refs) : null;
|
|
9120
|
+
var url = lastSyncRunUrlOf(row);
|
|
9121
|
+
var trail = url ? [runLogLink(url)] : row ? runTrailNodes(row, "") : [];
|
|
9122
|
+
return trail.length ? frag([sync].concat(trail)) : sync;
|
|
9004
9123
|
}
|
|
9005
9124
|
|
|
9006
9125
|
if (internals.length) {
|
|
@@ -10365,6 +10484,8 @@ ${calendarAddUrl.toString()}
|
|
|
10365
10484
|
// 古い「X分前に確認」を残さない(下に出るいまの結果と、時刻が2つ並ぶ)
|
|
10366
10485
|
var oldAt = card.querySelector(".ds-gate-at");
|
|
10367
10486
|
if (oldAt) oldAt.remove();
|
|
10487
|
+
// 古い run の導線も残さない(#560)。「いま測った結果」の横に夜間の run のログが並ぶ形になる
|
|
10488
|
+
removeRunTrail(card);
|
|
10368
10489
|
// 🔴 **古いスコープ名の札も必ず消してから出し直す。** 行には夜間の判定に添えた
|
|
10369
10490
|
// 札が出ていることがあり(段B)、置き換えた「接続OK」の横に古いスコープ名が
|
|
10370
10491
|
// 残ると、同じ行が2つのことを言う——この節が何度も直してきた形そのもの。
|
|
@@ -10817,6 +10938,59 @@ ${calendarAddUrl.toString()}
|
|
|
10817
10938
|
return null;
|
|
10818
10939
|
}
|
|
10819
10940
|
|
|
10941
|
+
/* -------------------------------------------------------------------------
|
|
10942
|
+
* 実行ログへの導線(#560)
|
|
10943
|
+
* -------------------------------------------------------------------------
|
|
10944
|
+
* 行の 「runUrl」(その行を書いた Actions の run)があれば、時刻の横に小さな「実行ログ ↗」を
|
|
10945
|
+
* 出す。run の無い書き手の行は、出どころを語で示す(「中央の処理」「その場で確認」)。
|
|
10946
|
+
* どちらを出すかの判断は純関数(runLogUrlOf / runSourceWordOf)が持ち、ここは描くだけ。
|
|
10947
|
+
* ----------------------------------------------------------------------- */
|
|
10948
|
+
|
|
10949
|
+
/** リンクの title。案件リポジトリに入っていない人には開けないので、押す前に分かるようにする */
|
|
10950
|
+
var RUN_LINK_TITLE = "GitHub Actions の実行ログを開きます(案件リポジトリへのアクセスが要ります)";
|
|
10951
|
+
/** 一覧(開始直後・run の番号がまだ無い)の title。飛び先が違うので文言も分ける */
|
|
10952
|
+
var RUN_LIST_TITLE = "GitHub Actions の実行の一覧を開きます(案件リポジトリへのアクセスが要ります)";
|
|
10953
|
+
var RUN_LIST_TEXT = "実行の一覧 ↗";
|
|
10954
|
+
|
|
10955
|
+
/** 「実行ログ ↗」(新しいタブ・title つき)。一覧のときは文言と title を一覧のものにする */
|
|
10956
|
+
function runLogLink(url, text) {
|
|
10957
|
+
var list = text === RUN_LIST_TEXT;
|
|
10958
|
+
return el("a", { class: "ds-run-link", href: url, target: "_blank", rel: "noopener", title: list ? RUN_LIST_TITLE : RUN_LINK_TITLE, text: text || "実行ログ ↗" });
|
|
10959
|
+
}
|
|
10960
|
+
|
|
10961
|
+
/**
|
|
10962
|
+
* 行の時刻の横に添えるもの(リンクか出どころの語)。**無ければ空配列。**
|
|
10963
|
+
* 「.ds-gate-at」「.ds-ingest」 の**兄弟**として置く(子にすると、文言の検査と
|
|
10964
|
+
* 「いま測った結果」への差し替えが崩れる)。
|
|
10965
|
+
*
|
|
10966
|
+
* @param kind どの時刻に添えたか(「gate」=「◯分前に確認」)。「いま測った結果」への差し替えは
|
|
10967
|
+
* **この印のものだけ**消す——「取り込み: 〜に成功」の横のリンク(別の行の run)は残す
|
|
10968
|
+
*/
|
|
10969
|
+
function runTrailNodes(row, url, kind) {
|
|
10970
|
+
var u = url === undefined ? runLogUrlOf(row) : url;
|
|
10971
|
+
var word = u ? "" : runSourceWordOf(row);
|
|
10972
|
+
var node = u ? runLogLink(u) : word ? el("span", { class: "ds-run-src", text: word }) : null;
|
|
10973
|
+
if (!node) return [];
|
|
10974
|
+
if (kind) node.setAttribute("data-trail", kind);
|
|
10975
|
+
return [node];
|
|
10976
|
+
}
|
|
10977
|
+
|
|
10978
|
+
/** 複数のノードを 1 つの子として返す(「el」 の children に並べるため) */
|
|
10979
|
+
function frag(nodes) {
|
|
10980
|
+
var f = document.createDocumentFragment();
|
|
10981
|
+
(nodes || []).forEach(function (n) { if (n) f.appendChild(n); });
|
|
10982
|
+
return f;
|
|
10983
|
+
}
|
|
10984
|
+
|
|
10985
|
+
/**
|
|
10986
|
+
* 「いま測った結果」に差し替えるとき、**「◯分前に確認」に添えた**古い run の導線を外す
|
|
10987
|
+
* (同じ行が 2 つのことを言わない)。「取り込み: 〜に成功」の横のリンクは別の行の run なので残す
|
|
10988
|
+
*/
|
|
10989
|
+
function removeRunTrail(scope) {
|
|
10990
|
+
var old = scope.querySelectorAll('.ds-run-link[data-trail="gate"], .ds-run-src[data-trail="gate"]');
|
|
10991
|
+
for (var i = 0; i < old.length; i++) old[i].remove();
|
|
10992
|
+
}
|
|
10993
|
+
|
|
10820
10994
|
/**
|
|
10821
10995
|
* 接続先1件の「取り込み」の表示。**測っていなければ何も出さない(null)。**
|
|
10822
10996
|
*
|
|
@@ -10839,10 +11013,12 @@ ${calendarAddUrl.toString()}
|
|
|
10839
11013
|
// 語は鍵カードの名前と揃える(keyMissingText の項)
|
|
10840
11014
|
else if (r.status === "skipped") text = "取り込み: 未実行(" + keyMissingText(cap) + ")";
|
|
10841
11015
|
if (!text) return null;
|
|
10842
|
-
|
|
11016
|
+
var span = el("span", {
|
|
10843
11017
|
class: "ds-ingest" + (r.status === "failed" ? " ds-ingest-failed" : ""),
|
|
10844
11018
|
text: text,
|
|
10845
11019
|
});
|
|
11020
|
+
// その行を書いた run へ(#560)。成功でも失敗でも、この時刻を書いた run のログ
|
|
11021
|
+
return frag([span].concat(runTrailNodes(r)));
|
|
10846
11022
|
}
|
|
10847
11023
|
|
|
10848
11024
|
/**
|
|
@@ -10884,6 +11060,8 @@ ${calendarAddUrl.toString()}
|
|
|
10884
11060
|
row.appendChild(el("span", { class: "ds-gate " + gate.cls, text: gate.text }));
|
|
10885
11061
|
var when = rtAgo(r.at);
|
|
10886
11062
|
if (when) row.appendChild(el("span", { class: "ds-gate-at", text: when + "に確認" }));
|
|
11063
|
+
// その行を書いた run へ(#560)。run の無い書き手は出どころの語
|
|
11064
|
+
runTrailNodes(r, undefined, "gate").forEach(function (n) { row.appendChild(n); });
|
|
10887
11065
|
return row;
|
|
10888
11066
|
}
|
|
10889
11067
|
|
|
@@ -11032,12 +11210,30 @@ ${calendarAddUrl.toString()}
|
|
|
11032
11210
|
at: (before && before.at) || "",
|
|
11033
11211
|
startedAt: Date.now(),
|
|
11034
11212
|
message: (j && j.message) || "",
|
|
11213
|
+
// 起こした run(特定できた回)と一覧(#560)。描き直しでもリンクが消えないよう控える
|
|
11214
|
+
runUrl: (j && RUN_URL_RE.test(String(j.runUrl || ""))) ? String(j.runUrl) : "",
|
|
11215
|
+
runsUrl: (j && /^https:\\/\\/github\\.com\\/[^\\s"'<>]+$/.test(String(j.runsUrl || ""))) ? String(j.runsUrl) : "",
|
|
11035
11216
|
};
|
|
11036
|
-
note
|
|
11217
|
+
probeWaitNote(note, PROBE_WAITS[key]);
|
|
11037
11218
|
// 待っているあいだは取り直しを回す(届いた行で一覧が描き直される)
|
|
11038
11219
|
refreshStateTimer();
|
|
11039
11220
|
}
|
|
11040
11221
|
|
|
11222
|
+
/**
|
|
11223
|
+
* 待ちの 1 文と、その横の導線(#560)。**その run を特定できていればそれ、無ければ一覧。**
|
|
11224
|
+
* 開始直後は run の番号が無いことが多いので一覧へ。行が更新されて待ちが解けたら、
|
|
11225
|
+
* 行側の「実行ログ ↗」(その run)に置き換わる。run の無い経路(固定 IP・中央)は何も出ない
|
|
11226
|
+
*/
|
|
11227
|
+
function probeWaitNote(note, wait) {
|
|
11228
|
+
note.textContent = (wait && wait.message) || "";
|
|
11229
|
+
if (!wait) return;
|
|
11230
|
+
var link = wait.runUrl ? runLogLink(wait.runUrl) : wait.runsUrl ? runLogLink(wait.runsUrl, RUN_LIST_TEXT) : null;
|
|
11231
|
+
if (link) {
|
|
11232
|
+
note.appendChild(document.createTextNode(" "));
|
|
11233
|
+
note.appendChild(link);
|
|
11234
|
+
}
|
|
11235
|
+
}
|
|
11236
|
+
|
|
11041
11237
|
/**
|
|
11042
11238
|
* 即答(#548 の direct)を行に映す。**「probeSection」 と同じ見た目にする**——
|
|
11043
11239
|
* 夜間のスナップショットの判定といま測った判定を**同じ行に並べない**ため
|
|
@@ -11074,6 +11270,8 @@ ${calendarAddUrl.toString()}
|
|
|
11074
11270
|
row.insertBefore(at, anchor);
|
|
11075
11271
|
}
|
|
11076
11272
|
at.textContent = "いま測った結果(" + (dsFmtTime(j.checkedAt) || "たった今") + ")";
|
|
11273
|
+
// 古い run の導線も外す(#560)。残すと「いま測った結果」の横に夜間の run のログが並ぶ
|
|
11274
|
+
removeRunTrail(row);
|
|
11077
11275
|
// **夜間の判定に添えてあった案内は隠す。** 置き換えた判定と食い違う案内が下に残ると、
|
|
11078
11276
|
// 同じ行が2つのことを言う(probeSection の stale 処理と同じ)
|
|
11079
11277
|
var stale = row.querySelectorAll(".ds-gate-help");
|
|
@@ -11111,8 +11309,13 @@ ${calendarAddUrl.toString()}
|
|
|
11111
11309
|
var note = el("p", { class: "ds-probe-wait" });
|
|
11112
11310
|
var phase = probeWaitPhaseOf(capId, ref);
|
|
11113
11311
|
var wait = probeWaitOf(capId, ref);
|
|
11114
|
-
if (phase === "waiting") note
|
|
11115
|
-
else if (phase === "timeout")
|
|
11312
|
+
if (phase === "waiting") probeWaitNote(note, wait);
|
|
11313
|
+
else if (phase === "timeout") {
|
|
11314
|
+
// 15 分待って届かないなら見に行く番。**行き先を添える**(#560)——一覧でも run でも
|
|
11315
|
+
note.textContent = PROBE_WAIT_TIMEOUT_TEXT;
|
|
11316
|
+
var to = wait && (wait.runUrl || wait.runsUrl);
|
|
11317
|
+
if (to) { note.appendChild(document.createTextNode(" ")); note.appendChild(runLogLink(to, wait.runUrl ? "実行ログ ↗" : RUN_LIST_TEXT)); }
|
|
11318
|
+
}
|
|
11116
11319
|
else note.hidden = true;
|
|
11117
11320
|
|
|
11118
11321
|
checkBtn.addEventListener("click", async function () {
|
|
@@ -12427,7 +12630,7 @@ ${calendarAddUrl.toString()}
|
|
|
12427
12630
|
// 起動できなかった案件(権限・スタブ未配布)ではリンクを出さない——押しても何も無い
|
|
12428
12631
|
if (j.runsUrl) {
|
|
12429
12632
|
msg.appendChild(document.createTextNode(" "));
|
|
12430
|
-
msg.appendChild(el("a", { href: j.runsUrl, target: "_blank", rel: "noopener", text: "実行状況を見る →" }));
|
|
12633
|
+
msg.appendChild(el("a", { href: j.runUrl || j.runsUrl, target: "_blank", rel: "noopener", title: RUN_LINK_TITLE, text: "実行状況を見る →" })); // その run を特定できていればそれ(#560)、無ければ一覧
|
|
12431
12634
|
}
|
|
12432
12635
|
// **「反映の状況 →」のリンクは無くなった(#221・2026-08-25)。** 指していたのは
|
|
12433
12636
|
// 「画面を追いつかせるための fleet-status の実行」で、その起動ごと撤去した
|
|
@@ -12977,6 +13180,8 @@ ${calendarAddUrl.toString()}
|
|
|
12977
13180
|
var gateAtEl = s.gateAt
|
|
12978
13181
|
? el("span", { class: "ds-gate-at", text: rtAgo(s.gateAt) + "に確認" })
|
|
12979
13182
|
: null;
|
|
13183
|
+
// その行を書いた run へ(#560)。overlay が写した 「gateRunUrl」 / 「gateBy」 から決める
|
|
13184
|
+
var gateTrail = s.gateAt ? runTrailNodes({ runUrl: s.gateRunUrl || "", by: s.gateBy || "" }, undefined, "gate") : [];
|
|
12980
13185
|
var card = el("div", { class: "ds-card" }, [
|
|
12981
13186
|
el("div", { class: "ds-card-main" }, [
|
|
12982
13187
|
el("span", { class: "ds-icon", text: meta.icon }),
|
|
@@ -12999,6 +13204,7 @@ ${calendarAddUrl.toString()}
|
|
|
12999
13204
|
card.appendChild(el("code", { class: "ds-probe-scope", text: String(s.needed) }));
|
|
13000
13205
|
}
|
|
13001
13206
|
if (gateAtEl) card.appendChild(gateAtEl);
|
|
13207
|
+
gateTrail.forEach(function (n) { card.appendChild(n); });
|
|
13002
13208
|
// チャンネルの登録解除。書き込み経路(intake Lambda)がある案件でだけ出す。
|
|
13003
13209
|
// **Slack だけ。** github は登録ファイルが別(dev-sources.json)で、下のトグルと
|
|
13004
13210
|
// 「登録から削除」が担う。
|
|
@@ -14027,7 +14233,7 @@ ${calendarAddUrl.toString()}
|
|
|
14027
14233
|
// 起動できたときだけ、実行状況への導線を出す(鍵を入れた直後に効いたか確かめられる)
|
|
14028
14234
|
if (j.runsUrl) {
|
|
14029
14235
|
msg.appendChild(document.createTextNode(" "));
|
|
14030
|
-
msg.appendChild(el("a", { href: j.runsUrl, target: "_blank", rel: "noopener", text: "実行状況を見る →" }));
|
|
14236
|
+
msg.appendChild(el("a", { href: j.runUrl || j.runsUrl, target: "_blank", rel: "noopener", title: RUN_LINK_TITLE, text: "実行状況を見る →" })); // その run を特定できていればそれ(#560)、無ければ一覧
|
|
14031
14237
|
}
|
|
14032
14238
|
// 入れた値は画面に残さない(肩越しに見えるのを防ぐ)
|
|
14033
14239
|
input.value = "";
|
package/package.json
CHANGED