@takagaki/cortex-decisions-viewer 0.10.0 → 0.10.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/render.js +164 -3
- package/package.json +1 -1
package/dist/render.js
CHANGED
|
@@ -15,6 +15,7 @@ exports.materialRowsToAdd = materialRowsToAdd;
|
|
|
15
15
|
exports.issueRowsToAdd = issueRowsToAdd;
|
|
16
16
|
exports.unsettledRegisteredCount = unsettledRegisteredCount;
|
|
17
17
|
exports.registeredRowsToAdd = registeredRowsToAdd;
|
|
18
|
+
exports.subtractRemovedRegistered = subtractRemovedRegistered;
|
|
18
19
|
exports.mergeRegisteredFleet = mergeRegisteredFleet;
|
|
19
20
|
exports.nextStateDelay = nextStateDelay;
|
|
20
21
|
exports.renderConnectionMap = renderConnectionMap;
|
|
@@ -769,9 +770,140 @@ function registeredRowsToAdd(view, reg) {
|
|
|
769
770
|
};
|
|
770
771
|
}
|
|
771
772
|
/**
|
|
772
|
-
*
|
|
773
|
+
* 登録ファイルから**消された**行を、まとめ表の写しから引く(段A補・2026-08-22)。
|
|
773
774
|
*
|
|
774
|
-
*
|
|
775
|
+
* 「解除しました」と出るのに、リロードすると数分間残る——追加は足していたのに、
|
|
776
|
+
* 削除はまとめ表の作り直し待ちだった。登録ファイルは今の正本なので、
|
|
777
|
+
* そこに無い行は消されたということ。
|
|
778
|
+
*
|
|
779
|
+
* 🔴 **能力のキーが在るときだけ引く。** キーが無い=登録ファイルが読めなかった、なので
|
|
780
|
+
* 引くと「読めない」が「全部消えた」に化ける。
|
|
781
|
+
* 🔴 **チャットは origin が "derived" の行だけ。** dev-sources.json 側にも宣言された行
|
|
782
|
+
* (explicit / both)は channels.json から消してもエンジンがまだ読む——隠すと
|
|
783
|
+
* 「読まれているのに画面に無い」という逆向きの嘘になる。
|
|
784
|
+
* 🔴 **チャットの突き合わせは ref だけ(追加側と非対称にしてある)。** まとめ表の
|
|
785
|
+
* workspace はエンジンが実測で埋めることがあり、宣言(登録ファイル)側と食い違う。
|
|
786
|
+
* ID+WSで引くと、実測で埋まった行を**誤って隠す**。ref 一致の登録が1つでも残って
|
|
787
|
+
* いれば引かない——引き損ね(数分の遅れ)は安全側、誤削除は嘘なので。
|
|
788
|
+
*/
|
|
789
|
+
function subtractRemovedRegistered(view, reg) {
|
|
790
|
+
const v = view || {};
|
|
791
|
+
if (!reg)
|
|
792
|
+
return v;
|
|
793
|
+
let out = v;
|
|
794
|
+
const set = (patch) => { out = out === v ? Object.assign({}, v, patch) : Object.assign(out, patch); };
|
|
795
|
+
if (Array.isArray(reg.chat) || Array.isArray(reg.dev)) {
|
|
796
|
+
const chatRefs = {};
|
|
797
|
+
for (const r of reg.chat || [])
|
|
798
|
+
if (r && r.ref)
|
|
799
|
+
chatRefs[String(r.ref)] = true;
|
|
800
|
+
const devRefs = {};
|
|
801
|
+
for (const r of reg.dev || [])
|
|
802
|
+
if (r && r.ref)
|
|
803
|
+
devRefs[String(r.ref)] = true;
|
|
804
|
+
const before = v.externalSources || [];
|
|
805
|
+
const after = before.filter((s) => {
|
|
806
|
+
if (!s || !s.ref)
|
|
807
|
+
return true;
|
|
808
|
+
if (s.type === "slack" && Array.isArray(reg.chat)) {
|
|
809
|
+
if (s.origin !== "derived")
|
|
810
|
+
return true;
|
|
811
|
+
return chatRefs[String(s.ref)] === true;
|
|
812
|
+
}
|
|
813
|
+
if (String(s.type || "").indexOf("github") === 0 && Array.isArray(reg.dev)) {
|
|
814
|
+
// 「読み取り停止中」(exclude)の行は登録簿の sources に居ないが、
|
|
815
|
+
// まとめ表はバッジを出すために保持している——引くと停止中の表示ごと消える
|
|
816
|
+
if (s.goldState === "excluded")
|
|
817
|
+
return true;
|
|
818
|
+
return devRefs[String(s.ref)] === true;
|
|
819
|
+
}
|
|
820
|
+
return true;
|
|
821
|
+
});
|
|
822
|
+
if (after.length !== before.length)
|
|
823
|
+
set({ externalSources: after });
|
|
824
|
+
}
|
|
825
|
+
if (Array.isArray(reg.design) || Array.isArray(reg.materials)) {
|
|
826
|
+
const internals = ((out.internalSources || v.internalSources) || []).slice();
|
|
827
|
+
let changed = false;
|
|
828
|
+
if (Array.isArray(reg.design)) {
|
|
829
|
+
const keys = {};
|
|
830
|
+
for (const r of reg.design)
|
|
831
|
+
if (r && r.key)
|
|
832
|
+
keys[String(r.key)] = true;
|
|
833
|
+
for (let i = 0; i < internals.length; i++) {
|
|
834
|
+
const it = internals[i];
|
|
835
|
+
if (!it || it.kind !== REGISTERED_CAP_NAMES.design || !Array.isArray(it.figmaFiles))
|
|
836
|
+
continue;
|
|
837
|
+
const files = it.figmaFiles.filter((f) => f && keys[String(f.key)] === true);
|
|
838
|
+
if (files.length !== it.figmaFiles.length) {
|
|
839
|
+
internals[i] = Object.assign({}, it, { figmaFiles: files });
|
|
840
|
+
changed = true;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
if (Array.isArray(reg.materials)) {
|
|
845
|
+
const ids = {};
|
|
846
|
+
for (const r of reg.materials)
|
|
847
|
+
if (r && r.id)
|
|
848
|
+
ids[String(r.id)] = true;
|
|
849
|
+
for (let i = 0; i < internals.length; i++) {
|
|
850
|
+
const it = internals[i];
|
|
851
|
+
if (!it || it.kind !== REGISTERED_CAP_NAMES.materials || !Array.isArray(it.driveFolderIds))
|
|
852
|
+
continue;
|
|
853
|
+
const kept = it.driveFolderIds.filter((id) => ids[String(id)] === true);
|
|
854
|
+
if (kept.length !== it.driveFolderIds.length) {
|
|
855
|
+
const names = {};
|
|
856
|
+
for (const id of kept)
|
|
857
|
+
if (it.driveFolderNames && it.driveFolderNames[id])
|
|
858
|
+
names[id] = it.driveFolderNames[id];
|
|
859
|
+
const patch = { driveFolderIds: kept, driveFolderNames: names };
|
|
860
|
+
// 0件になったら empty に倒す(正本が0件と言っている)。倒さないと
|
|
861
|
+
// 一覧が**無言で空**になり「まだ登録されていません」も出ない。
|
|
862
|
+
// **倒すのは on のときだけ**——broken(設定が読めない)/ off(意図的な停止)は
|
|
863
|
+
// 別の答えなので潰さない
|
|
864
|
+
if (!kept.length && it.driveState === "on")
|
|
865
|
+
patch.driveState = "empty";
|
|
866
|
+
internals[i] = Object.assign({}, it, patch);
|
|
867
|
+
changed = true;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
if (changed)
|
|
872
|
+
set({ internalSources: internals });
|
|
873
|
+
}
|
|
874
|
+
if (Array.isArray(reg.issues)) {
|
|
875
|
+
// 鍵の畳み方は足す側(issueRowsToAdd)と同じにする——別の畳み方にすると
|
|
876
|
+
// 大小の違いで「引いた直後に別綴りで足し直される」形になる
|
|
877
|
+
const issueKey = (t) => String(t.domain).toLowerCase() + "/" + String(t.projectKey).toUpperCase();
|
|
878
|
+
const keys = {};
|
|
879
|
+
for (const r of reg.issues)
|
|
880
|
+
if (r)
|
|
881
|
+
keys[issueKey(r)] = true;
|
|
882
|
+
const bt = (out.backlogTarget || v.backlogTarget);
|
|
883
|
+
const cur = bt && Array.isArray(bt.targets) ? bt.targets : bt && bt.domain && bt.projectKey ? [bt] : [];
|
|
884
|
+
const kept = cur.filter((t) => t && keys[issueKey(t)] === true);
|
|
885
|
+
if (kept.length !== cur.length) {
|
|
886
|
+
const patch = Object.assign({}, bt || {}, { targets: kept });
|
|
887
|
+
// 単数の2つは先頭の接続先。0件なら欄ごと消す(「無い」を装った値で残さない)
|
|
888
|
+
if (kept.length) {
|
|
889
|
+
patch.domain = kept[0].domain;
|
|
890
|
+
patch.projectKey = kept[0].projectKey;
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
delete patch.domain;
|
|
894
|
+
delete patch.projectKey;
|
|
895
|
+
}
|
|
896
|
+
set({ backlogTarget: patch });
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
return out;
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* まとめ表の3キー(externalSources / internalSources / backlogTarget)を、登録ファイルの
|
|
903
|
+
* 今の姿に合わせる——**消された行を引いてから、足りない行を足す**(段A補)。
|
|
904
|
+
*
|
|
905
|
+
* 引き算の条件と守りは subtractRemovedRegistered が持つ。既存の行の**欄**は書き換えない
|
|
906
|
+
* (状態・origin・名前はまとめ表のまま)。
|
|
775
907
|
*
|
|
776
908
|
* ⚠ 同期ソースの行がまだ無い能力(=夜間バッチが一度も走っていない案件)には、
|
|
777
909
|
* **その能力の行を作る**——作らないと、登録した Figma ファイル・Drive フォルダを
|
|
@@ -781,7 +913,8 @@ function registeredRowsToAdd(view, reg) {
|
|
|
781
913
|
* (まとめ表が持っている値は上書きしない)。
|
|
782
914
|
*/
|
|
783
915
|
function mergeRegisteredFleet(view, reg) {
|
|
784
|
-
|
|
916
|
+
// 先に「消された行」を引き、そのうえで「足りない行」を足す(登録ファイルが今の正本)
|
|
917
|
+
const v = subtractRemovedRegistered(view || {}, reg);
|
|
785
918
|
const out = {
|
|
786
919
|
externalSources: v.externalSources,
|
|
787
920
|
internalSources: v.internalSources,
|
|
@@ -2184,6 +2317,7 @@ ${designRowsToAdd.toString()}
|
|
|
2184
2317
|
${materialRowsToAdd.toString()}
|
|
2185
2318
|
${issueRowsToAdd.toString()}
|
|
2186
2319
|
${internalOf.toString()}
|
|
2320
|
+
${subtractRemovedRegistered.toString()}
|
|
2187
2321
|
${registeredRowsToAdd.toString()}
|
|
2188
2322
|
${unsettledRegisteredCount.toString()}
|
|
2189
2323
|
${mergeRegisteredFleet.toString()}
|
|
@@ -3662,6 +3796,29 @@ ${nextStateDelay.toString()}
|
|
|
3662
3796
|
if (add.design.length) out[REGISTERED_CAP_NAMES.design] = 1;
|
|
3663
3797
|
if (add.materials.length) out[REGISTERED_CAP_NAMES.materials] = 1;
|
|
3664
3798
|
if (add.issues.length) out[REGISTERED_CAP_NAMES.issues] = 1;
|
|
3799
|
+
// **引き算で0件になった能力も同じ語に倒す(段A補)。** 夜間の capabilities は
|
|
3800
|
+
// まだ「on」なので、そのまま出すとタイルは「接続OK」・一覧は0件という矛盾になる。
|
|
3801
|
+
// 「未接続」と言い切るのは夜間が追いついてから(capabilities は引き算の対象外)
|
|
3802
|
+
var raw = rawView();
|
|
3803
|
+
var sub = subtractRemovedRegistered(raw, LIVE_REGISTERED);
|
|
3804
|
+
var count = function (list, isType) {
|
|
3805
|
+
var n = 0;
|
|
3806
|
+
for (var j = 0; j < (list || []).length; j++) if (list[j] && isType(list[j])) n++;
|
|
3807
|
+
return n;
|
|
3808
|
+
};
|
|
3809
|
+
var isSlack = function (x) { return x.type === "slack"; };
|
|
3810
|
+
var isGh = function (x) { return String(x.type || "").indexOf("github") === 0; };
|
|
3811
|
+
if (count(raw.externalSources, isSlack) > 0 && count(sub.externalSources, isSlack) === 0) out["チャット"] = 1;
|
|
3812
|
+
if (count(raw.externalSources, isGh) > 0 && count(sub.externalSources, isGh) === 0) out["開発"] = 1;
|
|
3813
|
+
var dRaw = internalOf(raw.internalSources || [], REGISTERED_CAP_NAMES.design);
|
|
3814
|
+
var dSub = internalOf(sub.internalSources || [], REGISTERED_CAP_NAMES.design);
|
|
3815
|
+
if (dRaw && (dRaw.figmaFiles || []).length > 0 && dSub && (dSub.figmaFiles || []).length === 0) out[REGISTERED_CAP_NAMES.design] = 1;
|
|
3816
|
+
var mRaw = internalOf(raw.internalSources || [], REGISTERED_CAP_NAMES.materials);
|
|
3817
|
+
var mSub = internalOf(sub.internalSources || [], REGISTERED_CAP_NAMES.materials);
|
|
3818
|
+
if (mRaw && (mRaw.driveFolderIds || []).length > 0 && mSub && (mSub.driveFolderIds || []).length === 0) out[REGISTERED_CAP_NAMES.materials] = 1;
|
|
3819
|
+
var btRaw = raw.backlogTarget;
|
|
3820
|
+
var rawTargets = btRaw && Array.isArray(btRaw.targets) ? btRaw.targets.length : btRaw && btRaw.domain ? 1 : 0;
|
|
3821
|
+
if (rawTargets > 0 && Array.isArray(LIVE_REGISTERED.issues) && LIVE_REGISTERED.issues.length === 0) out[REGISTERED_CAP_NAMES.issues] = 1;
|
|
3665
3822
|
return out;
|
|
3666
3823
|
}
|
|
3667
3824
|
/** その能力に、まとめ表がまだ知らない行があるか */
|
|
@@ -5266,6 +5423,10 @@ ${nextStateDelay.toString()}
|
|
|
5266
5423
|
if (x && x.domain && x.projectKey) out.push({ domain: String(x.domain), projectKey: String(x.projectKey) });
|
|
5267
5424
|
}
|
|
5268
5425
|
if (out.length) return out;
|
|
5426
|
+
// 🔴 **正本(issues-config.json)が読めていて0件のときは、url から復元しない(段A補)。**
|
|
5427
|
+
// このフォールバックは「古いまとめ表に targets が無い」案件を救うためのもの。
|
|
5428
|
+
// 正本が「無い」と言っているのに復元すると、**最後の1件を解除してもリロードで戻ってくる**
|
|
5429
|
+
if (LIVE_REGISTERED && Array.isArray(LIVE_REGISTERED.issues) && LIVE_REGISTERED.issues.length === 0) return [];
|
|
5269
5430
|
var u = (s && s.url && backlogTargetOf(s.url)) || null;
|
|
5270
5431
|
return u ? [u] : [];
|
|
5271
5432
|
}
|
package/package.json
CHANGED