@takagaki/cortex-decisions-viewer 0.6.0 → 0.7.1
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/build.js +29 -1
- package/dist/render.js +400 -173
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -126,6 +126,14 @@ function resolveKnowledgeRoot(decisionsDirAbs) {
|
|
|
126
126
|
}
|
|
127
127
|
return null;
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* スペースごとの Backlog キーの登録状況で、画面へ運んでよい値。
|
|
131
|
+
*
|
|
132
|
+
* **Lambda 側(infra/lambda/intake/logic.mjs の FLEET_MAP_VALUE_ALLOW)と同じにすること。**
|
|
133
|
+
* 片方だけ増やすと、静的ビルドでは出ないものがライブ差し替えの瞬間だけ出る
|
|
134
|
+
* ——「朝は正しいのに、開いて数秒すると表示が変わる」という一番気づきにくい食い違いになる。
|
|
135
|
+
*/
|
|
136
|
+
const SECRET_SPACE_STATES = ["new", "legacy", "false"];
|
|
129
137
|
/**
|
|
130
138
|
* リポジトリルートの fleet-status.json から externalSources / internalSources / pipelines を読む。
|
|
131
139
|
* ファイルが無い・パース不能・当該フィールドが無い場合は undefined を返し、
|
|
@@ -375,7 +383,26 @@ async function readFleetSources(repoRoot) {
|
|
|
375
383
|
const secretSources = obj.secretSources && typeof obj.secretSources === "object"
|
|
376
384
|
? obj.secretSources
|
|
377
385
|
: undefined;
|
|
378
|
-
|
|
386
|
+
// スペースごとの Backlog キーの登録状況(画面が接続先の行ごとに出す)。
|
|
387
|
+
//
|
|
388
|
+
// **値は列挙した3つだけを通す。** この値は顧客のブラウザまで届くので、engine が
|
|
389
|
+
// 語を増やしたときに知らない文字列をそのまま画面へ運ばない
|
|
390
|
+
// (Lambda 側の FLEET_MAP_VALUE_ALLOW と**同じ3つ**にそろえること。片方だけ増やすと、
|
|
391
|
+
// 静的では出ないものがライブ差し替えの瞬間だけ出る=一番気づきにくい食い違い)。
|
|
392
|
+
//
|
|
393
|
+
// **1つも残らなければキーごと落とす。** 空の器を通すと、画面が「確かめたうえで0件」と
|
|
394
|
+
// 読んで「未登録」と断定する。**知らないことは、キーが無いことで表す**
|
|
395
|
+
let secretSpaces;
|
|
396
|
+
if (obj.secretSpaces != null && typeof obj.secretSpaces === "object" && !Array.isArray(obj.secretSpaces)) {
|
|
397
|
+
const out = {};
|
|
398
|
+
for (const [space, v] of Object.entries(obj.secretSpaces)) {
|
|
399
|
+
if (typeof v === "string" && SECRET_SPACE_STATES.includes(v))
|
|
400
|
+
out[space] = v;
|
|
401
|
+
}
|
|
402
|
+
if (Object.keys(out).length)
|
|
403
|
+
secretSpaces = out;
|
|
404
|
+
}
|
|
405
|
+
return { externalSources, slackWorkspaces, internalSources, pipelines, capabilities, fleetGeneratedAt, secretSources, secretSpaces, checks, githubOwners, backlogTarget };
|
|
379
406
|
}
|
|
380
407
|
/** パスがディレクトリとして存在するか */
|
|
381
408
|
async function isDirectory(dirAbs) {
|
|
@@ -1312,6 +1339,7 @@ async function build(opts) {
|
|
|
1312
1339
|
slackWorkspaces: fleet.slackWorkspaces,
|
|
1313
1340
|
fleetGeneratedAt: fleet.fleetGeneratedAt,
|
|
1314
1341
|
secretSources: fleet.secretSources,
|
|
1342
|
+
secretSpaces: fleet.secretSpaces,
|
|
1315
1343
|
internalSources: fleet.internalSources,
|
|
1316
1344
|
pipelines: fleet.pipelines,
|
|
1317
1345
|
capabilities: fleet.capabilities,
|
package/dist/render.js
CHANGED
|
@@ -1107,18 +1107,17 @@ a:hover { text-decoration: underline; }
|
|
|
1107
1107
|
display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px;
|
|
1108
1108
|
}
|
|
1109
1109
|
.ds-card-main { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 0; }
|
|
1110
|
-
/*
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
.ds-
|
|
1121
|
-
.ds-card.ds-capbody > .ds-card-main { flex: 0 0 auto; }
|
|
1110
|
+
/* 能力モーダルの中身は**箱に入れない**(2026-08-21・オーナー実機指摘)。
|
|
1111
|
+
かつては .ds-card.ds-capbody という枠で包み、その中に「📋 課題管理 Backlog」と
|
|
1112
|
+
能力名まで書いていた。押しているのは Backlog のタイルで、**モーダルの見出しも
|
|
1113
|
+
ツール名(Backlog)**なので、枠と能力名は「課題管理・Backlog」という入れ子の
|
|
1114
|
+
重複でしかなかった。いまは見出しの直下へ中身をそのまま並べ、ここは
|
|
1115
|
+
**縦に積む役だけ**を持つ(枠線・背景・影は持たない)。
|
|
1116
|
+
⚠ **枠が無くなったので、未使用(enabled: false)の灰色の破線は出ない。**
|
|
1117
|
+
代わりに未使用を示すのは (1) 下の .ds-inactive の子孫ルール(中の文字が灰色になる)と
|
|
1118
|
+
(2)「未使用(この案件では設定されていません)」の一行(.ds-inactive-note)。
|
|
1119
|
+
モーダルは1つの能力しか映さないので、他の行と並べて灰色で見分ける必要が無い。 */
|
|
1120
|
+
.ds-capblock { display: flex; flex-direction: column; gap: 10px; }
|
|
1122
1121
|
.ds-icon { font-size: 18px; line-height: 1; flex: 0 0 auto; }
|
|
1123
1122
|
.ds-type { font-size: 12px; font-weight: 600; color: var(--muted); flex: 0 0 auto; }
|
|
1124
1123
|
.ds-name { font-size: 14.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -1304,9 +1303,12 @@ a.ds-name:hover { text-decoration: underline; }
|
|
|
1304
1303
|
.ds-toggle-msg.is-ok { color: #1a7f37; }
|
|
1305
1304
|
.ds-toggle-msg.is-error { color: #b42318; }
|
|
1306
1305
|
.badge.ds-notify { background: #eff6ff; color: #1e40af; border: 1px solid #bfdbfe; }
|
|
1306
|
+
/* 読み取りを止めてあるリポジトリ(2026-08-21)。**それまではトグルの向きが示していた**ので、
|
|
1307
|
+
トグルを撤去したいま、読み取られていないことを示すのはこのバッジだけ。
|
|
1308
|
+
**判断のバッジなので、由来や組織のバッジより強く出す** */
|
|
1309
|
+
.badge.ds-excluded { background: #f3f4f6; color: #4b5563; border: 1px solid #d1d5db; }
|
|
1307
1310
|
/* 登録の由来(#118)。**薄く出す**——読み取りの可否や Gold 対象かより弱い情報で、
|
|
1308
1311
|
ここが目立つと「除外」「未宣言」の判断のバッジと同じ強さに見えてしまう */
|
|
1309
|
-
.badge.ds-origin { background: transparent; color: var(--muted); border: 1px dashed var(--border); }
|
|
1310
1312
|
/* どの Slack ワークスペースのチャンネルか(#104)。**由来のバッジと同じ強さにする**——
|
|
1311
1313
|
「Gold 対象か」より弱い、どれのことかを見分けるための情報。強くすると判断のバッジと競る */
|
|
1312
1314
|
.badge.ds-workspace { background: transparent; color: var(--muted); border: 1px solid var(--border); }
|
|
@@ -1371,6 +1373,31 @@ a.ds-name:hover { text-decoration: underline; }
|
|
|
1371
1373
|
.sec-state { font-size: 12.5px; font-weight: 600; margin: 0 0 8px; color: var(--muted); }
|
|
1372
1374
|
.sec-state.is-managed { color: #1a7f37; }
|
|
1373
1375
|
.sec-state.is-none { color: var(--muted); font-weight: 400; }
|
|
1376
|
+
/* 登録されているか分からない(engine がスペース別の状況をまだ出していない)。
|
|
1377
|
+
**未登録と同じ見た目にしない**——断定していないことが色でも分かるようにする */
|
|
1378
|
+
.sec-state.is-unknown { color: var(--muted); font-weight: 400; font-style: italic; }
|
|
1379
|
+
/* 鍵の欄の置き場(2026-08-21)。レコードの行の中と、一覧の直後の2か所で使う。
|
|
1380
|
+
**.ds-card は flex-wrap: wrap の横並び**なので、100% の basis を与えて
|
|
1381
|
+
行の中で自分の段へ落とす(行そのものの並びは変えない——縦組みのクラスを
|
|
1382
|
+
流用すると Slack / GitHub の行まで縦に割れる)。 */
|
|
1383
|
+
.ds-keyrow { flex: 1 1 100%; min-width: 0; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
|
|
1384
|
+
/* 一覧の直後に置くとき(Figma)は、行の中ではないので区切り線を持たない */
|
|
1385
|
+
.ds-keyrow-list { margin-top: 10px; padding-top: 0; border-top: none; }
|
|
1386
|
+
/* 行の中に入った鍵カードは、カードの枠を持たない(行の一部に見せる) */
|
|
1387
|
+
.ops-card.ds-keycard { border: none; box-shadow: none; padding: 0; background: transparent; gap: 6px; }
|
|
1388
|
+
.ops-card.ds-keycard > .ops-card-head { gap: 8px; }
|
|
1389
|
+
.ops-card.ds-keycard .ops-card-icon { font-size: 16px; }
|
|
1390
|
+
.ops-card.ds-keycard .ops-card-title { font-size: 13px; }
|
|
1391
|
+
/* 押すまで入力欄を出さない(2026-08-21・オーナー指摘)。summary はボタンに見せる */
|
|
1392
|
+
.sec-input-fold { border: none; margin: 0; }
|
|
1393
|
+
.sec-input-fold > summary {
|
|
1394
|
+
cursor: pointer; display: inline-block; list-style: none;
|
|
1395
|
+
padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border);
|
|
1396
|
+
background: #fff; color: var(--text); font-size: 12.5px; font-weight: 600;
|
|
1397
|
+
}
|
|
1398
|
+
.sec-input-fold > summary::-webkit-details-marker { display: none; }
|
|
1399
|
+
.sec-input-fold > summary:hover { border-color: var(--accent); color: var(--accent); }
|
|
1400
|
+
.sec-input-fold[open] > summary { margin-bottom: 8px; }
|
|
1374
1401
|
.ds-addform { border: 1px dashed var(--border); border-radius: 8px; padding: 12px 14px; margin-top: 10px; background: #fff; }
|
|
1375
1402
|
.ds-addform-title { font-size: 13px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
|
|
1376
1403
|
.ds-addform .sec-input { margin-bottom: 6px; }
|
|
@@ -1398,6 +1425,12 @@ a.ds-name:hover { text-decoration: underline; }
|
|
|
1398
1425
|
padding: 18px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 10px;
|
|
1399
1426
|
}
|
|
1400
1427
|
/* リアルタイム同期の設定手順(#113)。番号付きなのは「上から順に1回やる」作業だから */
|
|
1428
|
+
/* **上に余白を置く(2026-08-21・オーナー実機指摘「リアルタイム同期のセクションが
|
|
1429
|
+
くっついてて気持ち悪かった。上のスペースがないから違和感ある」)。**
|
|
1430
|
+
直前に来るのは接続先の追加フォーム(.ds-addform)で、そちらは margin-top: 10px を
|
|
1431
|
+
持っている。こちらが 0 だと2つの箱が接して1枚に見える。**同じ 10px で釣り合わせる。**
|
|
1432
|
+
⚠ CSS は jsdom から見えないので、この余白はテストでは守れない(実機で見ること)。 */
|
|
1433
|
+
.rt-card { margin-top: 10px; }
|
|
1401
1434
|
.rt-steps { margin: 0; padding-left: 1.4em; color: var(--text); font-size: 13px; line-height: 1.9; }
|
|
1402
1435
|
.rt-steps li { margin: 2px 0; }
|
|
1403
1436
|
/* URLは長いので、入力欄を伸ばしてボタンを右に置く(折り返しても崩れないように wrap) */
|
|
@@ -2767,14 +2800,6 @@ ${capabilityState.toString()}
|
|
|
2767
2800
|
}
|
|
2768
2801
|
|
|
2769
2802
|
|
|
2770
|
-
var DS_KIND_ICON = {
|
|
2771
|
-
"課題管理": "📋",
|
|
2772
|
-
"会議": "🗒️",
|
|
2773
|
-
"共有資料": "📎",
|
|
2774
|
-
"デザイン": "🎨",
|
|
2775
|
-
"開発": "🐙",
|
|
2776
|
-
"チャット": "💬",
|
|
2777
|
-
};
|
|
2778
2803
|
function dsFmtTime(iso) {
|
|
2779
2804
|
var d = new Date(iso);
|
|
2780
2805
|
if (isNaN(d.getTime())) return "";
|
|
@@ -2975,14 +3000,33 @@ ${capabilityState.toString()}
|
|
|
2975
3000
|
* 能力モーダル。**中身は既存の部品をそのまま入れる。**
|
|
2976
3001
|
* 一覧・追加フォーム・鍵・手動投入は作り直さない(先出しバッジやライブ差し替えを壊さないため)。
|
|
2977
3002
|
*/
|
|
3003
|
+
/**
|
|
3004
|
+
* 能力(課題管理・会議…)→ **押したタイルのツール名**(Backlog・Google Meet…)。
|
|
3005
|
+
*
|
|
3006
|
+
* 2026-08-21 のオーナー実機指摘「押してるのはそのツールなんだから、Backlog とか
|
|
3007
|
+
* Google ドライブとして出る必要がある」。出どころは ADAPTER_CATALOG(能力→アダプタ)で、
|
|
3008
|
+
* **今日は能力あたり1アダプタなので一意に決まる**(#107 / #127 で複数になったら、
|
|
3009
|
+
* ここが「どれを見出しにするか」を決める場所になる)。
|
|
3010
|
+
*
|
|
3011
|
+
* ⚠ **カタログに無いものは、そのまま返す。** ここには能力名だけでなく
|
|
3012
|
+
* 「文字起こしを手動で追加」のような**能力ではない見出し**も渡ってくるし、
|
|
3013
|
+
* 未知の能力(engine が先に増やした場合)も来る。空にすると
|
|
3014
|
+
* **名前の無いダイアログ**になり、何を開いたのか分からなくなる——落とすなら能力名まで。
|
|
3015
|
+
*/
|
|
3016
|
+
function capToolLabel(cap) {
|
|
3017
|
+
var list = ADAPTER_CATALOG[cap] || [];
|
|
3018
|
+
var tool = list.length ? list[0] : "";
|
|
3019
|
+
return (tool && CM_TOOL_LABEL_C[tool]) || cap;
|
|
3020
|
+
}
|
|
3021
|
+
|
|
2978
3022
|
function openCapabilityModal(cap, items, note) {
|
|
2979
|
-
var m = makeModal(cap, true);
|
|
3023
|
+
var m = makeModal(capToolLabel(cap), true);
|
|
2980
3024
|
// **何が読み取られるのかを必ず書く。** 一覧に並ぶものと読み取られるものの関係は、
|
|
2981
3025
|
// 書いていないと分からない(チャットは「載っていれば全部」、開発はリポジトリ単位でOFFできる)
|
|
2982
3026
|
if (cap === "チャット") {
|
|
2983
3027
|
m.modal.appendChild(el("p", { class: "modal-desc", text: "ここに並んでいるチャンネルは、例外なく全て毎晩の Gold 昇格が読み取り、Decision・用語集の材料になります。読み取りを止めるには「登録を解除」してください。" }));
|
|
2984
3028
|
} else if (cap === "開発") {
|
|
2985
|
-
m.modal.appendChild(el("p", { class: "modal-desc", text: "ここに並んでいるリポジトリの Issues を毎晩の Gold
|
|
3029
|
+
m.modal.appendChild(el("p", { class: "modal-desc", text: "ここに並んでいるリポジトリの Issues を毎晩の Gold 昇格が読み取り、Decision・用語集の材料になります。読み取りをやめるには「登録から削除」してください。" }));
|
|
2986
3030
|
}
|
|
2987
3031
|
// **なぜこの状態なのかを、押した先でも読めるようにする(#125②)。** タイルは常時出す
|
|
2988
3032
|
// ようになったので、未接続の能力を押したときに中身が空になる場面が増えた。
|
|
@@ -3003,7 +3047,32 @@ ${capabilityState.toString()}
|
|
|
3003
3047
|
showModal(m.overlay, m.modal);
|
|
3004
3048
|
}
|
|
3005
3049
|
|
|
3050
|
+
/**
|
|
3051
|
+
* 鍵の欄の置き場(2026-08-21・オーナー指摘「APIキーのセクションが下にあって、
|
|
3052
|
+
* 変わってないように見えます」)。
|
|
3053
|
+
*
|
|
3054
|
+
* 鍵の欄は**レコードの行の内側**(Backlog は接続先の行ごと・Figma は一覧の直後)に出す。
|
|
3055
|
+
* ところが**出す責任はここには移していない**——鍵カードを作っているのは
|
|
3056
|
+
* 「SECRET_FORMS」のループで、そこには
|
|
3057
|
+
* - intake を持たない案件でも鍵の欄を出す(internalControls は SITE.intake で早期return)
|
|
3058
|
+
* - OFF にした能力には入力欄を出さない
|
|
3059
|
+
* という2つのゲートが掛かっている。**内側で作り直すと、その両方が外れる**
|
|
3060
|
+
* (前者は「鍵の欄しか無い案件でデータソース節が丸ごと消える」形で実際に起きた)。
|
|
3061
|
+
*
|
|
3062
|
+
* そこで**置き場だけを内側から渡す**。ここに登録された受け皿へ、ループが作った
|
|
3063
|
+
* 鍵カードを差し込む。受け皿が無ければ従来どおり能力カードの直下へ積む。
|
|
3064
|
+
*
|
|
3065
|
+
* - backlog … スペース(ドメイン小文字)→ 受け皿。接続先が無い案件は空文字のキー
|
|
3066
|
+
* - backlogNamed … 保存時にスペースを名乗ってよいか(名簿由来の行だけ true)
|
|
3067
|
+
* - figma … 一覧の直後の受け皿(Figma の鍵は案件に1本なので1つだけ)
|
|
3068
|
+
*
|
|
3069
|
+
* **描き直すたびに作り直す。** ライブ差し替えで節ごと作り直されるので、
|
|
3070
|
+
* 前回の受け皿(切り離された古いノード)が残っていると、鍵の欄が画面から消える。
|
|
3071
|
+
*/
|
|
3072
|
+
var KEY_SLOTS = { backlog: {}, backlogNamed: false, figma: null };
|
|
3073
|
+
|
|
3006
3074
|
function buildDataSources() {
|
|
3075
|
+
KEY_SLOTS = { backlog: {}, backlogNamed: false, figma: null };
|
|
3007
3076
|
var internals = fleetVal("internalSources") || [];
|
|
3008
3077
|
var sources = fleetVal("externalSources") || [];
|
|
3009
3078
|
var pipes = fleetVal("pipelines") || [];
|
|
@@ -3087,8 +3156,18 @@ ${capabilityState.toString()}
|
|
|
3087
3156
|
// 用意してからここを戻す(syncNowRow と Lambda の op=sync は残してある)。
|
|
3088
3157
|
// sec.appendChild(syncNowRow());
|
|
3089
3158
|
internals.forEach(function (s) {
|
|
3090
|
-
//
|
|
3091
|
-
|
|
3159
|
+
// 補足行(会議の照合キー・Drive未設定の注記)を重ねられるよう縦組みにする。
|
|
3160
|
+
//
|
|
3161
|
+
// **情報源の名前は出さない(2026-08-21・オーナー指摘)。** モーダルの見出しが
|
|
3162
|
+
// ツール名(Backlog / Figma / Google Drive …)になったので、その直下にもう一度
|
|
3163
|
+
// 名前を出すと**同じことを2回言う**。実データの label は
|
|
3164
|
+
// 「Backlog 課題・ドキュメント(同期ミラー)」のような説明的な文で、見出しの
|
|
3165
|
+
// 言い換えにしかなっていない。
|
|
3166
|
+
//
|
|
3167
|
+
// **リンクを失わないことは確かめてある。** url を持つのは課題管理(プロジェクト)と
|
|
3168
|
+
// デザイン(Figmaファイル)だけで、どちらも**レコードの行が同じ先へリンクしている**。
|
|
3169
|
+
// 会議・共有資料は url を持たない。
|
|
3170
|
+
var col = el("div", { class: "ds-col" }, []);
|
|
3092
3171
|
// 照合キーの表示はここ1箇所に集約する(下の案内と二重に出さない)。
|
|
3093
3172
|
// **ON/OFFのトグルは出さない。** 取り込むかどうかは「Bot を会議に招待したか」で決まる
|
|
3094
3173
|
// (Router.gs:「フィルタは持たない…招待が同意のゲート」)。enabled はルーティングの
|
|
@@ -3163,27 +3242,31 @@ ${capabilityState.toString()}
|
|
|
3163
3242
|
// モーダルの中身がタイルより前に来る変更が入った瞬間、getElementById が
|
|
3164
3243
|
// 「開いていないモーダルの中」を指して黙って無反応になる
|
|
3165
3244
|
//
|
|
3166
|
-
//
|
|
3167
|
-
//
|
|
3168
|
-
//
|
|
3169
|
-
//
|
|
3170
|
-
//
|
|
3171
|
-
//
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3245
|
+
// **枠(.ds-card)とアイコン・能力名(.ds-icon / .ds-type)を落とす**
|
|
3246
|
+
// (2026-08-21・オーナー実機指摘)。Backlog のタイルを押して開いたモーダルの中に
|
|
3247
|
+
// 「📋 課題管理 Backlog」という箱がもう一段あり、見出しと同じことを二度言っていた。
|
|
3248
|
+
// モーダルの見出しがツール名になったので、ここは**見出しの直下に中身を並べる**だけ。
|
|
3249
|
+
//
|
|
3250
|
+
// 🔴 **落としたのは見出しと重複する2つだけ。** 会議の合図(.ds-keys)・別名チップ・
|
|
3251
|
+
// Drive / 未使用の注記・情報源へのリンクは col がそのまま抱えており、
|
|
3252
|
+
// 最終同期(.ds-sync)も条件ごと残している。
|
|
3253
|
+
//
|
|
3254
|
+
// **data-cap を付ける。** 能力名の文字列が画面から消えたので、
|
|
3255
|
+
// 「これはどの能力のブロックか」を掴む手掛かりがここしか無くなる(テストが引く)。
|
|
3256
|
+
var block = el("div", {
|
|
3257
|
+
class: "ds-capblock" + (inactive ? " ds-inactive" : ""),
|
|
3258
|
+
"data-cap": s.kind || "",
|
|
3259
|
+
}, [
|
|
3260
|
+
col,
|
|
3178
3261
|
!inactive && s.lastSync && dsFmtTime(s.lastSync)
|
|
3179
3262
|
? el("span", { class: "ds-sync", text: "最終同期: " + dsFmtTime(s.lastSync) })
|
|
3180
3263
|
: null,
|
|
3181
3264
|
]);
|
|
3182
|
-
//
|
|
3265
|
+
// 会議・共有資料・デザインの操作をブロック内に置く(その情報源の文脈で押せるように)
|
|
3183
3266
|
var ctl = internalControls(s, inactive);
|
|
3184
|
-
if (ctl)
|
|
3267
|
+
if (ctl) block.appendChild(ctl);
|
|
3185
3268
|
// 能力ごとの受け皿へ入れる(並べるのは下の CAP_ORDER のループ)
|
|
3186
|
-
pushCap(s.kind,
|
|
3269
|
+
pushCap(s.kind, block);
|
|
3187
3270
|
});
|
|
3188
3271
|
}
|
|
3189
3272
|
|
|
@@ -3349,10 +3432,34 @@ ${capabilityState.toString()}
|
|
|
3349
3432
|
// **Backlog は接続先のスペースごとにカードを出す(2026-08-20・#127)。**
|
|
3350
3433
|
// キーはスペースごとに別なので、欄が1つだと**どちらの鍵を入れたのか
|
|
3351
3434
|
// 誰にも分からない**まま片方の棚に入る(入れたのに動かない、が起きる)。
|
|
3435
|
+
//
|
|
3436
|
+
// **置き場は行の中(2026-08-21)。** backlogTargetsSection が接続先の行ごとに
|
|
3437
|
+
// 受け皿を用意しているので、そこへ差し込む。受け皿が無い案件
|
|
3438
|
+
//(intake を持たない・固定IP同期)では従来どおり能力カードの直下へ積む
|
|
3439
|
+
//——**ここで return してしまうと、鍵の欄しか無い案件で鍵が丸ごと消える。**
|
|
3352
3440
|
if (k === "backlog") {
|
|
3441
|
+
var slots = KEY_SLOTS.backlog;
|
|
3442
|
+
var spaces = Object.keys(slots);
|
|
3443
|
+
if (spaces.length) {
|
|
3444
|
+
spaces.forEach(function (space) {
|
|
3445
|
+
slots[space].appendChild(secretCard(k, SECRET_FORMS[k], {
|
|
3446
|
+
// **名乗るのは名簿由来の行だけ。** 同期ミラーのURLから作った行で
|
|
3447
|
+
// スペースを名乗ると、名簿とミラーがずれている案件で**黙って別の棚に入る**
|
|
3448
|
+
space: KEY_SLOTS.backlogNamed ? space : "",
|
|
3449
|
+
stateSpace: space,
|
|
3450
|
+
spaceCount: spaces.length,
|
|
3451
|
+
inRow: true,
|
|
3452
|
+
}));
|
|
3453
|
+
});
|
|
3454
|
+
return;
|
|
3455
|
+
}
|
|
3353
3456
|
backlogSecretCards().forEach(function (n) { pushCap(SECRET_CAP[k], n); });
|
|
3354
3457
|
return;
|
|
3355
3458
|
}
|
|
3459
|
+
if (k === "figma" && KEY_SLOTS.figma) {
|
|
3460
|
+
KEY_SLOTS.figma.appendChild(secretCard(k, SECRET_FORMS[k], { inRow: true }));
|
|
3461
|
+
return;
|
|
3462
|
+
}
|
|
3356
3463
|
pushCap(SECRET_CAP[k], secretCard(k, SECRET_FORMS[k]));
|
|
3357
3464
|
});
|
|
3358
3465
|
|
|
@@ -3480,7 +3587,8 @@ ${capabilityState.toString()}
|
|
|
3480
3587
|
} else if (live.length) {
|
|
3481
3588
|
// 単位は分かるものだけ。知らない種別に勝手な単位を付けない。
|
|
3482
3589
|
// **「N件をGoldに使用」の内訳は出さない。** チャンネルは載っていれば全部が対象で、
|
|
3483
|
-
// github
|
|
3590
|
+
// github の除外は行のバッジ(「読み取り停止中」)が示す
|
|
3591
|
+
//(件数の内訳は Gold トグルがあった頃の名残)
|
|
3484
3592
|
var unit = cap === "チャット" ? "チャンネル" : cap === "開発" ? "リポジトリ" : "件";
|
|
3485
3593
|
parts.push(live.length + unit);
|
|
3486
3594
|
} else if (cap === "共有資料" && adapter === "google-drive" && internal && internal.driveFolderIds) {
|
|
@@ -3643,7 +3751,7 @@ ${capabilityState.toString()}
|
|
|
3643
3751
|
|
|
3644
3752
|
// 注記は全能力の後ろに1つ。**何が Gold の材料になるのかを1文で言う。**
|
|
3645
3753
|
if (anyCap) {
|
|
3646
|
-
sec.appendChild(el("p", { class: "ds-note", text: "登録されている Slack チャンネルと GitHub リポジトリは、毎晩の Gold 昇格が読み取り、Decision
|
|
3754
|
+
sec.appendChild(el("p", { class: "ds-note", text: "登録されている Slack チャンネルと GitHub リポジトリは、毎晩の Gold 昇格が読み取り、Decision・用語集の材料になります。チャンネルは登録を解除すると、リポジトリは登録から削除すると、以後は読み取られません。" }));
|
|
3647
3755
|
}
|
|
3648
3756
|
|
|
3649
3757
|
if (pipes.length) {
|
|
@@ -3723,7 +3831,7 @@ ${capabilityState.toString()}
|
|
|
3723
3831
|
* 注: ここは埋め込みJSのテンプレートリテラル内。**コメントでもバッククォートを使わない**
|
|
3724
3832
|
*(リテラルが閉じて構文エラーになる。実際にそれで壊した)。
|
|
3725
3833
|
*
|
|
3726
|
-
*
|
|
3834
|
+
* **これが画面から Slack の読み取りを止める唯一の手段。** チャンネル単位の Gold トグルは撤去した
|
|
3727
3835
|
* (載っているチャンネルは例外なく全て Gold 昇格の対象)。事故(社内限定の会話が顧客可視の
|
|
3728
3836
|
* Gold へ流れ始めた)に画面から手を打てないと、git で channels.json を直接編集するしかない。
|
|
3729
3837
|
*
|
|
@@ -4072,12 +4180,16 @@ ${capabilityState.toString()}
|
|
|
4072
4180
|
* **キーはスペースごとに別。** 欄が1つだと、複数スペースの案件で
|
|
4073
4181
|
* 「どちらの鍵を入れたのか」が誰にも分からないまま片方の棚に入る。
|
|
4074
4182
|
*
|
|
4075
|
-
*
|
|
4183
|
+
* **ここは受け皿が無いときの退避先(2026-08-21)。** ふつうは接続先の行の中へ
|
|
4184
|
+
* 差し込む(KEY_SLOTS のコメント参照)。この関数が使われるのは、
|
|
4185
|
+
* 行を描く経路そのものが無い案件——intake を持たない案件——だけ。
|
|
4186
|
+
*
|
|
4187
|
+
* ## 登録状況はスペースごとに引く
|
|
4076
4188
|
*
|
|
4077
|
-
* 夜間の実測(secretSources.backlog)は**種別ごと**の1
|
|
4078
|
-
*
|
|
4079
|
-
*
|
|
4080
|
-
*
|
|
4189
|
+
* 夜間の実測(secretSources.backlog)は**種別ごと**の1つの値で、スペース別の充足を
|
|
4190
|
+
* 表せない。1枚目に帰属させると**片方だけ入れた状態で両方に「登録済み」と出る**
|
|
4191
|
+
* ——画面が嘘をつく。スペース別の答えは secretSpaces(engine 側)が持ち、
|
|
4192
|
+
* それが無い生成物では**断定しない**(「確認中」に倒す)。
|
|
4081
4193
|
*
|
|
4082
4194
|
* ## 接続先がまだ無いとき
|
|
4083
4195
|
*
|
|
@@ -4085,9 +4197,11 @@ ${capabilityState.toString()}
|
|
|
4085
4197
|
*/
|
|
4086
4198
|
function backlogSecretCards() {
|
|
4087
4199
|
var spaces = backlogSpacesNow();
|
|
4088
|
-
if (spaces.length <= 1) return [secretCard("backlog", SECRET_FORMS["backlog"])];
|
|
4200
|
+
if (spaces.length <= 1) return [secretCard("backlog", SECRET_FORMS["backlog"], { spaceCount: spaces.length })];
|
|
4089
4201
|
return spaces.map(function (space) {
|
|
4090
|
-
return secretCard("backlog", SECRET_FORMS["backlog"], {
|
|
4202
|
+
return secretCard("backlog", SECRET_FORMS["backlog"], {
|
|
4203
|
+
space: space, stateSpace: space, spaceCount: spaces.length,
|
|
4204
|
+
});
|
|
4091
4205
|
});
|
|
4092
4206
|
}
|
|
4093
4207
|
|
|
@@ -4170,9 +4284,48 @@ ${capabilityState.toString()}
|
|
|
4170
4284
|
return row;
|
|
4171
4285
|
}
|
|
4172
4286
|
|
|
4287
|
+
/**
|
|
4288
|
+
* 描く順番。**同じスペースの行を隣り合わせにする(2026-08-21)。**
|
|
4289
|
+
*
|
|
4290
|
+
* 鍵の欄はそのスペースの**最後の行の下**に1つだけ出すので、
|
|
4291
|
+
* 「cm1/A, jleague/B, cm1/C」のように入り混じっていると
|
|
4292
|
+
* **どの行の鍵なのかが読めない**(cm1 の鍵が jleague の行を挟んだ先に出る)。
|
|
4293
|
+
* スペースの初出の順は保つので、一覧の見え方は今までと変わらない。
|
|
4294
|
+
*/
|
|
4295
|
+
function grouped(list) {
|
|
4296
|
+
var order = [];
|
|
4297
|
+
var byDomain = {};
|
|
4298
|
+
for (var i = 0; i < list.length; i++) {
|
|
4299
|
+
var d = String(list[i].domain || "").toLowerCase();
|
|
4300
|
+
if (!byDomain[d]) { byDomain[d] = []; order.push(d); }
|
|
4301
|
+
byDomain[d].push(list[i]);
|
|
4302
|
+
}
|
|
4303
|
+
var out = [];
|
|
4304
|
+
for (var j = 0; j < order.length; j++) out = out.concat(byDomain[order[j]]);
|
|
4305
|
+
return out;
|
|
4306
|
+
}
|
|
4307
|
+
|
|
4173
4308
|
function paint() {
|
|
4174
4309
|
while (listEl.firstChild) listEl.removeChild(listEl.firstChild);
|
|
4175
|
-
|
|
4310
|
+
var shown = grouped(targets);
|
|
4311
|
+
// そのスペースの**最後の行**を覚えておく(鍵の欄はそこへ入れる)
|
|
4312
|
+
var lastRowOf = {};
|
|
4313
|
+
for (var i = 0; i < shown.length; i++) {
|
|
4314
|
+
var row = removeRow(shown[i]);
|
|
4315
|
+
listEl.appendChild(row);
|
|
4316
|
+
lastRowOf[String(shown[i].domain || "").toLowerCase()] = row;
|
|
4317
|
+
}
|
|
4318
|
+
// 🔴 **鍵の欄は作り直さない。入れ直すだけ。** ここは追加・削除の応答でも
|
|
4319
|
+
// 呼ばれるので、作り直すと**接続先を1つ足しただけで入力中の鍵と「保存中…」が消える**
|
|
4320
|
+
//(ライブ差し替えで踏んだのと同じ事故が、別の経路で復活する)。
|
|
4321
|
+
// appendChild は既存ノードを移すだけなので、入力値もイベントも保たれる
|
|
4322
|
+
for (var d in keySlots) {
|
|
4323
|
+
if (!Object.prototype.hasOwnProperty.call(keySlots, d)) continue;
|
|
4324
|
+
if (!d) continue; // 接続先が無い案件の受け皿は box 側に置いてある(行が無い)
|
|
4325
|
+
var host = lastRowOf[d];
|
|
4326
|
+
if (host) host.appendChild(keySlots[d]);
|
|
4327
|
+
else if (keySlots[d].parentNode) keySlots[d].parentNode.removeChild(keySlots[d]);
|
|
4328
|
+
}
|
|
4176
4329
|
// **0件を黙って見せない。** 表示が無いと「まだ何も無い」のか「出し忘れ」なのか
|
|
4177
4330
|
// 区別できない。**一覧の外**(Figma / Drive と同じ)に、件数に応じて出し入れする
|
|
4178
4331
|
// ——出しっぱなしにすると、設定済みの案件にも「未設定」と書いた行が残る
|
|
@@ -4201,10 +4354,40 @@ ${capabilityState.toString()}
|
|
|
4201
4354
|
return { onTargets: adoptTargets, staleNote: TARGETS_RACE_NOTE };
|
|
4202
4355
|
}
|
|
4203
4356
|
|
|
4357
|
+
// **鍵の欄の受け皿を、行のスペースごとに1つ用意する(2026-08-21・オーナー指摘)。**
|
|
4358
|
+
//
|
|
4359
|
+
// 🔴 **行のドメインから引くこと。** backlogSpacesNow() は backlogTargetsNow(null) を
|
|
4360
|
+
// 呼ぶので、fleet が接続先を持たない案件(同期ミラーのURLから1行だけ作っている案件)では
|
|
4361
|
+
// **空を返す**——行は出るのに鍵の欄が1つも付かない、という空振りになる。
|
|
4362
|
+
//
|
|
4363
|
+
// **この画面から投入できない案件(固定IP同期)には出さない。** 押しても Lambda が
|
|
4364
|
+
// 「固定IP経由のため対応していません」で断るので、導線そのものを作らない。
|
|
4365
|
+
// 判定は鍵カードを出すループの条件と同じ線(SITE.secretKinds に backlog があるか)。
|
|
4366
|
+
var keySlots = {};
|
|
4367
|
+
if (editable && !Object.keys(KEY_SLOTS.backlog).length) {
|
|
4368
|
+
// 保存時にスペースを名乗ってよいのは、名簿(fleet の backlogTarget)由来の行だけ。
|
|
4369
|
+
// 同期ミラーのURLから作った行で名乗ると、名簿とミラーがずれている案件で
|
|
4370
|
+
// **黙って別の棚に入る**(入れたのに動かない、が一番起きてほしくない形)
|
|
4371
|
+
KEY_SLOTS.backlogNamed = backlogTargetsNow(null).length > 0;
|
|
4372
|
+
var domains = [];
|
|
4373
|
+
for (var ti = 0; ti < targets.length; ti++) {
|
|
4374
|
+
var dom = String(targets[ti].domain || "").toLowerCase();
|
|
4375
|
+
if (dom && domains.indexOf(dom) === -1) domains.push(dom);
|
|
4376
|
+
}
|
|
4377
|
+
// **0件の案件にも1つ出す。** 「接続先を足してからでないと鍵を入れられない」形にすると、
|
|
4378
|
+
// 立ち上げ直後の案件が最初の一歩を踏めない(#138 で直したのと同じ穴)。
|
|
4379
|
+
// 空文字のキーは「どのスペースとも結び付いていない受け皿」で、行の中には入らない
|
|
4380
|
+
if (!domains.length) domains.push("");
|
|
4381
|
+
for (var di = 0; di < domains.length; di++) keySlots[domains[di]] = el("div", { class: "ds-keyrow" });
|
|
4382
|
+
KEY_SLOTS.backlog = keySlots;
|
|
4383
|
+
}
|
|
4384
|
+
|
|
4204
4385
|
// **box を先に作る。** paint() は 0件の1行を box へ出し入れするので、
|
|
4205
4386
|
// 箱が無いと最初の描画で「未設定」の行が出ない
|
|
4206
4387
|
var box = el("div", {}, [listEl]);
|
|
4207
4388
|
paint();
|
|
4389
|
+
// 接続先がまだ無い案件の受け皿は、0件の1行の直後に置く(行が無いので中へ入れられない)
|
|
4390
|
+
if (keySlots[""]) box.appendChild(keySlots[""]);
|
|
4208
4391
|
if (editable) {
|
|
4209
4392
|
box.appendChild(addForm({
|
|
4210
4393
|
// **「追加」に戻す(#127)。** 1件しか持てなかった頃は「保存」(置き換え)だったが、
|
|
@@ -4215,7 +4398,7 @@ ${capabilityState.toString()}
|
|
|
4215
4398
|
// **手順のリストにする(2026-08-20・Slack からの横展開)。**
|
|
4216
4399
|
// **リスト(ol.sec-steps)そのものは維持する**——他の能力の手順と形を揃える。
|
|
4217
4400
|
//
|
|
4218
|
-
// **鍵の発行手順は二重に持たない。**
|
|
4401
|
+
// **鍵の発行手順は二重に持たない。** 正本は接続先の行の下にある鍵の欄
|
|
4219
4402
|
//(SECRET_FORMS.backlog の how)で、ここからは参照するだけ。
|
|
4220
4403
|
//
|
|
4221
4404
|
// ## 4行 → 2行に圧縮した(2026-08-21・オーナー指摘「何も変わってない気がする」)
|
|
@@ -4225,8 +4408,8 @@ ${capabilityState.toString()}
|
|
|
4225
4408
|
// ここ以外に置き場が無いので、**消さずに2行へ畳んでいる**:
|
|
4226
4409
|
// - 「起票先は変わりません」… 追加の確認をやめたとき(2026-08-20)に
|
|
4227
4410
|
// ここへ移してきたもの。落とすと知る手段が無くなる
|
|
4228
|
-
// - 「スペースごとに別のキー」…
|
|
4229
|
-
//
|
|
4411
|
+
// - 「スペースごとに別のキー」… 鍵の欄からは読めない。1スペースの案件は
|
|
4412
|
+
// 行が1本しか無いので、これから2つ目を足す人に「別の鍵が要る」が届かない
|
|
4230
4413
|
// - 「案件専用URLの登録」… 救出先の realtimeSyncCard() は稼働中の案件では
|
|
4231
4414
|
// 手順一式を <details> に畳むので、**いちばん要る人に対して閉じている**
|
|
4232
4415
|
hint: [
|
|
@@ -4507,6 +4690,15 @@ ${capabilityState.toString()}
|
|
|
4507
4690
|
// 「読めていない」のか区別できない(Driveは driveState で理由まで出している)
|
|
4508
4691
|
box.appendChild(el("p", { class: "ds-empty", text: "同期対象のFigmaファイルはまだ登録されていません。" }));
|
|
4509
4692
|
}
|
|
4693
|
+
// **鍵の欄は一覧の直後に1つ(2026-08-21・オーナー指摘)。**
|
|
4694
|
+
// Backlog と違い、Figma の鍵は**案件に1本**(ファイルごとではない)。
|
|
4695
|
+
// 行ごとに出すと同じ欄が並ぶだけなので、一覧をひとまとまりと見て、その下に置く。
|
|
4696
|
+
// **中身を作るのはここではない**——SECRET_FORMS のループが差し込む
|
|
4697
|
+
//(intake / OFF のゲートをループ側に残すため。KEY_SLOTS のコメント参照)
|
|
4698
|
+
if (!KEY_SLOTS.figma) {
|
|
4699
|
+
KEY_SLOTS.figma = el("div", { class: "ds-keyrow ds-keyrow-list" });
|
|
4700
|
+
box.appendChild(KEY_SLOTS.figma);
|
|
4701
|
+
}
|
|
4510
4702
|
box.appendChild(addForm({
|
|
4511
4703
|
title: "+ Figmaファイルを追加",
|
|
4512
4704
|
placeholder: "https://www.figma.com/design/…",
|
|
@@ -4515,11 +4707,11 @@ ${capabilityState.toString()}
|
|
|
4515
4707
|
// **手順のリストにする(2026-08-20・Slack からの横展開)。**
|
|
4516
4708
|
// 一続きの文章だと、読む人が「自分がいま何をすべきか」を自分で切り出すことになる。
|
|
4517
4709
|
//
|
|
4518
|
-
// **手順1・2
|
|
4710
|
+
// **手順1・2は要約にとどめ、正本は上の鍵の欄に置く**(SECRET_FORMS.figma の
|
|
4519
4711
|
// how / note)。全文をここに移すと二重になり、片方だけ直る形になる
|
|
4520
4712
|
// ——カードは接続マップとタイルの注記と条件を揃えているので、動かすと壊れやすい。
|
|
4521
4713
|
hint: [
|
|
4522
|
-
"Figma でトークンを発行します(読み取りだけ。スコープ2
|
|
4714
|
+
"Figma でトークンを発行します(読み取りだけ。スコープ2つ)。手順は上の「Figma のトークン」の欄にあります。",
|
|
4523
4715
|
"発行したアカウントを、読み取りたい Figma ファイルに閲覧者として招待します(招待が無いと、トークンが正しくても読めません)。",
|
|
4524
4716
|
"そのファイルのURLを下の欄に貼って「追加」を押します。",
|
|
4525
4717
|
"追加したファイルは、画面名と Figma へのリンクが毎晩同期されます(画像は取り込まれません)。",
|
|
@@ -4634,7 +4826,7 @@ ${capabilityState.toString()}
|
|
|
4634
4826
|
hint: [
|
|
4635
4827
|
{ text: "読み取りたいリポジトリがある組織に、Cortex の GitHub App を入れます(Issues の読み取りだけ)。", node: appInstallLink() },
|
|
4636
4828
|
"そのリポジトリを下の欄に入れて「追加」を押します(owner/repo でも、GitHub のURLでも構いません)。",
|
|
4637
|
-
"追加したリポジトリの Issues が、毎晩の Gold
|
|
4829
|
+
"追加したリポジトリの Issues が、毎晩の Gold 昇格の材料になります。やめるときは、その行の「登録から削除」を押します。",
|
|
4638
4830
|
],
|
|
4639
4831
|
build: function (repo, name) { return { op: "add-github-source", repo: repo, name: name }; },
|
|
4640
4832
|
adder: "github",
|
|
@@ -4878,39 +5070,30 @@ ${capabilityState.toString()}
|
|
|
4878
5070
|
}
|
|
4879
5071
|
|
|
4880
5072
|
/**
|
|
4881
|
-
* ON/OFF
|
|
4882
|
-
*
|
|
5073
|
+
* ⚠ **ON/OFF のトグル(stateToggle)は関数ごと撤去した(2026-08-21・オーナー判断)。**
|
|
5074
|
+
*
|
|
5075
|
+
* 唯一の利用者が GitHub の「読み取りを止める/始める」だった。オーナー指摘:
|
|
5076
|
+
* 「登録から削除っていうボタンがあるのに、これがある理由がわかんないです」。
|
|
5077
|
+
*
|
|
5078
|
+
* 作った理由は「**自動で見つかったリポジトリ(derived)は登録簿から消しても
|
|
5079
|
+
* 翌日また現れるので、止めることだけはできるようにする**」だったが、
|
|
5080
|
+
* #119 以降に生成されたデータの github は必ず explicit で、全9案件36リポジトリの
|
|
5081
|
+
* 実測でも derived は0件・excluded も0件だった。
|
|
5082
|
+
*
|
|
5083
|
+
* **残さずに消す。** 呼び出しが1つも無い関数を残すと、壊しても何も起きない
|
|
5084
|
+
* =変異検証の網から静かに漏れる(このリポジトリが繰り返し踏んでいる形)。
|
|
5085
|
+
* 同じ理由で「ds-toggle-btn is-on」(押した向きを示すクラス)の生成元も無くなった。
|
|
5086
|
+
*
|
|
5087
|
+
* ⚠ **confirmOn(広げる向きだけ確認する)の利用者もこれだけだった。**
|
|
5088
|
+
* 「広げる向きの確認を await し損ねていないか」を見ていた検査は**引き継げない**
|
|
5089
|
+
* ——removeButton は向きに関わらず必ず確認するので、同じ性質を持たない。
|
|
5090
|
+
*
|
|
5091
|
+
* ⚠ **サーバ側の受け口(op=set-github-source-enabled)は残してある。**
|
|
5092
|
+
* 理由は logic.mjs の RETIRED_CONFIG_OPS のコメントに書いた。
|
|
4883
5093
|
*/
|
|
4884
|
-
function stateToggle(opts) {
|
|
4885
|
-
var wrap = el("div", { class: "ds-toggle" });
|
|
4886
|
-
var on = opts.on === true;
|
|
4887
|
-
var btn = el("button", { class: "ds-toggle-btn" + (on ? " is-on" : ""), type: "button" });
|
|
4888
|
-
var msg = el("div", { class: "ds-toggle-msg" });
|
|
4889
|
-
var paint = function () {
|
|
4890
|
-
btn.textContent = on ? opts.labelOn : opts.labelOff;
|
|
4891
|
-
btn.className = "ds-toggle-btn" + (on ? " is-on" : "");
|
|
4892
|
-
};
|
|
4893
|
-
paint();
|
|
4894
|
-
|
|
4895
|
-
btn.addEventListener("click", async function () {
|
|
4896
|
-
var next = !on;
|
|
4897
|
-
// 読み始める方向(危険)だけ確認する。止める方向は素通し
|
|
4898
|
-
if (next && opts.confirmOn && !(await confirmDanger(opts.confirmOn, { returnTo: btn }))) { msg.textContent = ""; return; }
|
|
4899
|
-
sendConfig(opts.build(next), msg, btn, function () {
|
|
4900
|
-
// **押した内容をボタンに反映し、逆向きの操作を残す。**
|
|
4901
|
-
// **カードごと作り直さない。** 上の msg に出した結果表示が消えてしまう
|
|
4902
|
-
on = next;
|
|
4903
|
-
paint();
|
|
4904
|
-
});
|
|
4905
|
-
});
|
|
4906
|
-
wrap.appendChild(btn);
|
|
4907
|
-
wrap.appendChild(msg);
|
|
4908
|
-
return wrap;
|
|
4909
|
-
}
|
|
4910
5094
|
|
|
4911
5095
|
/**
|
|
4912
|
-
*
|
|
4913
|
-
* 向きに関わらず取り消せないので常に確認する)。
|
|
5096
|
+
* 削除ボタン。**必ず確認を出す**(取り消せないので、向きに関わらず確認する)。
|
|
4914
5097
|
*
|
|
4915
5098
|
* 成功しても一覧からは消さない。接続状況は夜間バッチのスナップショットで、消したつもりの行が
|
|
4916
5099
|
* 翌朝まで残るのが正しい状態のため——行に取り消し線を引き、ボタンだけを無効にする
|
|
@@ -5116,18 +5299,24 @@ ${capabilityState.toString()}
|
|
|
5116
5299
|
return teamId;
|
|
5117
5300
|
}
|
|
5118
5301
|
|
|
5119
|
-
var ORIGIN_LABEL = { explicit: "明示登録", derived: "自動検出", both: "明示登録+自動検出" };
|
|
5120
|
-
var ORIGIN_HELP = {
|
|
5121
|
-
explicit: "開発の登録ファイル(dev-sources.json)に登録されているリポジトリです。ここから登録を削除できます。",
|
|
5122
|
-
derived: ".gitmodules から自動で見つかったリポジトリです。登録ファイルに無いので削除はできません(読み取りを止めることはできます)。",
|
|
5123
|
-
both: "登録ファイルにも書かれていて、.gitmodules からも見つかっているリポジトリです。",
|
|
5124
|
-
};
|
|
5125
5302
|
|
|
5126
5303
|
function extSourceCard(s, meta) {
|
|
5127
5304
|
var badges = el("div", { class: "ds-badges" });
|
|
5128
5305
|
// **Gold 対象かのバッジは持たない。** 一覧に並ぶ Slack チャンネルは例外なく全て対象で、
|
|
5129
|
-
// 行ごとに「対象です」と書いても情報が増えない。
|
|
5130
|
-
//
|
|
5306
|
+
// 行ごとに「対象です」と書いても情報が増えない。
|
|
5307
|
+
//
|
|
5308
|
+
// 🔴 **github の除外(goldState: "excluded")だけは印を出す(2026-08-21)。**
|
|
5309
|
+
// それまでは行のトグル(「読み取りを始める/止める」)が**向きで示していた**ので、
|
|
5310
|
+
// トグルを撤去すると**読み取られていないのに印が1つも無い行**になる。
|
|
5311
|
+
// sourceNeedsAttention も excluded を警告から外すので、他に気づく手掛かりが無い。
|
|
5312
|
+
// 実測では0件だが、exclude は dev-sources.json に手で書けるので「今日は0件」でしかない
|
|
5313
|
+
if (String(s.type).indexOf("github") === 0 && s.goldState === "excluded") {
|
|
5314
|
+
badges.appendChild(el("span", {
|
|
5315
|
+
class: "badge ds-excluded",
|
|
5316
|
+
text: "読み取り停止中",
|
|
5317
|
+
title: "このリポジトリは読み取り対象から除外されています(開発の登録ファイル dev-sources.json の exclude)。この画面からは戻せません。",
|
|
5318
|
+
}));
|
|
5319
|
+
}
|
|
5131
5320
|
if (s.notify === true) badges.appendChild(el("span", { class: "badge ds-notify", text: "通知先" }));
|
|
5132
5321
|
// **どのワークスペースのチャンネルかを、必ず行に出す(#104・2026-08-20 に社内も)。**
|
|
5133
5322
|
//
|
|
@@ -5160,13 +5349,6 @@ ${capabilityState.toString()}
|
|
|
5160
5349
|
}
|
|
5161
5350
|
}
|
|
5162
5351
|
// 登録の由来(#118)。**「登録から削除」が出る/出ないの理由がこれ。** 導出されたリポは
|
|
5163
|
-
// 登録ファイルから消しても翌日また現れるので削除を出していないが、画面には
|
|
5164
|
-
// 「同じ見た目の行なのに、片方にだけ削除がある」としか映らず、毎回考え直すことになる。
|
|
5165
|
-
// **GitHub の行だけに出す。** ORIGIN_HELP の文面がリポジトリと .gitmodules に
|
|
5166
|
-
// 特化していて、Slack に出すと嘘になる。Slack も由来で「登録を解除」を出し分ける
|
|
5167
|
-
// ようになった(explicit には出さない)が、Slack で explicit なのは登録ファイルに
|
|
5168
|
-
// 直接書いた例外的な行だけで、バッジのために文面をもう一組増やすには釣り合わない。
|
|
5169
|
-
// #119 以降、新しいデータの github は必ず explicit(詳細は ORIGIN_LABEL)
|
|
5170
5352
|
// **どの組織のリポジトリかを行に出す(2026-08-20)。**
|
|
5171
5353
|
// 組織ごとの独立した一覧をやめたので、**組織を言うのは行のラベルだけ**になった。
|
|
5172
5354
|
// トークンは組織ごとにしか効かないので、これが判断の単位になる
|
|
@@ -5191,13 +5373,16 @@ ${capabilityState.toString()}
|
|
|
5191
5373
|
}));
|
|
5192
5374
|
}
|
|
5193
5375
|
}
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5376
|
+
// **登録の由来は出さない(2026-08-21・オーナー指摘)。**
|
|
5377
|
+
//
|
|
5378
|
+
// 由来は「明示登録(人が登録簿に書いた)」と「自動検出(.gitmodules から見つかった)」の
|
|
5379
|
+
// 2つで、**自動検出は登録簿から消しても翌日また現れる**ので違いを見せていた。
|
|
5380
|
+
//
|
|
5381
|
+
// **実測(全9案件・37リポジトリ)で自動検出は0件。** 全部の行に同じ札が並ぶだけで、
|
|
5382
|
+
// 読む人にとって情報量がゼロだった。「読み取りを止める」を廃止したのと同じ理由で外す。
|
|
5383
|
+
//
|
|
5384
|
+
// ⚠ **s.origin 自体は残す。** 「登録から削除」を出すかどうかの判定に使っている
|
|
5385
|
+
//(自動検出の行に削除を出すと、押しても翌日戻ってくる)。**札を出さないだけ**
|
|
5201
5386
|
var gate = dsGateOf(s);
|
|
5202
5387
|
// **「接続を確認」が押されたら、この要素を live の判定で置き換える**(probeSection)。
|
|
5203
5388
|
// 2つの判定を同じ行に並べないため、参照を持っておく
|
|
@@ -5223,32 +5408,20 @@ ${capabilityState.toString()}
|
|
|
5223
5408
|
if (SITE.intake && s.type === "slack" && s.ref && s.origin !== "explicit") {
|
|
5224
5409
|
card.appendChild(removeChannelButton(s, card));
|
|
5225
5410
|
}
|
|
5226
|
-
// GitHub
|
|
5411
|
+
// GitHubリポの登録から削除。**ON/OFF のトグルは撤去した(2026-08-21)**
|
|
5412
|
+
//(stateToggle のコメント参照)。
|
|
5227
5413
|
if (SITE.intake && s.type.indexOf("github") === 0 && s.ref) {
|
|
5228
|
-
card.appendChild(stateToggle({
|
|
5229
|
-
on: s.goldState !== "excluded",
|
|
5230
|
-
labelOn: "読み取りを止める",
|
|
5231
|
-
labelOff: "読み取りを始める",
|
|
5232
|
-
confirmOn: [
|
|
5233
|
-
"このリポジトリの Issues を、Gold 昇格の材料に戻します。",
|
|
5234
|
-
"",
|
|
5235
|
-
"Issues の内容から、Decision・用語集が作られます。",
|
|
5236
|
-
"",
|
|
5237
|
-
s.ref,
|
|
5238
|
-
"",
|
|
5239
|
-
"有効にしますか?",
|
|
5240
|
-
],
|
|
5241
|
-
build: function (next) {
|
|
5242
|
-
return { op: "set-github-source-enabled", repo: s.ref, value: next };
|
|
5243
|
-
},
|
|
5244
|
-
}));
|
|
5245
5414
|
// **削除は「手で登録したもの」にだけ出す。** 自動で見つかったリポは
|
|
5246
5415
|
// 登録ファイルから消しても翌日また現れる(=消えないのに消せたように見える)。
|
|
5247
|
-
//
|
|
5416
|
+
//
|
|
5417
|
+
// ⚠ **トグルを撤去したので、derived / both / 由来不明の行には操作が1つも無くなる**
|
|
5418
|
+
//(分類B・2026-08-21 に記録)。実測で derived は0件だが、.gitmodules からの
|
|
5419
|
+
// 導出経路が消えたわけではない。再び現れたら、その行は**画面からは止められない**
|
|
5420
|
+
// ——dev-sources.json の exclude を直接編集する。
|
|
5248
5421
|
//
|
|
5249
5422
|
// **#119 以降、新しいデータの github は必ず explicit** なので、この条件は
|
|
5250
5423
|
// いずれ常に真になる。それまでは残す——再生成前のスナップショットには derived が
|
|
5251
|
-
//
|
|
5424
|
+
// まだ入っており、条件を外すと押しても戻ってくる削除ボタンが出る。
|
|
5252
5425
|
if (s.origin === "explicit") {
|
|
5253
5426
|
card.appendChild(removeButton({
|
|
5254
5427
|
label: "登録から削除",
|
|
@@ -5256,7 +5429,10 @@ ${capabilityState.toString()}
|
|
|
5256
5429
|
return [
|
|
5257
5430
|
"「" + s.ref + "」を、読み取り対象の登録から削除します。",
|
|
5258
5431
|
"",
|
|
5259
|
-
|
|
5432
|
+
// **「読み取りを止める」への案内は消した(2026-08-21)。** そのボタンごと
|
|
5433
|
+
// 撤去したので、指す先が画面に無い。**代わりの手段は書かない**
|
|
5434
|
+
//——削除がその手段そのもので、他に無い
|
|
5435
|
+
"次回の Gold 昇格から、このリポジトリの Issues は読み取られません。",
|
|
5260
5436
|
"",
|
|
5261
5437
|
"すでに作られた Decision・用語集は消えません。",
|
|
5262
5438
|
"",
|
|
@@ -5562,7 +5738,12 @@ ${capabilityState.toString()}
|
|
|
5562
5738
|
return el("div", { class: "ops-card rt-card is-live" }, [
|
|
5563
5739
|
el("div", { class: "ops-card-head" }, [
|
|
5564
5740
|
el("span", { class: "ops-card-icon", text: "⚡" }),
|
|
5565
|
-
|
|
5741
|
+
// **「(任意)」を付ける(2026-08-21・オーナー指摘「リアルタイム同期は
|
|
5742
|
+
// オプションなので、一番下に配置してほしい」)。** 設定しなくても毎晩の同期で
|
|
5743
|
+
// 反映されるので、必須の手順と並べると「まだ終わっていない」と読まれる。
|
|
5744
|
+
// ⚠ **改名箇所は2つある**(稼働中の枝と未設定の枝)。片方だけ直すと、
|
|
5745
|
+
// **これから設定する人にだけ「(任意)」が付かない**=一番読ませたい人に届かない
|
|
5746
|
+
el("h3", { class: "ops-card-title", text: "リアルタイム同期(任意)" }),
|
|
5566
5747
|
el("span", { class: "rt-live-badge", text: "✓ 稼働中" }),
|
|
5567
5748
|
]),
|
|
5568
5749
|
lines,
|
|
@@ -5574,7 +5755,9 @@ ${capabilityState.toString()}
|
|
|
5574
5755
|
return el("div", { class: "ops-card rt-card" }, [
|
|
5575
5756
|
el("div", { class: "ops-card-head" }, [
|
|
5576
5757
|
el("span", { class: "ops-card-icon", text: "⚡" }),
|
|
5577
|
-
|
|
5758
|
+
// **稼働中の枝と同じ見出しにする**(上の ⚠ 参照。片方だけ直すと、
|
|
5759
|
+
// これから設定する人にだけ「(任意)」が付かない)
|
|
5760
|
+
el("h3", { class: "ops-card-title", text: "リアルタイム同期(任意)" }),
|
|
5578
5761
|
]),
|
|
5579
5762
|
el("p", { class: "ops-card-desc", text: "Backlog で課題やコメントが変わったときに、その内容をすぐ取り込みます(毎晩の同期を待たずに反映されます)。Backlog 側で一度だけ設定してください。" }),
|
|
5580
5763
|
].concat(steps));
|
|
@@ -5657,39 +5840,68 @@ ${capabilityState.toString()}
|
|
|
5657
5840
|
}
|
|
5658
5841
|
|
|
5659
5842
|
/**
|
|
5660
|
-
*
|
|
5661
|
-
*
|
|
5662
|
-
*
|
|
5843
|
+
* 鍵が登録されているかを、そのカードが担当する範囲で答える(2026-08-21)。
|
|
5844
|
+
*
|
|
5845
|
+
* 返す値は "yes" / "no" / "unknown" の**3つ**。
|
|
5846
|
+
*
|
|
5847
|
+
* 🔴 **"unknown" を潰さないこと。** スペースごとの登録状況(secretSpaces)を出すのは
|
|
5848
|
+
* engine 側で、配布は**画面が先・engine が後**——secretSpaces を知らない生成物を
|
|
5849
|
+
* 画面が読む期間が必ずある。そこで「未登録」に倒すと、
|
|
5850
|
+
* **入っている鍵を「入っていない」と断定して、要らない貼り直しをさせる。**
|
|
5851
|
+
*
|
|
5852
|
+
* @returns { known, src } src は取得元の文字列("yes" のときだけ意味を持つ)
|
|
5853
|
+
*/
|
|
5854
|
+
function secretStateOf(kind, stateSpace, spaceCount) {
|
|
5855
|
+
var perKind = (fleetVal("secretSources") || {})[kind] || "";
|
|
5856
|
+
var spaces = fleetVal("secretSpaces");
|
|
5857
|
+
if (kind === "backlog" && stateSpace && spaces && typeof spaces === "object") {
|
|
5858
|
+
var v = spaces[stateSpace];
|
|
5859
|
+
if (v === "new") return { known: "yes", src: "Secrets Manager" };
|
|
5860
|
+
if (v === "legacy") return { known: "yes", src: "Secrets Manager(旧名)" };
|
|
5861
|
+
if (v === "false") return { known: "no", src: "" };
|
|
5862
|
+
}
|
|
5863
|
+
// **スペースが1つに定まるなら、種別ごとの値で答えてよい。** 取り違えようがないので、
|
|
5864
|
+
// engine が secretSpaces を出す前から今までどおりの表示を保てる
|
|
5865
|
+
if ((spaceCount || 0) <= 1) return { known: perKind ? "yes" : "no", src: perKind };
|
|
5866
|
+
// 複数スペースなのに、スペース別の答えが無い。**片方だけ入れた状態を表せない**ので
|
|
5867
|
+
// 断定しない(「登録済み」も「未登録」も、どちらかのスペースで嘘になる)
|
|
5868
|
+
return { known: "unknown", src: "" };
|
|
5869
|
+
}
|
|
5870
|
+
|
|
5871
|
+
/**
|
|
5872
|
+
* @param opts { space, stateSpace, spaceCount, inRow }
|
|
5873
|
+
* space … 保存時に名乗る Backlog スペース(名乗らないときは空)
|
|
5874
|
+
* stateSpace … 状態を引くスペース(画面の行のドメイン)
|
|
5875
|
+
* spaceCount … 画面に出ているスペースの数(1つなら種別ごとの値で答えられる)
|
|
5876
|
+
* inRow … レコードの行の中に置く(枠と影を持たない見た目にする)
|
|
5663
5877
|
*/
|
|
5664
5878
|
function secretCard(kind, meta, opts) {
|
|
5665
5879
|
var cardSpace = (opts && opts.space) || "";
|
|
5666
|
-
var
|
|
5667
|
-
|
|
5880
|
+
var stateSpace = (opts && opts.stateSpace) || "";
|
|
5881
|
+
var spaceCount = (opts && opts.spaceCount) || 0;
|
|
5882
|
+
var inRow = !!(opts && opts.inRow);
|
|
5883
|
+
// **いま登録されているか**を先に出す。入れ直したのに反映されていない状態が
|
|
5668
5884
|
// 画面で分かるようにする(接続状況は夜間バッチのスナップショットなので、
|
|
5669
5885
|
// 保存の直後は前日の値のまま。時刻は上の節に出している)。
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
var
|
|
5673
|
-
//
|
|
5674
|
-
//
|
|
5675
|
-
|
|
5886
|
+
var st = secretStateOf(kind, stateSpace, spaceCount);
|
|
5887
|
+
var src = st.known === "yes" ? st.src : "";
|
|
5888
|
+
var cardTitle = meta.title;
|
|
5889
|
+
// 🔴 **「登録済み」は「読めている」を意味しない。** 鍵が入っていても、そのアカウントから
|
|
5890
|
+
// プロジェクトが見えなければ同期は失敗する。**「接続OK」「同期OK」とは書かないこと**
|
|
5891
|
+
//(同期できているかのバッジは、夜間処理が接続先ごとの成否を保存してからの別作業)。
|
|
5892
|
+
//
|
|
5676
5893
|
// **前方一致で見る。** #105 の移行期は「Secrets Manager(旧名)」も来る。
|
|
5677
5894
|
// 完全一致にすると、旧名で動いている案件だけが repo secret と同じ見た目になり、
|
|
5678
5895
|
// 「管理下にあるのに未移行」という一番知りたい状態が画面から消える
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
text: "スペースごとの登録状況は、まだ表示できません(貼り直すと、このスペースの鍵として上書きされます)" })
|
|
5689
|
-
: src
|
|
5690
|
-
? el("p", { class: "sec-state" + (src.indexOf("Secrets Manager") === 0 ? " is-managed" : ""),
|
|
5691
|
-
text: "現在: " + src + " から取得中" })
|
|
5692
|
-
: el("p", { class: "sec-state is-none", text: "現在: 未設定" });
|
|
5896
|
+
var state = st.known === "yes"
|
|
5897
|
+
? el("p", { class: "sec-state" + (src.indexOf("Secrets Manager") === 0 ? " is-managed" : ""),
|
|
5898
|
+
text: "登録済み(" + src + " から取得中)" })
|
|
5899
|
+
: st.known === "no"
|
|
5900
|
+
? el("p", { class: "sec-state is-none", text: "未登録" })
|
|
5901
|
+
// **断定しない(レビュー指摘)。** 黙って消すと、利用者は
|
|
5902
|
+
// 「入っているのか未登録なのか」も「なぜ表示が無いのか」も知る手段が無い
|
|
5903
|
+
: el("p", { class: "sec-state is-unknown",
|
|
5904
|
+
text: "登録状況を確認中です(スペースごとの状況は、次回の自動チェックのあとに表示されます)" });
|
|
5693
5905
|
|
|
5694
5906
|
var input = el("input", { class: "sec-input", type: "password", placeholder: "トークンを貼り付け", autocomplete: "off" });
|
|
5695
5907
|
var btn = el("button", { class: "ds-toggle-btn", type: "button", text: "保存" });
|
|
@@ -5752,18 +5964,33 @@ ${capabilityState.toString()}
|
|
|
5752
5964
|
var guidanceBox = el("details", { class: "sec-fold" }, [el("summary", { text: "発行のしかた" })]);
|
|
5753
5965
|
for (var gi = 0; gi < guidance.length; gi++) guidanceBox.appendChild(guidance[gi]);
|
|
5754
5966
|
|
|
5755
|
-
//
|
|
5967
|
+
// **押すまで入力欄を出さない(2026-08-21・オーナー指摘)。**
|
|
5968
|
+
// 「今のAPIキーのセクション、欄があると思うんだけど…押すとフォームだけ出てくる」。
|
|
5756
5969
|
//
|
|
5757
|
-
//
|
|
5758
|
-
//
|
|
5970
|
+
// 🔴 **前回とは向きが逆。** 前回は「.sec-input は畳まない」と決めていたが、
|
|
5971
|
+
// 鍵の欄がレコードの行の下へ移り、**行に常時ぶら下がる入力欄**になったため、
|
|
5972
|
+
// 一覧の見通しを取り戻す側へ倒した。**状態(.sec-state)は畳まない**ので、
|
|
5973
|
+
// 「保存したのに反映されていない」は開かなくても読める。
|
|
5759
5974
|
//
|
|
5760
|
-
//
|
|
5975
|
+
// ⚠ **DOM には常に置く**(押すまで生成しない作りにしない)。ライブ差し替えは
|
|
5976
|
+
// input のノードを直接触るし、テストも card.querySelector("input.sec-input") で掴む。
|
|
5977
|
+
// ⚠ **<summary> は button ではない**ので、「保存」を掴む既存の取り方は変わらない。
|
|
5978
|
+
var inputFold = el("details", { class: "sec-input-fold" }, [
|
|
5979
|
+
el("summary", { class: "sec-input-summary", text: st.known === "yes" ? "入れ直す" : "登録する" }),
|
|
5980
|
+
]);
|
|
5981
|
+
inputFold.appendChild(input);
|
|
5982
|
+
inputFold.appendChild(el("div", { class: "ds-toggle" }, [btn, msg]));
|
|
5983
|
+
|
|
5984
|
+
// ライブ取得後に状態の行だけを差し替えるための目印(カードごと作り直すと入力が消える)
|
|
5985
|
+
//
|
|
5986
|
+
// **並びは「状態 → 貼る(畳む) → 畳んだ手順」。**
|
|
5987
|
+
//
|
|
5988
|
+
// 🔴 **.sec-state / .sec-preferred は <details> の外に置くこと。**
|
|
5761
5989
|
// - .sec-state … 保存したのに反映されていない状態が分かる唯一の手段。
|
|
5762
5990
|
// 押すまで見えないと成立しない
|
|
5763
5991
|
// - .sec-preferred … 「誰のアカウントで発行するのか」を**手順より先に**伝える行。
|
|
5764
|
-
//
|
|
5765
|
-
|
|
5766
|
-
return el("div", { class: "ops-card", "data-secret-kind": kind }, [
|
|
5992
|
+
// 未登録のときだけ出る=これから貼る人にだけ出るので、畳むと存在理由が消える
|
|
5993
|
+
return el("div", { class: "ops-card" + (inRow ? " ds-keycard" : ""), "data-secret-kind": kind }, [
|
|
5767
5994
|
el("div", { class: "ops-card-head" }, [
|
|
5768
5995
|
el("span", { class: "ops-card-icon", text: meta.icon }),
|
|
5769
5996
|
el("h3", { class: "ops-card-title", text: cardTitle }),
|
|
@@ -5772,11 +5999,11 @@ ${capabilityState.toString()}
|
|
|
5772
5999
|
// 代入するので、無条件に出すと画面に文字列 undefined が出る
|
|
5773
6000
|
meta.desc ? el("p", { class: "ops-card-desc", text: meta.desc }) : null,
|
|
5774
6001
|
state,
|
|
5775
|
-
//
|
|
5776
|
-
//
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
6002
|
+
// **未登録のときだけ、先に試すべき手を出す。** 既に動いているカードに
|
|
6003
|
+
// 「まずこれをやれ」と出すと、直す必要が無いものを触らせることになる。
|
|
6004
|
+
// **「確認中」にも出さない**——入っているかもしれないものを触らせない
|
|
6005
|
+
st.known === "no" && meta.selfServe ? el("p", { class: "sec-preferred", text: meta.selfServe.text }) : null,
|
|
6006
|
+
inputFold,
|
|
5780
6007
|
guidanceBox,
|
|
5781
6008
|
// **扱いの説明はカードに持たせる。** 節の見出しの下に置いていたときは、
|
|
5782
6009
|
// #101 でカードだけがモーダルへ移り、説明だけが画面から消えた。
|
|
@@ -5925,10 +6152,10 @@ ${capabilityState.toString()}
|
|
|
5925
6152
|
* モーダルを app に載せて、中へフォーカスを移す。
|
|
5926
6153
|
*
|
|
5927
6154
|
* **「最初の focusable」に載せてはいけない。** 一覧の先頭に来るのは
|
|
5928
|
-
*
|
|
5929
|
-
*
|
|
5930
|
-
*
|
|
5931
|
-
*
|
|
6155
|
+
* 「登録を解除」「このファイルを外す」といった設定を書き換えるボタンで、
|
|
6156
|
+
* タイルを Enter で開いてもう一度 Enter を押しただけで、そこへ手が届く。
|
|
6157
|
+
* いま並んでいるものは確認を必ず出すが、**確認を出さない操作が1つ増えるだけで
|
|
6158
|
+
* この形は復活する**ので、載せ先の側で塞いでおく。
|
|
5932
6159
|
* 移す先は閉じるボタン——押しても何も壊れないものにする。
|
|
5933
6160
|
*/
|
|
5934
6161
|
/**
|