@takagaki/cortex-decisions-viewer 0.12.24 → 0.12.25
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 -96
- package/package.json +1 -1
package/dist/render.js
CHANGED
|
@@ -86,6 +86,7 @@ ${styleTag}
|
|
|
86
86
|
<body>
|
|
87
87
|
<header class="site-header">
|
|
88
88
|
<div class="header-inner">
|
|
89
|
+
<span class="site-icon-slot" id="site-icon-slot"></span>
|
|
89
90
|
<a class="site-title" href="?" id="home-link">${safeTitle}</a>
|
|
90
91
|
${askBtn}
|
|
91
92
|
${githubBtn}
|
|
@@ -2261,6 +2262,71 @@ a:hover { text-decoration: underline; }
|
|
|
2261
2262
|
}
|
|
2262
2263
|
.site-title { font-size: 18px; font-weight: 700; color: var(--text); }
|
|
2263
2264
|
.site-title:hover { text-decoration: none; color: var(--accent); }
|
|
2265
|
+
/* ---- 案件アイコン(#348)----
|
|
2266
|
+
**ヘッダーの案件名の左に丸を置く。** ヘッダーは全タブ共通なので、
|
|
2267
|
+
どのタブを開いていても同じ場所に居る。0.12.24 で Home 本文に置いた
|
|
2268
|
+
「大きな枠+その下のボタン」はオーナー実機で却下された(本文の先頭が重くなった)。
|
|
2269
|
+
|
|
2270
|
+
見た目はポータルの一覧カード(portal の ProjectIcon.tsx)に寄せる:
|
|
2271
|
+
丸・cover・未設定は薄い青地に案件名の頭文字1字。同じ画像が2つの画面で
|
|
2272
|
+
別の切れ方をすると「設定したのと違う絵が出ている」と読まれる */
|
|
2273
|
+
.site-icon-slot { position: relative; flex: 0 0 auto; display: flex; align-items: center; }
|
|
2274
|
+
.site-icon {
|
|
2275
|
+
position: relative;
|
|
2276
|
+
width: 28px; height: 28px; border-radius: 50%; overflow: hidden;
|
|
2277
|
+
display: flex; align-items: center; justify-content: center;
|
|
2278
|
+
padding: 0; border: 0; background: var(--accent-weak); color: var(--accent);
|
|
2279
|
+
font-size: 13px; font-weight: 600; line-height: 1;
|
|
2280
|
+
}
|
|
2281
|
+
.site-icon-initial {
|
|
2282
|
+
display: flex; align-items: center; justify-content: center;
|
|
2283
|
+
width: 100%; height: 100%;
|
|
2284
|
+
}
|
|
2285
|
+
/* **押せる丸の頭文字だけ薄くして、上に「+」を重ねる。**
|
|
2286
|
+
頭文字だけだと「設定済みの何か」に見え、置ける場所だと分からない
|
|
2287
|
+
——薄い字の上の「+」で「ここに画像を置ける」を一目にする。
|
|
2288
|
+
受け口が無い案件(span.site-icon)は置けないので、薄くも「+」も付けない */
|
|
2289
|
+
button.site-icon .site-icon-initial { opacity: .45; }
|
|
2290
|
+
.site-icon-plus {
|
|
2291
|
+
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
|
2292
|
+
display: flex; align-items: center; justify-content: center;
|
|
2293
|
+
color: var(--accent); font-size: 16px; font-weight: 700; line-height: 1;
|
|
2294
|
+
}
|
|
2295
|
+
/* 設定済みの丸は画像だけ。**押せることはホバーで出す**——常時ラベルを重ねると
|
|
2296
|
+
選んだロゴが読めなくなる(アイコンを設定した意味が薄れる) */
|
|
2297
|
+
.site-icon-hover {
|
|
2298
|
+
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
|
|
2299
|
+
display: flex; align-items: center; justify-content: center;
|
|
2300
|
+
background: rgba(0, 0, 0, 0.55); color: #fff;
|
|
2301
|
+
font-size: 11px; font-weight: 600; line-height: 1;
|
|
2302
|
+
opacity: 0; transition: opacity 0.12s ease;
|
|
2303
|
+
}
|
|
2304
|
+
button.site-icon:hover .site-icon-hover,
|
|
2305
|
+
button.site-icon[aria-expanded="true"] .site-icon-hover { opacity: 1; }
|
|
2306
|
+
/* **押せることはホバーで示す。** 受け口が無い案件の丸は span なので、この効果は付かない
|
|
2307
|
+
——押せない丸に指差しカーソルやリングを出すのが、画面の嘘のうちで一番たちが悪い */
|
|
2308
|
+
button.site-icon { cursor: pointer; }
|
|
2309
|
+
button.site-icon:hover, button.site-icon[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--accent); }
|
|
2310
|
+
.site-icon-img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
2311
|
+
/* 丸を押したときだけ出るメニュー。スロットを基準に浮かせる(ヘッダーは sticky なので
|
|
2312
|
+
ページを送っても位置がずれない) */
|
|
2313
|
+
.site-icon-menu {
|
|
2314
|
+
position: absolute; top: 36px; left: 0; z-index: 30; min-width: 220px;
|
|
2315
|
+
background: #fff; border: 1px solid var(--border); border-radius: 10px;
|
|
2316
|
+
box-shadow: 0 8px 24px rgba(0,0,0,.12); padding: 8px;
|
|
2317
|
+
display: flex; flex-direction: column; gap: 6px;
|
|
2318
|
+
}
|
|
2319
|
+
.site-icon-menu[hidden] { display: none; }
|
|
2320
|
+
.site-icon-menu button {
|
|
2321
|
+
text-align: left; padding: 8px 10px; border-radius: 8px;
|
|
2322
|
+
border: 1px solid var(--border); background: #fff; font-size: 13px; cursor: pointer;
|
|
2323
|
+
}
|
|
2324
|
+
.site-icon-menu button:hover { background: #f3f6fb; }
|
|
2325
|
+
.site-icon-menu button:disabled { opacity: .6; cursor: default; }
|
|
2326
|
+
/* 結果の行はメニューの中に置く(丸の横に出すとヘッダーの高さに押し込まれて読めない) */
|
|
2327
|
+
.site-icon-status { font-size: 12.5px; padding: 2px 4px; }
|
|
2328
|
+
.site-icon-status:empty { display: none; }
|
|
2329
|
+
.site-icon-status-error { color: #b91c1c; }
|
|
2264
2330
|
.record-count { color: var(--muted); font-size: 13px; }
|
|
2265
2331
|
.ask-ai-btn {
|
|
2266
2332
|
margin-left: auto; flex: 0 0 auto;
|
|
@@ -2495,30 +2561,6 @@ a:hover { text-decoration: underline; }
|
|
|
2495
2561
|
padding-bottom: 6px; border-bottom: 1px solid var(--border);
|
|
2496
2562
|
}
|
|
2497
2563
|
.home-grounding > .home-grounding-title:first-child { margin-top: 0; }
|
|
2498
|
-
/* ---- 案件アイコン(#348)----
|
|
2499
|
-
Home のタイトルの左に丸い枠を置く。ポータルの一覧カード(ProjectIcon.tsx)と
|
|
2500
|
-
同じ「丸・cover」にする——同じ画像が2つの画面で別の切れ方をすると、
|
|
2501
|
-
「設定したのと違う絵が出ている」と読まれる */
|
|
2502
|
-
.home-head { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
|
|
2503
|
-
.home-title-wrap { flex: 1 1 320px; min-width: 0; }
|
|
2504
|
-
.project-icon { flex: 0 0 auto; }
|
|
2505
|
-
/* 未設定は破線(置き場が空いていることを見せる)・設定済みは実線 */
|
|
2506
|
-
.project-icon-frame {
|
|
2507
|
-
width: 72px; height: 72px; border-radius: 50%; overflow: hidden;
|
|
2508
|
-
border: 2px dashed var(--border); background: #f6f7f9;
|
|
2509
|
-
display: flex; align-items: center; justify-content: center;
|
|
2510
|
-
padding: 0; cursor: pointer;
|
|
2511
|
-
}
|
|
2512
|
-
.project-icon-frame.project-icon-filled { border-style: solid; }
|
|
2513
|
-
/* 受け口が無い案件では押せないので、押せる見た目にしない */
|
|
2514
|
-
.project-icon-frame:not(button) { cursor: default; }
|
|
2515
|
-
.project-icon-img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
2516
|
-
.project-icon-empty { font-size: 11px; color: var(--muted); text-align: center; line-height: 1.3; }
|
|
2517
|
-
.project-icon-actions { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
|
|
2518
|
-
/* 結果の行はタイトルの下へ回す(枠の横に入れると72pxの高さに押し込まれる) */
|
|
2519
|
-
.project-icon-status { flex-basis: 100%; font-size: 13px; }
|
|
2520
|
-
.project-icon-status:empty { display: none; }
|
|
2521
|
-
.project-icon-status-error { color: #b91c1c; }
|
|
2522
2564
|
/* ---- レコード詳細の「AIによる最近の変更」(リポジトリの git 履歴 由来)----
|
|
2523
2565
|
カードは詳細ページの提案(.proposals)と同系色にする——どちらも
|
|
2524
2566
|
「AIがやったこと・言っていることを読む」もので種類が同じ。
|
|
@@ -4329,10 +4371,14 @@ ${deriveCapTile.toString()}
|
|
|
4329
4371
|
// ---------- 案件アイコン(#348) ----------
|
|
4330
4372
|
//
|
|
4331
4373
|
// ポータルの案件一覧はカードにアイコンを出す。置き場はこの案件のリポジトリの
|
|
4332
|
-
// Cortex/icon.<ext>
|
|
4374
|
+
// Cortex/icon.<ext> で、**設定する口はこのビューアにしかない**——ポータル側に
|
|
4333
4375
|
// 置くと「誰の案件か」の判定を先に作らねばならず、案件を知っている人が
|
|
4334
4376
|
// その場で直せる形にならない。
|
|
4335
4377
|
//
|
|
4378
|
+
// **出す場所はヘッダーの案件名の左**(0.12.24 の Home 本文から移した・#348)。
|
|
4379
|
+
// ヘッダーは全タブ共通なので、どのタブを開いていても同じ場所に居る。
|
|
4380
|
+
// 押せる口はメニューの中に畳む——常時見えるボタンは、たまにしか使わない操作には重い。
|
|
4381
|
+
//
|
|
4336
4382
|
// 保存はビルドを待たずに画面へ反映する(mirror)。恒久化は次のビルドで
|
|
4337
4383
|
// site-data ごと焼き直されるので、mirror はこのタブが開いているあいだだけ。
|
|
4338
4384
|
// 上限はサーバ側(logic.mjs の PROJECT_ICON_MAX_BYTES)と同じ値。画面の門は
|
|
@@ -4373,83 +4419,158 @@ ${deriveCapTile.toString()}
|
|
|
4373
4419
|
return req.then(function (r) { return r.json().then(function (j) { return { ok: r.ok, j: j }; }); });
|
|
4374
4420
|
}
|
|
4375
4421
|
|
|
4422
|
+
// ヘッダーの丸のメニューが開いているか。**DOM ではなくこの変数が正本。**
|
|
4423
|
+
// 保存・解除のあとに丸を描き直すので、開閉を DOM だけに持たせると描き直しで畳まれ、
|
|
4424
|
+
// 「✓ 保存しました」と保存先のリンクが一度も見えないまま消える
|
|
4425
|
+
var siteIconMenuOpen = false;
|
|
4426
|
+
// document に付ける開閉のリスナーは1組だけ。描き直しのたびに足すと Escape 1回で
|
|
4427
|
+
// 同じ処理が何度も走る(見た目は同じなので気づけない)
|
|
4428
|
+
var siteIconGlobalBound = false;
|
|
4429
|
+
|
|
4430
|
+
/**
|
|
4431
|
+
* 案件名の頭文字1字。**ポータルの ProjectIcon.tsx(initialOf)と同じ取り方**にする
|
|
4432
|
+
* ——同じ案件がポータルとビューアで違う字になると「別の案件を見ている」と読まれる。
|
|
4433
|
+
*
|
|
4434
|
+
* ⚠ title[0] にしない。サロゲートペア(絵文字・一部の漢字)が半分に割れて化ける
|
|
4435
|
+
*/
|
|
4436
|
+
function siteInitial() {
|
|
4437
|
+
return Array.from(String(SITE.title || "").trim())[0] || "?";
|
|
4438
|
+
}
|
|
4439
|
+
|
|
4440
|
+
/** 丸の中の頭文字(薄くするかどうかは CSS が丸の種類で決める) */
|
|
4441
|
+
function siteIconInitialEl() {
|
|
4442
|
+
return el("span", { class: "site-icon-initial", text: siteInitial() });
|
|
4443
|
+
}
|
|
4444
|
+
|
|
4445
|
+
/** メニューの開閉。描き直さずに hidden と aria-expanded だけ動かす */
|
|
4446
|
+
function setSiteIconMenu(open) {
|
|
4447
|
+
siteIconMenuOpen = !!open;
|
|
4448
|
+
var slot = document.getElementById("site-icon-slot");
|
|
4449
|
+
if (!slot) return;
|
|
4450
|
+
var menu = slot.querySelector(".site-icon-menu");
|
|
4451
|
+
if (menu) {
|
|
4452
|
+
if (siteIconMenuOpen) menu.removeAttribute("hidden");
|
|
4453
|
+
else menu.setAttribute("hidden", "");
|
|
4454
|
+
}
|
|
4455
|
+
var circle = slot.querySelector("button.site-icon");
|
|
4456
|
+
if (circle) circle.setAttribute("aria-expanded", siteIconMenuOpen ? "true" : "false");
|
|
4457
|
+
}
|
|
4458
|
+
|
|
4376
4459
|
/**
|
|
4377
|
-
*
|
|
4460
|
+
* ヘッダーの案件名の左の丸を描く(#site-icon-slot の中身を作り直す)。
|
|
4378
4461
|
*
|
|
4379
|
-
*
|
|
4380
|
-
|
|
4381
|
-
*
|
|
4462
|
+
* **丸は常に出す**(未設定なら頭文字)——ポータルの一覧と同じ顔をここでも見せる。
|
|
4463
|
+
* **押せる形にするのは受け口(intake)がある案件だけ。** 無ければ span にして
|
|
4464
|
+
* メニューもファイル選択も付けない——押して何も起きない口は「壊れている」と読まれる。
|
|
4382
4465
|
*
|
|
4383
|
-
* @param status
|
|
4466
|
+
* @param status 前の描画から引き継ぐ結果の行(省略時は新しく作る)
|
|
4384
4467
|
*/
|
|
4385
|
-
function
|
|
4468
|
+
function renderSiteIcon(status) {
|
|
4469
|
+
var slot = document.getElementById("site-icon-slot");
|
|
4470
|
+
if (!slot) return;
|
|
4386
4471
|
var intake = SITE.intake;
|
|
4387
4472
|
var cur = projectIconCurrent();
|
|
4388
|
-
|
|
4473
|
+
slot.textContent = "";
|
|
4389
4474
|
|
|
4390
|
-
var
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
var
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
}
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
};
|
|
4405
|
-
|
|
4406
|
-
// **受け口が無ければ button にしない。** 押せる形(フォーカスが当たる・指差しの
|
|
4407
|
-
// カーソルが出る)で何も起きないのが、画面の嘘のうちで一番たちが悪い
|
|
4408
|
-
var frame = el(intake ? "button" : "div", {
|
|
4409
|
-
class: "project-icon-frame" + (cur ? " project-icon-filled" : ""),
|
|
4410
|
-
"aria-label": "案件アイコン",
|
|
4411
|
-
});
|
|
4412
|
-
if (intake) frame.setAttribute("type", "button");
|
|
4475
|
+
var circle = el(intake ? "button" : "span", { class: "site-icon" });
|
|
4476
|
+
if (intake) {
|
|
4477
|
+
circle.setAttribute("type", "button");
|
|
4478
|
+
circle.setAttribute("aria-haspopup", "menu");
|
|
4479
|
+
circle.setAttribute("aria-expanded", siteIconMenuOpen ? "true" : "false");
|
|
4480
|
+
// 未設定は「+」が見えているので、説明は「変更」ではなく置ける話にしない——
|
|
4481
|
+
// 読み上げと tooltip は、いまの状態でできることをそのまま言う
|
|
4482
|
+
var label = cur ? "案件アイコンを変更/外す" : "案件アイコンを設定";
|
|
4483
|
+
circle.setAttribute("title", label);
|
|
4484
|
+
circle.setAttribute("aria-label", label);
|
|
4485
|
+
} else {
|
|
4486
|
+
// すぐ隣に案件名が文字で出ているので、読み上げで名前を2回言わせない
|
|
4487
|
+
circle.setAttribute("aria-hidden", "true");
|
|
4488
|
+
}
|
|
4413
4489
|
if (cur) {
|
|
4414
|
-
|
|
4490
|
+
// **設定済みは画像だけ。** 頭文字も「+」も重ねない(選んだロゴが読めなくなる)
|
|
4491
|
+
var img = el("img", { class: "site-icon-img", src: cur.src, alt: "" });
|
|
4415
4492
|
// **onerror 属性で書かない(CSP でインラインハンドラは動かない)。**
|
|
4416
|
-
// blob: が配信先の img-src
|
|
4493
|
+
// blob: が配信先の img-src で拒まれることがあるので、そのときは頭文字に倒す
|
|
4417
4494
|
img.addEventListener("error", function () {
|
|
4418
|
-
if (
|
|
4419
|
-
img.parentNode.replaceChild(el("span", { class: "project-icon-empty", text: "保存済み" }), img);
|
|
4495
|
+
if (img.parentNode) img.parentNode.replaceChild(siteIconInitialEl(), img);
|
|
4420
4496
|
});
|
|
4421
|
-
|
|
4497
|
+
circle.appendChild(img);
|
|
4498
|
+
// 押せる案件だけ、ホバーで「変更」と出す(見た目は CSS の opacity で切り替える)
|
|
4499
|
+
if (intake) circle.appendChild(el("span", { class: "site-icon-hover", "aria-hidden": "true", text: "変更" }));
|
|
4422
4500
|
} else {
|
|
4423
|
-
|
|
4501
|
+
circle.appendChild(siteIconInitialEl());
|
|
4502
|
+
// **未設定の押せる丸には「+」を重ねる。** 薄い頭文字だけだと
|
|
4503
|
+
// 「設定済みの何か」に見えて、置ける場所だと分からない
|
|
4504
|
+
if (intake) circle.appendChild(el("span", { class: "site-icon-plus", "aria-hidden": "true", text: "+" }));
|
|
4424
4505
|
}
|
|
4425
|
-
|
|
4506
|
+
slot.appendChild(circle);
|
|
4507
|
+
if (!intake) return;
|
|
4426
4508
|
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4509
|
+
circle.addEventListener("click", function () { setSiteIconMenu(!siteIconMenuOpen); });
|
|
4510
|
+
|
|
4511
|
+
// **status の要素は描き直しをまたいで持ち回る。** 描き直したあとに
|
|
4512
|
+
// 「✓ 保存しました」と保存先のリンクを足すので、入れ替わると書いた先が画面から外れる
|
|
4513
|
+
var st = status || el("div", { class: "site-icon-status", "aria-live": "polite" });
|
|
4514
|
+
var menu = el("div", { class: "site-icon-menu", role: "menu" });
|
|
4515
|
+
if (!siteIconMenuOpen) menu.setAttribute("hidden", "");
|
|
4516
|
+
|
|
4517
|
+
function setStatus(msg, isError) {
|
|
4518
|
+
st.className = "site-icon-status" + (isError ? " site-icon-status-error" : "");
|
|
4519
|
+
st.textContent = msg || "";
|
|
4520
|
+
}
|
|
4521
|
+
var ui = {
|
|
4522
|
+
status: st,
|
|
4523
|
+
setStatus: setStatus,
|
|
4524
|
+
// 描き直すと押していたボタンが DOM から消えてフォーカスが body に落ちるので、
|
|
4525
|
+
// 丸へ戻す(キーボードの人が位置を失わない。Escape は document 側なので効く)
|
|
4526
|
+
redraw: function () {
|
|
4527
|
+
renderSiteIcon(st);
|
|
4528
|
+
var s = document.getElementById("site-icon-slot");
|
|
4529
|
+
var c = s && s.querySelector("button.site-icon");
|
|
4530
|
+
if (c && typeof c.focus === "function") c.focus();
|
|
4531
|
+
},
|
|
4532
|
+
input: null,
|
|
4533
|
+
buttons: [],
|
|
4534
|
+
};
|
|
4535
|
+
ui.disable = function (flag) { ui.buttons.forEach(function (b) { b.disabled = !!flag; }); };
|
|
4536
|
+
|
|
4537
|
+
var input = el("input", { type: "file", accept: "image/png,image/jpeg,image/webp", hidden: "" });
|
|
4538
|
+
ui.input = input;
|
|
4539
|
+
input.addEventListener("change", function () {
|
|
4540
|
+
var f = input.files && input.files[0];
|
|
4541
|
+
// **読んだらすぐ value を戻す**(成功時だけ戻す形だと、形式で断られた直後に
|
|
4542
|
+
// 同じファイルを選び直しても change が飛ばず、直す経路がここで死ぬ)
|
|
4543
|
+
try { input.value = ""; } catch (e) {}
|
|
4544
|
+
if (f) setProjectIcon(f, ui);
|
|
4545
|
+
});
|
|
4546
|
+
var choose = el("button", { class: "site-icon-choose", type: "button", role: "menuitem", text: cur ? "画像を変える" : "画像を選ぶ" });
|
|
4547
|
+
choose.addEventListener("click", function () { input.click(); });
|
|
4548
|
+
ui.buttons.push(choose);
|
|
4549
|
+
menu.appendChild(choose);
|
|
4550
|
+
if (cur) {
|
|
4551
|
+
var remove = el("button", { class: "site-icon-remove", type: "button", role: "menuitem", text: "画像を外す" });
|
|
4552
|
+
remove.addEventListener("click", function () { removeProjectIcon(ui); });
|
|
4553
|
+
ui.buttons.push(remove);
|
|
4554
|
+
menu.appendChild(remove);
|
|
4555
|
+
}
|
|
4556
|
+
menu.appendChild(input);
|
|
4557
|
+
menu.appendChild(st);
|
|
4558
|
+
slot.appendChild(menu);
|
|
4559
|
+
|
|
4560
|
+
if (!siteIconGlobalBound) {
|
|
4561
|
+
siteIconGlobalBound = true;
|
|
4562
|
+
// 外を押したら閉じる。**スロットの中では閉じない**——「画像を選ぶ」を押した
|
|
4563
|
+
// 瞬間に畳まれると、選び終えたときに結果を書く場所が無い
|
|
4564
|
+
document.addEventListener("click", function (ev) {
|
|
4565
|
+
if (!siteIconMenuOpen) return;
|
|
4566
|
+
var s = document.getElementById("site-icon-slot");
|
|
4567
|
+
if (s && s.contains(ev.target)) return;
|
|
4568
|
+
setSiteIconMenu(false);
|
|
4569
|
+
});
|
|
4570
|
+
document.addEventListener("keydown", function (ev) {
|
|
4571
|
+
if (siteIconMenuOpen && (ev.key === "Escape" || ev.key === "Esc")) setSiteIconMenu(false);
|
|
4436
4572
|
});
|
|
4437
|
-
var choose = el("button", { class: "project-icon-choose", type: "button", text: cur ? "画像を変える" : "画像を選ぶ" });
|
|
4438
|
-
choose.addEventListener("click", function () { input.click(); });
|
|
4439
|
-
// 枠を押すのも「選ぶ」と同じ(丸を押したくなるので、押せる場所を分けない)
|
|
4440
|
-
frame.addEventListener("click", function () { input.click(); });
|
|
4441
|
-
ui.buttons.push(choose, frame);
|
|
4442
|
-
var actions = el("div", { class: "project-icon-actions" }, [choose]);
|
|
4443
|
-
if (cur) {
|
|
4444
|
-
var remove = el("button", { class: "project-icon-remove", type: "button", text: "画像を外す" });
|
|
4445
|
-
remove.addEventListener("click", function () { removeProjectIcon(ui); });
|
|
4446
|
-
ui.buttons.push(remove);
|
|
4447
|
-
actions.appendChild(remove);
|
|
4448
|
-
}
|
|
4449
|
-
actions.appendChild(input);
|
|
4450
|
-
box.appendChild(actions);
|
|
4451
4573
|
}
|
|
4452
|
-
return box;
|
|
4453
4574
|
}
|
|
4454
4575
|
|
|
4455
4576
|
/** 保存先(GitHub)の1行。submitIntake の modal-paths と同じ組み立て */
|
|
@@ -4552,18 +4673,12 @@ ${deriveCapTile.toString()}
|
|
|
4552
4673
|
text: "最終更新: " + SITE.homeUpdatedAt,
|
|
4553
4674
|
}));
|
|
4554
4675
|
}
|
|
4555
|
-
var titleWrap = el("div", {
|
|
4676
|
+
var titleWrap = el("div", {}, [ titleEl ]);
|
|
4556
4677
|
var ai = h.fm ? adoptionInfo(h.fm.adoption) : null;
|
|
4557
4678
|
if (ai) titleWrap.appendChild(el("span", { class: "chip adoption-" + String(h.fm.adoption), text: ai.label }));
|
|
4558
|
-
// 案件アイコン(#348
|
|
4559
|
-
//
|
|
4560
|
-
|
|
4561
|
-
var iconStatus = el("div", { class: "project-icon-status", "aria-live": "polite" });
|
|
4562
|
-
var iconBox = renderProjectIcon(iconStatus);
|
|
4563
|
-
if (iconBox) homeHead.appendChild(iconBox);
|
|
4564
|
-
homeHead.appendChild(titleWrap);
|
|
4565
|
-
if (iconBox) homeHead.appendChild(iconStatus);
|
|
4566
|
-
head.appendChild(homeHead);
|
|
4679
|
+
// 案件アイコン(#348)はここには置かない。**ヘッダーの案件名の左**にある
|
|
4680
|
+
// (renderSiteIcon)——全タブから同じ場所で触れる形にした
|
|
4681
|
+
head.appendChild(titleWrap);
|
|
4567
4682
|
var homeEditRow = el("div", { class: "detail-actions-row" }, [
|
|
4568
4683
|
el("a", { class: "ai-edit-btn", href: codeUrl(HOME_EDIT_PROMPT), target: "_blank", rel: "noopener", text: "AIで編集" }),
|
|
4569
4684
|
]);
|
|
@@ -14367,6 +14482,10 @@ ${deriveCapTile.toString()}
|
|
|
14367
14482
|
}
|
|
14368
14483
|
|
|
14369
14484
|
window.addEventListener("popstate", route);
|
|
14485
|
+
// ヘッダーの案件アイコン(#348)は #app の外なので、**起動時に1回だけ描く**。
|
|
14486
|
+
// route() はタブを替えるたびに走るが、ヘッダーは描き替えない——描き直すと
|
|
14487
|
+
// 保存直後の mirror とメニューの開閉が、タブを移るたびに畳まれる
|
|
14488
|
+
renderSiteIcon();
|
|
14370
14489
|
route();
|
|
14371
14490
|
/**
|
|
14372
14491
|
* 接続状況の先読み(#264)。**開いたタブに関係なく、起動時に1回だけ取りに行く。**
|
package/package.json
CHANGED