dsh-diff-approval 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -10
- package/README.zh.md +18 -10
- package/docs/images/pending-panel.png +0 -0
- package/docs/images/pending-panel.zh.png +0 -0
- package/lib/client.js +815 -212
- package/lib/index.js +714 -34
- package/lib/types/client/PendingPanel.d.ts +11 -1
- package/lib/types/client/SettingsTab.d.ts +11 -0
- package/lib/types/client/locales.d.ts +38 -0
- package/lib/types/client/port.d.ts +7 -1
- package/lib/types/client/settings.d.ts +19 -0
- package/lib/types/client/slots.d.ts +17 -1
- package/lib/types/client/store.d.ts +9 -1
- package/lib/types/pending.d.ts +12 -0
- package/lib/types/types.d.ts +17 -2
- package/lib/types/vcs.d.ts +89 -0
- package/package.json +3 -1
package/lib/client.js
CHANGED
|
@@ -11620,8 +11620,39 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
11620
11620
|
return `${referencePathOf(path, workspacePath)}:${lineRangeLabel(start, end)}`;
|
|
11621
11621
|
}
|
|
11622
11622
|
//#endregion
|
|
11623
|
+
//#region lib/types/client/settings.js
|
|
11624
|
+
/** Client preferences for the review panel, persisted in localStorage. */
|
|
11625
|
+
const PASTE_ON_COPY_KEY = "diff-approval:paste-on-copy";
|
|
11626
|
+
const IMPORT_UNTRACKED_KEY = "diff-approval:import-untracked";
|
|
11627
|
+
/**
|
|
11628
|
+
* Whether copying a reference should also paste it into the chat input and
|
|
11629
|
+
* focus it. Defaults to on; only an explicit `'0'` disables it.
|
|
11630
|
+
* @returns whether auto-paste is enabled.
|
|
11631
|
+
*/
|
|
11632
|
+
function pasteOnCopyEnabled() {
|
|
11633
|
+
return localStorage.getItem(PASTE_ON_COPY_KEY) !== "0";
|
|
11634
|
+
}
|
|
11635
|
+
/** Persist the auto-paste preference. */
|
|
11636
|
+
function setPasteOnCopyEnabled(value) {
|
|
11637
|
+
localStorage.setItem(PASTE_ON_COPY_KEY, value ? "1" : "0");
|
|
11638
|
+
}
|
|
11639
|
+
/**
|
|
11640
|
+
* Whether importing workspace VCS changes includes new/untracked files (git
|
|
11641
|
+
* `??`, svn `?`, p4 unversioned). Defaults to off: collecting them scans the
|
|
11642
|
+
* whole workspace, which can be slow on large trees, so the preference is
|
|
11643
|
+
* opt-in. Only an explicit `'1'` enables it.
|
|
11644
|
+
* @returns whether untracked files are imported.
|
|
11645
|
+
*/
|
|
11646
|
+
function includeUntrackedEnabled() {
|
|
11647
|
+
return localStorage.getItem(IMPORT_UNTRACKED_KEY) === "1";
|
|
11648
|
+
}
|
|
11649
|
+
/** Persist the import-untracked preference. */
|
|
11650
|
+
function setIncludeUntrackedEnabled(value) {
|
|
11651
|
+
localStorage.setItem(IMPORT_UNTRACKED_KEY, value ? "1" : "0");
|
|
11652
|
+
}
|
|
11653
|
+
//#endregion
|
|
11623
11654
|
//#region \0dsh-css:/home/runner/work/dsh-diff-approval/dsh-diff-approval/src/client/PendingPanel.module.css.mjs
|
|
11624
|
-
const css = ".F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 8px);height:42px;margin:4px -4px;display:flex;position:relative}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_states{flex:1;min-height:0;padding:4px 12px 12px;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex:none;width:240px;min-height:0;padding:4px 8px 12px;overflow-y:auto}.F1KBNa_resizeHandle{cursor:col-resize;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:baseline;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-markdown-code-block);overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);flex:1;font-size:12px;line-height:18px;overflow:hidden}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);cursor:text;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_diffBody [data-diff-search=hit]{background-image:linear-gradient(#facc1529,#facc1529)}.F1KBNa_diffBody [data-diff-search=current]{background-image:linear-gradient(#facc1552,#facc1552)}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;display:table}.F1KBNa_line{height:22px;line-height:22px;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}";
|
|
11655
|
+
const css = ".F1KBNa_layer{box-sizing:border-box;flex:none;align-items:center;width:calc(100% + 4px);height:42px;margin:4px -2px;display:flex;position:relative}.F1KBNa_footerButtons{align-items:center;width:100%;display:flex}.F1KBNa_badge{box-sizing:border-box;width:100%;height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.F1KBNa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_badge[data-active]{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_badge:disabled{color:var(--dsw-alias-label-tertiary);cursor:default;background:0 0}.F1KBNa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.F1KBNa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}.F1KBNa_layer.F1KBNa_rail{width:36px;height:36px;margin:8px 0 10px}.F1KBNa_rail .F1KBNa_badge{border-radius:50%;justify-content:center;gap:0;width:36px;height:36px;padding:0}.F1KBNa_rail .F1KBNa_badgeLabel{display:none}.F1KBNa_rail .F1KBNa_badgeCount{box-sizing:border-box;background:var(--dsw-alias-state-business-primary);min-width:18px;height:18px;color:var(--dsw-alias-label-primary-foreground);font-variant-numeric:tabular-nums;border-radius:9px;justify-content:center;align-items:center;padding:0 4px;font-size:11px;line-height:18px;display:flex;position:absolute;top:-3px;right:-7px}.F1KBNa_fullscreenBackdrop{z-index:29;background:var(--dsw-specific-sidebar-fill);position:fixed;inset:0}.F1KBNa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:auto;max-width:none;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;inset:8px 8px 128px;overflow:hidden}.F1KBNa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:10px 12px;display:flex}.F1KBNa_headerActions{align-items:center;gap:2px;display:flex}.F1KBNa_settingsPage{padding:8px 12px}.F1KBNa_settingsRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.F1KBNa_settingsRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.F1KBNa_settingsRowTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.F1KBNa_settingsRowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.F1KBNa_settingsSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.F1KBNa_settingsSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_settingsSelectorChevron{flex:none}.F1KBNa_states{flex-direction:column;flex:1;min-height:0;padding:4px 12px 12px;display:flex;overflow-y:auto}.F1KBNa_split{flex:1;align-items:stretch;min-height:0;display:flex}.F1KBNa_fileList{box-sizing:border-box;border-right:1px solid var(--dsw-alias-border-l2);flex-direction:column;flex:none;width:240px;min-height:0;padding:4px 8px 12px;display:flex}.F1KBNa_listScroll{flex:1;min-height:0;overflow-y:auto}.F1KBNa_bulkActions{flex:none;gap:6px;padding-top:8px;display:flex}.F1KBNa_bulkActions .F1KBNa_action{text-align:center;flex:1}.F1KBNa_resizeHandle{cursor:col-resize;background:0 0;flex:none;width:5px;margin:0 -2px}.F1KBNa_resizeHandle:hover{background:var(--dsw-alias-border-l2)}.F1KBNa_detail{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.F1KBNa_detailEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;margin:0;padding:24px;font-size:12px;line-height:18px;display:flex}.F1KBNa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.F1KBNa_note,.F1KBNa_readError,.F1KBNa_hint{color:var(--dsw-alias-label-tertiary);margin:4px 0;font-size:12px;line-height:18px}.F1KBNa_noteCentered{text-align:center;margin:auto}.F1KBNa_emptyState{flex-direction:column;align-items:center;gap:10px;margin:auto;display:flex}.F1KBNa_importButton{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 14px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_importButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_importButton:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_importNote{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;font-size:12px;line-height:18px}.F1KBNa_readError{color:var(--dsw-alias-state-error-primary)}.F1KBNa_group{color:var(--dsw-alias-label-tertiary);margin:8px 0 4px;font-size:12px;font-weight:500;line-height:16px}.F1KBNa_rows{margin:0;padding:0;list-style:none}.F1KBNa_row{border:1px solid #0000;border-radius:10px;margin:2px 0}.F1KBNa_rowHead{width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:baseline;gap:8px;padding:6px 8px;display:flex}.F1KBNa_rowHead:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.F1KBNa_rowHead[data-selected]{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_rowPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-markdown-code-block);overflow:hidden}.F1KBNa_kindTag{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_kindHint{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:16px}.F1KBNa_divergedHint,.F1KBNa_missingHint{border-bottom:1px solid var(--dsw-alias-border-l2);margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missing{border:1px solid var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary));white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_rowFailed{border:1px solid var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);white-space:nowrap;border-radius:6px;flex:none;padding:1px 6px;font-size:11px;line-height:14px}.F1KBNa_actionError{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;margin:0;padding:6px 8px;font-size:12px;line-height:18px}.F1KBNa_missingHint{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-state-warn-primary))}.F1KBNa_rowMeta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;gap:6px;margin-left:auto;font-size:12px;line-height:16px;display:inline-flex}.F1KBNa_addCount{color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_delCount{color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 60%, var(--dsw-alias-label-primary))}.F1KBNa_diff{background:var(--dsw-alias-markdown-code-block);flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.F1KBNa_diffHeader{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffPath{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code-block);flex:1;font-size:12px;line-height:18px;overflow:hidden}.F1KBNa_diffActions{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:6px 8px;display:flex}.F1KBNa_diffStats{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:16px}.F1KBNa_flexSpacer{flex:1}.F1KBNa_action{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_action:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.F1KBNa_actionPrimary{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50)}.F1KBNa_actionPrimary:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-static-neutral-bluish-1000))}.F1KBNa_actionPrimary:disabled{background:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:.55}.F1KBNa_actionQuietDisabled:disabled{cursor:pointer;color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1);background:0 0}.F1KBNa_actionPrimary.F1KBNa_actionQuietDisabled:disabled{background:var(--dsw-alias-state-business-primary);border-color:var(--dsw-alias-state-business-primary);color:var(--dsw-static-neutral-bluish-50);opacity:1}.F1KBNa_iconAction{justify-content:center;align-items:center;min-height:25px;padding:4px 6px;display:inline-flex}.F1KBNa_close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expand{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:0 0;border:none;border-radius:28px;justify-content:center;align-items:center;padding:0;display:inline-flex}.F1KBNa_expand:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.F1KBNa_expandExpanded svg{transform:rotate(180deg)}.F1KBNa_diffBodyWrap{flex:1;min-height:0;display:flex;position:relative}.F1KBNa_diffBody{min-width:0;font:var(--dsw-font-markdown-code-block);cursor:text;outline:none;flex:1;padding:0;position:relative;overflow:auto}.F1KBNa_diffBody::-webkit-scrollbar,.F1KBNa_diffBody::-webkit-scrollbar-track,.F1KBNa_diffBody::-webkit-scrollbar-thumb{cursor:default}.F1KBNa_blockActions{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);z-index:2;border-radius:10px;align-items:center;gap:9px;padding:5px;display:flex;position:absolute;right:8px}.F1KBNa_blockPosition{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;margin-top:1px;margin-left:7px;font-size:12px;line-height:16px}.F1KBNa_searchBar{z-index:3;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-markdown-code-block);box-shadow:var(--dsw-shadow-lv1);border-radius:10px;align-items:center;gap:4px;padding:4px;display:flex;position:absolute;top:8px;right:8px}.F1KBNa_searchInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);width:150px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:3px 8px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_searchInput:focus{border-color:var(--dsw-alias-state-business-primary)}.F1KBNa_searchCount{text-align:center;min-width:34px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:12px;line-height:16px}.F1KBNa_diffBody [data-diff-search=hit]{background-image:linear-gradient(#facc1529,#facc1529)}.F1KBNa_diffBody [data-diff-search=current]{background-image:linear-gradient(#facc1552,#facc1552)}.F1KBNa_blockFlash{z-index:1;box-sizing:border-box;border:2px solid var(--dsw-alias-state-business-primary);pointer-events:none;border-radius:4px;animation:1s ease-out forwards F1KBNa_diffFlash;position:absolute;left:0;right:0}@keyframes F1KBNa_diffFlash{0%{opacity:1}to{opacity:0}}.F1KBNa_overviewRuler{pointer-events:none;opacity:.5;width:4px;position:absolute;top:0;bottom:0;right:0}.F1KBNa_overviewMarker{border-radius:2px;width:100%;min-height:2px;position:absolute;right:0}.F1KBNa_markerDel{background-color:var(--dsw-alias-state-error-primary)}.F1KBNa_markerAdd{background-color:var(--dsw-alias-state-success-primary)}.F1KBNa_lines{border-spacing:0;width:max-content;min-width:100%;display:table}.F1KBNa_line{height:22px;line-height:22px;display:table-row}.F1KBNa_vSpacer{display:table-row}.F1KBNa_gutter{box-sizing:border-box;text-align:right;width:44px;color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;user-select:none;cursor:default;padding-right:10px;display:table-cell}.F1KBNa_code{white-space:pre;display:table-cell}.F1KBNa_context{color:var(--dsw-alias-label-primary)}.F1KBNa_del{background-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.F1KBNa_add{background-color:color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent)}.F1KBNa_statusBar{box-sizing:border-box;border-top:1px solid var(--dsw-alias-border-l2);height:34px;color:var(--dsw-alias-label-tertiary);font-family:var(--dsw-font-markdown-code-block);font-variant-numeric:tabular-nums;flex:none;align-items:center;padding:0 8px;font-size:12px;line-height:18px;display:flex}.F1KBNa_statusAction{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border-radius:8px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px}.F1KBNa_statusAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langSelect{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;flex:none;align-items:center;gap:4px;padding:3px 12px;font-family:inherit;font-size:12px;line-height:18px;display:inline-flex}.F1KBNa_langSelect:hover{background:var(--dsw-alias-interactive-bg-hover)}.F1KBNa_langLabel{text-overflow:ellipsis;white-space:nowrap;max-width:140px;overflow:hidden}.F1KBNa_notice{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);max-width:360px;box-shadow:var(--dsw-shadow-lv3);border-radius:10px;align-items:flex-start;gap:12px;padding:12px 14px;display:flex;position:fixed;bottom:24px;right:24px}.F1KBNa_noticeText{font:var(--dsw-font-caption);color:var(--dsw-alias-label-primary);flex:1;margin:0;line-height:1.45}.F1KBNa_noticeButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);font:var(--dsw-font-caption);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px}.F1KBNa_noticeButton:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}";
|
|
11625
11656
|
const tagId = "dsh-diff-approval/PendingPanel.module.css";
|
|
11626
11657
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
11627
11658
|
const tag = document.createElement("style");
|
|
@@ -11631,73 +11662,95 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
11631
11662
|
document.head.appendChild(tag);
|
|
11632
11663
|
}
|
|
11633
11664
|
var PendingPanel_module_css_default = {
|
|
11634
|
-
"
|
|
11635
|
-
"
|
|
11665
|
+
"rows": "F1KBNa_rows",
|
|
11666
|
+
"flexSpacer": "F1KBNa_flexSpacer",
|
|
11667
|
+
"importNote": "F1KBNa_importNote",
|
|
11668
|
+
"detailEmpty": "F1KBNa_detailEmpty",
|
|
11669
|
+
"divergedHint": "F1KBNa_divergedHint",
|
|
11670
|
+
"detail": "F1KBNa_detail",
|
|
11671
|
+
"note": "F1KBNa_note",
|
|
11672
|
+
"settingsRowDesc": "F1KBNa_settingsRowDesc",
|
|
11673
|
+
"add": "F1KBNa_add",
|
|
11636
11674
|
"searchCount": "F1KBNa_searchCount",
|
|
11637
|
-
"hint": "F1KBNa_hint",
|
|
11638
|
-
"layer": "F1KBNa_layer",
|
|
11639
11675
|
"footerButtons": "F1KBNa_footerButtons",
|
|
11640
|
-
"
|
|
11641
|
-
"
|
|
11642
|
-
"
|
|
11643
|
-
"
|
|
11676
|
+
"settingsRowTitle": "F1KBNa_settingsRowTitle",
|
|
11677
|
+
"title": "F1KBNa_title",
|
|
11678
|
+
"hint": "F1KBNa_hint",
|
|
11679
|
+
"overviewRuler": "F1KBNa_overviewRuler",
|
|
11680
|
+
"gutter": "F1KBNa_gutter",
|
|
11681
|
+
"code": "F1KBNa_code",
|
|
11682
|
+
"badge": "F1KBNa_badge",
|
|
11683
|
+
"badgeLabel": "F1KBNa_badgeLabel",
|
|
11684
|
+
"rail": "F1KBNa_rail",
|
|
11685
|
+
"diffBody": "F1KBNa_diffBody",
|
|
11686
|
+
"rowMeta": "F1KBNa_rowMeta",
|
|
11687
|
+
"resizeHandle": "F1KBNa_resizeHandle",
|
|
11644
11688
|
"kindTag": "F1KBNa_kindTag",
|
|
11645
11689
|
"states": "F1KBNa_states",
|
|
11646
|
-
"
|
|
11647
|
-
"
|
|
11690
|
+
"panel": "F1KBNa_panel",
|
|
11691
|
+
"diff": "F1KBNa_diff",
|
|
11692
|
+
"statusAction": "F1KBNa_statusAction",
|
|
11693
|
+
"blockPosition": "F1KBNa_blockPosition",
|
|
11694
|
+
"notice": "F1KBNa_notice",
|
|
11695
|
+
"noticeText": "F1KBNa_noticeText",
|
|
11696
|
+
"rowFailed": "F1KBNa_rowFailed",
|
|
11697
|
+
"context": "F1KBNa_context",
|
|
11648
11698
|
"del": "F1KBNa_del",
|
|
11649
|
-
"searchInput": "F1KBNa_searchInput",
|
|
11650
|
-
"expand": "F1KBNa_expand",
|
|
11651
|
-
"searchBar": "F1KBNa_searchBar",
|
|
11652
11699
|
"markerDel": "F1KBNa_markerDel",
|
|
11653
|
-
"
|
|
11654
|
-
"
|
|
11700
|
+
"langLabel": "F1KBNa_langLabel",
|
|
11701
|
+
"missing": "F1KBNa_missing",
|
|
11702
|
+
"diffStats": "F1KBNa_diffStats",
|
|
11703
|
+
"actionError": "F1KBNa_actionError",
|
|
11704
|
+
"blockFlash": "F1KBNa_blockFlash",
|
|
11705
|
+
"noticeButton": "F1KBNa_noticeButton",
|
|
11706
|
+
"iconAction": "F1KBNa_iconAction",
|
|
11707
|
+
"diffFlash": "F1KBNa_diffFlash",
|
|
11708
|
+
"noteCentered": "F1KBNa_noteCentered",
|
|
11655
11709
|
"badgeCount": "F1KBNa_badgeCount",
|
|
11656
|
-
"
|
|
11657
|
-
"
|
|
11710
|
+
"statusBar": "F1KBNa_statusBar",
|
|
11711
|
+
"listScroll": "F1KBNa_listScroll",
|
|
11658
11712
|
"expandExpanded": "F1KBNa_expandExpanded",
|
|
11659
|
-
"
|
|
11660
|
-
"diffHeader": "F1KBNa_diffHeader",
|
|
11661
|
-
"fileList": "F1KBNa_fileList",
|
|
11662
|
-
"diffActions": "F1KBNa_diffActions",
|
|
11713
|
+
"lines": "F1KBNa_lines",
|
|
11663
11714
|
"readError": "F1KBNa_readError",
|
|
11664
|
-
"
|
|
11665
|
-
"
|
|
11666
|
-
"
|
|
11667
|
-
"
|
|
11668
|
-
"
|
|
11669
|
-
"
|
|
11715
|
+
"layer": "F1KBNa_layer",
|
|
11716
|
+
"expand": "F1KBNa_expand",
|
|
11717
|
+
"blockActions": "F1KBNa_blockActions",
|
|
11718
|
+
"actionPrimary": "F1KBNa_actionPrimary",
|
|
11719
|
+
"fullscreenBackdrop": "F1KBNa_fullscreenBackdrop",
|
|
11720
|
+
"diffBodyWrap": "F1KBNa_diffBodyWrap",
|
|
11721
|
+
"diffHeader": "F1KBNa_diffHeader",
|
|
11722
|
+
"rowPath": "F1KBNa_rowPath",
|
|
11670
11723
|
"headerActions": "F1KBNa_headerActions",
|
|
11671
|
-
"
|
|
11672
|
-
"
|
|
11673
|
-
"add": "F1KBNa_add",
|
|
11674
|
-
"badgeLabel": "F1KBNa_badgeLabel",
|
|
11675
|
-
"iconAction": "F1KBNa_iconAction",
|
|
11676
|
-
"markerAdd": "F1KBNa_markerAdd",
|
|
11677
|
-
"row": "F1KBNa_row",
|
|
11678
|
-
"diffBody": "F1KBNa_diffBody",
|
|
11679
|
-
"langLabel": "F1KBNa_langLabel",
|
|
11680
|
-
"lines": "F1KBNa_lines",
|
|
11681
|
-
"panel": "F1KBNa_panel",
|
|
11724
|
+
"kindHint": "F1KBNa_kindHint",
|
|
11725
|
+
"diffPath": "F1KBNa_diffPath",
|
|
11682
11726
|
"split": "F1KBNa_split",
|
|
11683
|
-
"
|
|
11727
|
+
"importButton": "F1KBNa_importButton",
|
|
11728
|
+
"diffActions": "F1KBNa_diffActions",
|
|
11684
11729
|
"delCount": "F1KBNa_delCount",
|
|
11685
|
-
"overviewRuler": "F1KBNa_overviewRuler",
|
|
11686
|
-
"rowMeta": "F1KBNa_rowMeta",
|
|
11687
|
-
"blockActions": "F1KBNa_blockActions",
|
|
11688
|
-
"rows": "F1KBNa_rows",
|
|
11689
|
-
"diffBodyWrap": "F1KBNa_diffBodyWrap",
|
|
11690
|
-
"detailEmpty": "F1KBNa_detailEmpty",
|
|
11691
|
-
"close": "F1KBNa_close",
|
|
11692
|
-
"statusBar": "F1KBNa_statusBar",
|
|
11693
|
-
"actionPrimary": "F1KBNa_actionPrimary",
|
|
11694
11730
|
"rowHead": "F1KBNa_rowHead",
|
|
11695
|
-
"
|
|
11696
|
-
"diffPath": "F1KBNa_diffPath",
|
|
11697
|
-
"flexSpacer": "F1KBNa_flexSpacer",
|
|
11698
|
-
"blockPosition": "F1KBNa_blockPosition",
|
|
11731
|
+
"overviewMarker": "F1KBNa_overviewMarker",
|
|
11699
11732
|
"header": "F1KBNa_header",
|
|
11700
|
-
"
|
|
11733
|
+
"searchInput": "F1KBNa_searchInput",
|
|
11734
|
+
"markerAdd": "F1KBNa_markerAdd",
|
|
11735
|
+
"vSpacer": "F1KBNa_vSpacer",
|
|
11736
|
+
"settingsRowText": "F1KBNa_settingsRowText",
|
|
11737
|
+
"missingHint": "F1KBNa_missingHint",
|
|
11738
|
+
"group": "F1KBNa_group",
|
|
11739
|
+
"emptyState": "F1KBNa_emptyState",
|
|
11740
|
+
"bulkActions": "F1KBNa_bulkActions",
|
|
11741
|
+
"settingsSelector": "F1KBNa_settingsSelector",
|
|
11742
|
+
"searchBar": "F1KBNa_searchBar",
|
|
11743
|
+
"settingsSelectorChevron": "F1KBNa_settingsSelectorChevron",
|
|
11744
|
+
"row": "F1KBNa_row",
|
|
11745
|
+
"close": "F1KBNa_close",
|
|
11746
|
+
"line": "F1KBNa_line",
|
|
11747
|
+
"settingsRow": "F1KBNa_settingsRow",
|
|
11748
|
+
"fileList": "F1KBNa_fileList",
|
|
11749
|
+
"settingsPage": "F1KBNa_settingsPage",
|
|
11750
|
+
"addCount": "F1KBNa_addCount",
|
|
11751
|
+
"action": "F1KBNa_action",
|
|
11752
|
+
"langSelect": "F1KBNa_langSelect",
|
|
11753
|
+
"actionQuietDisabled": "F1KBNa_actionQuietDisabled"
|
|
11701
11754
|
};
|
|
11702
11755
|
//#endregion
|
|
11703
11756
|
//#region lib/types/client/PendingPanel.js
|
|
@@ -11731,6 +11784,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
11731
11784
|
const MAX_LIST_WIDTH_PX = 560;
|
|
11732
11785
|
/** Fixed diff-row height in px; the virtual window and jump math are built on it. */
|
|
11733
11786
|
const ROW_HEIGHT_PX = 22;
|
|
11787
|
+
/** The overview ruler's width in px (mirrors `.overviewRuler`). The flash is
|
|
11788
|
+
* kept off it even when the scroller has no vertical scrollbar. */
|
|
11789
|
+
const OVERVIEW_RULER_WIDTH_PX = 4;
|
|
11734
11790
|
/** Rows rendered beyond the visible window in each direction. */
|
|
11735
11791
|
const OVERSCAN_ROWS = 8;
|
|
11736
11792
|
/** Height of the floating per-block Keep/Revert frame in px: 26px actions +
|
|
@@ -11742,12 +11798,31 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
11742
11798
|
const index = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
11743
11799
|
return index < 0 ? path : path.slice(index + 1);
|
|
11744
11800
|
}
|
|
11801
|
+
/**
|
|
11802
|
+
* Open the DSH settings dialog and switch to this plugin's section. The
|
|
11803
|
+
* settings shell keeps its open state and the active section id as
|
|
11804
|
+
* component-local viewing state with no cross-plugin service, so the dialog
|
|
11805
|
+
* is opened by clicking the sidebar's settings trigger and then the nav cell
|
|
11806
|
+
* for this section. `element.click()` still fires React's delegated click
|
|
11807
|
+
* handlers, reaching the same state transitions a user gesture would.
|
|
11808
|
+
* @param sectionLabel - the nav label of this plugin's settings section.
|
|
11809
|
+
*/
|
|
11810
|
+
function openSettingsSection(sectionLabel) {
|
|
11811
|
+
const trigger = document.querySelector("button[aria-haspopup=\"dialog\"]");
|
|
11812
|
+
if (trigger === null) return;
|
|
11813
|
+
trigger.click();
|
|
11814
|
+
requestAnimationFrame(() => {
|
|
11815
|
+
Array.from(document.querySelectorAll("button")).find((button) => button.textContent?.trim() === sectionLabel)?.click();
|
|
11816
|
+
});
|
|
11817
|
+
}
|
|
11745
11818
|
/** The diff body's row class per line kind. */
|
|
11746
11819
|
const ROW_CLASS = {
|
|
11747
11820
|
context: PendingPanel_module_css_default.context,
|
|
11748
11821
|
del: PendingPanel_module_css_default.del,
|
|
11749
11822
|
add: PendingPanel_module_css_default.add
|
|
11750
11823
|
};
|
|
11824
|
+
/** Empty failure map reused as the snapshot's canonical absent value. */
|
|
11825
|
+
const EMPTY_FAILED_MAP = /* @__PURE__ */ new Map();
|
|
11751
11826
|
/**
|
|
11752
11827
|
* One rendered diff row, memoized so a poll or an unrelated state change
|
|
11753
11828
|
* does not re-render rows whose content, highlight, and focus are unchanged.
|
|
@@ -11909,7 +11984,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
11909
11984
|
};
|
|
11910
11985
|
}
|
|
11911
11986
|
/** One row of the file list: the clickable head in the left pane. */
|
|
11912
|
-
function PendingFileRow({ file, selected, t, onSelect }) {
|
|
11987
|
+
function PendingFileRow({ file, selected, failedMessage, t, onSelect }) {
|
|
11913
11988
|
const stats = (0, react.useMemo)(() => computeWholeFileDiff(file.oldText, file.newText), [file.oldText, file.newText]);
|
|
11914
11989
|
return (0, react_jsx_runtime.jsx)("li", {
|
|
11915
11990
|
className: PendingPanel_module_css_default.row,
|
|
@@ -11938,6 +12013,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
11938
12013
|
title: t("panel.missingHint"),
|
|
11939
12014
|
children: t("panel.missing")
|
|
11940
12015
|
}),
|
|
12016
|
+
failedMessage !== void 0 && (0, react_jsx_runtime.jsx)("span", {
|
|
12017
|
+
className: PendingPanel_module_css_default.rowFailed,
|
|
12018
|
+
title: failedMessage,
|
|
12019
|
+
children: t("row.failed")
|
|
12020
|
+
}),
|
|
11941
12021
|
(0, react_jsx_runtime.jsxs)("span", {
|
|
11942
12022
|
className: PendingPanel_module_css_default.rowMeta,
|
|
11943
12023
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
@@ -11954,7 +12034,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
11954
12034
|
});
|
|
11955
12035
|
}
|
|
11956
12036
|
/** The selected file's diff, actions, jump controls, and copy toolbar. */
|
|
11957
|
-
function PendingDiff({ file, busy, workspacePath, jumpSignal, t, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen }) {
|
|
12037
|
+
function PendingDiff({ file, busy, workspacePath, jumpSignal, undoFlash, failedMessage, onPasteReference, t, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen }) {
|
|
11958
12038
|
const [langOverride, setLangOverride] = (0, react.useState)(void 0);
|
|
11959
12039
|
const [langMenuOpen, setLangMenuOpen] = (0, react.useState)(false);
|
|
11960
12040
|
const langMenuItems = (0, react.useMemo)(() => [{
|
|
@@ -12039,10 +12119,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12039
12119
|
const [searchQuery, setSearchQuery] = (0, react.useState)("");
|
|
12040
12120
|
const [searchIndex, setSearchIndex] = (0, react.useState)(0);
|
|
12041
12121
|
const searchInputRef = (0, react.useRef)(null);
|
|
12122
|
+
const [flashKey, setFlashKey] = (0, react.useState)(0);
|
|
12042
12123
|
(0, react.useEffect)(() => {
|
|
12043
12124
|
setFocus(0);
|
|
12044
|
-
|
|
12045
|
-
|
|
12125
|
+
bodyRef.current?.focus();
|
|
12126
|
+
setFlashKey((key) => key + 1);
|
|
12046
12127
|
setHoveredBlock(void 0);
|
|
12047
12128
|
setSelection(void 0);
|
|
12048
12129
|
setLangOverride(void 0);
|
|
@@ -12052,6 +12133,12 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12052
12133
|
setSearchQuery("");
|
|
12053
12134
|
setSearchIndex(0);
|
|
12054
12135
|
}, [file.id]);
|
|
12136
|
+
(0, react.useEffect)(() => {
|
|
12137
|
+
if (undoFlash === 0) return;
|
|
12138
|
+
setFocus(0);
|
|
12139
|
+
setScrollTick((tick) => tick + 1);
|
|
12140
|
+
setFlashKey((key) => key + 1);
|
|
12141
|
+
}, [undoFlash]);
|
|
12055
12142
|
const blockRanges = (0, react.useMemo)(() => {
|
|
12056
12143
|
return model.blocks.map((block) => blockRangesOf(model.diff.rows, block));
|
|
12057
12144
|
}, [model]);
|
|
@@ -12086,7 +12173,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12086
12173
|
(0, react.useEffect)(() => {
|
|
12087
12174
|
setSearchIndex(0);
|
|
12088
12175
|
}, [searchQuery, file.id]);
|
|
12089
|
-
(0, react.
|
|
12176
|
+
(0, react.useLayoutEffect)(() => {
|
|
12090
12177
|
const row = currentSearchRow;
|
|
12091
12178
|
if (row === void 0) return;
|
|
12092
12179
|
const body = bodyRef.current;
|
|
@@ -12132,7 +12219,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12132
12219
|
observer?.disconnect();
|
|
12133
12220
|
};
|
|
12134
12221
|
}, [file.id]);
|
|
12135
|
-
(0, react.
|
|
12222
|
+
(0, react.useLayoutEffect)(() => {
|
|
12136
12223
|
if (rowCount === 0) return;
|
|
12137
12224
|
const block = model.blocks[focus];
|
|
12138
12225
|
if (block === void 0) return;
|
|
@@ -12161,6 +12248,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12161
12248
|
return 0;
|
|
12162
12249
|
});
|
|
12163
12250
|
setScrollTick((tick) => tick + 1);
|
|
12251
|
+
setFlashKey((key) => key + 1);
|
|
12164
12252
|
};
|
|
12165
12253
|
(0, react.useEffect)(() => {
|
|
12166
12254
|
if (jumpSignal === 0) return;
|
|
@@ -12190,10 +12278,15 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12190
12278
|
if (selectionReference === void 0) return;
|
|
12191
12279
|
if (!await (0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(selectionReference)) return;
|
|
12192
12280
|
setCopied(true);
|
|
12281
|
+
if (pasteOnCopyEnabled()) onPasteReference(file.sessionId, selectionReference);
|
|
12193
12282
|
window.setTimeout(() => {
|
|
12194
12283
|
setCopied(false);
|
|
12195
12284
|
}, 1500);
|
|
12196
|
-
}, [
|
|
12285
|
+
}, [
|
|
12286
|
+
file.sessionId,
|
|
12287
|
+
onPasteReference,
|
|
12288
|
+
selectionReference
|
|
12289
|
+
]);
|
|
12197
12290
|
(0, react.useEffect)(() => {
|
|
12198
12291
|
const onKeyDown = (event) => {
|
|
12199
12292
|
if (!(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey) return;
|
|
@@ -12202,9 +12295,9 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12202
12295
|
event.preventDefault();
|
|
12203
12296
|
copySelection();
|
|
12204
12297
|
};
|
|
12205
|
-
|
|
12298
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
12206
12299
|
return () => {
|
|
12207
|
-
|
|
12300
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
12208
12301
|
};
|
|
12209
12302
|
}, [copySelection]);
|
|
12210
12303
|
(0, react.useEffect)(() => {
|
|
@@ -12221,8 +12314,31 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12221
12314
|
window.removeEventListener("keydown", onKeyDown, true);
|
|
12222
12315
|
};
|
|
12223
12316
|
}, []);
|
|
12317
|
+
const jumpRef = (0, react.useRef)(jump);
|
|
12318
|
+
jumpRef.current = jump;
|
|
12319
|
+
(0, react.useEffect)(() => {
|
|
12320
|
+
const onKeyDown = (event) => {
|
|
12321
|
+
if (!(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey) return;
|
|
12322
|
+
const key = event.key.toLowerCase();
|
|
12323
|
+
if (key !== "arrowup" && key !== "arrowdown") return;
|
|
12324
|
+
const target = event.target;
|
|
12325
|
+
if (target instanceof Element && target.closest("input, textarea, [contenteditable=\"true\"]") !== null) return;
|
|
12326
|
+
event.preventDefault();
|
|
12327
|
+
jumpRef.current(key === "arrowup" ? -1 : 1);
|
|
12328
|
+
};
|
|
12329
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
12330
|
+
return () => {
|
|
12331
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
12332
|
+
};
|
|
12333
|
+
}, []);
|
|
12224
12334
|
const focusedBlock = model.blocks.length > 0 ? model.blocks[focus] : void 0;
|
|
12225
12335
|
const inFocusedBlock = (index) => focusedBlock !== void 0 && index >= focusedBlock.start && index <= focusedBlock.end;
|
|
12336
|
+
const flashWidth = (() => {
|
|
12337
|
+
const scroller = bodyRef.current;
|
|
12338
|
+
if (scroller === null) return 0;
|
|
12339
|
+
const scrollbarWidth = scroller.offsetWidth - scroller.clientWidth;
|
|
12340
|
+
return Math.max(0, scroller.clientWidth - (scrollbarWidth > 0 ? 0 : OVERVIEW_RULER_WIDTH_PX));
|
|
12341
|
+
})();
|
|
12226
12342
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
12227
12343
|
className: PendingPanel_module_css_default.diff,
|
|
12228
12344
|
"data-diff-approval-diff": true,
|
|
@@ -12281,7 +12397,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12281
12397
|
children: t("panel.createHint")
|
|
12282
12398
|
}),
|
|
12283
12399
|
model.blocks.length > 0 && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12284
|
-
label: t("action.prevDiff")
|
|
12400
|
+
label: `${t("action.prevDiff")} (Ctrl+↑)`,
|
|
12285
12401
|
side: "bottom",
|
|
12286
12402
|
delayMs: 500,
|
|
12287
12403
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -12296,7 +12412,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12296
12412
|
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutline14, { size: 14 })
|
|
12297
12413
|
})
|
|
12298
12414
|
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12299
|
-
label: t("action.nextDiff")
|
|
12415
|
+
label: `${t("action.nextDiff")} (Ctrl+↓)`,
|
|
12300
12416
|
side: "bottom",
|
|
12301
12417
|
delayMs: 500,
|
|
12302
12418
|
children: (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -12327,26 +12443,31 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12327
12443
|
(0, react_jsx_runtime.jsx)("span", { className: PendingPanel_module_css_default.flexSpacer }),
|
|
12328
12444
|
(0, react_jsx_runtime.jsx)("button", {
|
|
12329
12445
|
type: "button",
|
|
12330
|
-
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary}`,
|
|
12446
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary} ${PendingPanel_module_css_default.actionQuietDisabled}`,
|
|
12331
12447
|
"data-diff-keep": true,
|
|
12332
12448
|
disabled: busy,
|
|
12333
12449
|
onClick: () => {
|
|
12334
12450
|
onKeep(file.sessionId, file.id);
|
|
12335
12451
|
},
|
|
12336
|
-
children:
|
|
12452
|
+
children: t("action.keep")
|
|
12337
12453
|
}),
|
|
12338
12454
|
(0, react_jsx_runtime.jsx)("button", {
|
|
12339
12455
|
type: "button",
|
|
12340
|
-
className: PendingPanel_module_css_default.action
|
|
12456
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionQuietDisabled}`,
|
|
12341
12457
|
"data-diff-revert": true,
|
|
12342
12458
|
disabled: busy,
|
|
12343
12459
|
onClick: () => {
|
|
12344
12460
|
onRevert(file.sessionId, file.id);
|
|
12345
12461
|
},
|
|
12346
|
-
children:
|
|
12462
|
+
children: t("action.revert")
|
|
12347
12463
|
})
|
|
12348
12464
|
]
|
|
12349
12465
|
}),
|
|
12466
|
+
failedMessage !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
12467
|
+
className: PendingPanel_module_css_default.actionError,
|
|
12468
|
+
"data-diff-action-error": true,
|
|
12469
|
+
children: failedMessage
|
|
12470
|
+
}),
|
|
12350
12471
|
file.missing && (0, react_jsx_runtime.jsx)("p", {
|
|
12351
12472
|
className: PendingPanel_module_css_default.missingHint,
|
|
12352
12473
|
children: t("panel.missingHint")
|
|
@@ -12357,6 +12478,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12357
12478
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
12358
12479
|
className: PendingPanel_module_css_default.diffBody,
|
|
12359
12480
|
ref: bodyRef,
|
|
12481
|
+
tabIndex: 0,
|
|
12360
12482
|
onScroll,
|
|
12361
12483
|
onMouseLeave: () => {
|
|
12362
12484
|
setHoveredBlock(void 0);
|
|
@@ -12430,6 +12552,15 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12430
12552
|
]
|
|
12431
12553
|
})]
|
|
12432
12554
|
}),
|
|
12555
|
+
focusedBlock !== void 0 && flashKey > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
12556
|
+
className: PendingPanel_module_css_default.blockFlash,
|
|
12557
|
+
"data-diff-block-flash": true,
|
|
12558
|
+
style: {
|
|
12559
|
+
top: focusedBlock.start * ROW_HEIGHT_PX - scrollTop,
|
|
12560
|
+
height: Math.min((focusedBlock.end - focusedBlock.start + 1) * ROW_HEIGHT_PX, viewportHeight > 0 ? viewportHeight : Number.POSITIVE_INFINITY),
|
|
12561
|
+
width: flashWidth
|
|
12562
|
+
}
|
|
12563
|
+
}, flashKey),
|
|
12433
12564
|
searchOpen && (0, react_jsx_runtime.jsxs)("div", {
|
|
12434
12565
|
className: PendingPanel_module_css_default.searchBar,
|
|
12435
12566
|
"data-diff-searchbar": true,
|
|
@@ -12563,16 +12694,36 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12563
12694
|
});
|
|
12564
12695
|
}
|
|
12565
12696
|
/** Render the pending-edit review panel and its unified footer action. */
|
|
12566
|
-
function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, t }) {
|
|
12697
|
+
function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, t }) {
|
|
12567
12698
|
const current = useSessions((state) => state.current);
|
|
12699
|
+
const currentBlank = useSessions((state) => {
|
|
12700
|
+
const id = state.current;
|
|
12701
|
+
return id === void 0 ? false : state.byId[id]?.blank ?? false;
|
|
12702
|
+
});
|
|
12703
|
+
const noSession = current === void 0 || currentBlank;
|
|
12568
12704
|
const snapshot = usePending((snapshot) => snapshot);
|
|
12569
12705
|
const [open, setOpen] = (0, react.useState)(false);
|
|
12570
12706
|
const [selected, setSelected] = (0, react.useState)("");
|
|
12571
12707
|
/** Bumped when the already-open file is clicked again, to jump to the next
|
|
12572
12708
|
* diff block in the open file's detail pane. */
|
|
12573
12709
|
const [jumpSignal, setJumpSignal] = (0, react.useState)(0);
|
|
12574
|
-
/**
|
|
12575
|
-
|
|
12710
|
+
/** Bumped when an undo/redo affected the already-open file, so its detail
|
|
12711
|
+
* pane re-selects the undone diff (flash). */
|
|
12712
|
+
const [undoFlash, setUndoFlash] = (0, react.useState)(0);
|
|
12713
|
+
/** Which bulk decision (keep-all / revert-all) is running; null when idle. */
|
|
12714
|
+
const [bulkBusy, setBulkBusy] = (0, react.useState)(null);
|
|
12715
|
+
/** True while a workspace-changes import is running. */
|
|
12716
|
+
const [importBusy, setImportBusy] = (0, react.useState)(false);
|
|
12717
|
+
/** Feedback under the empty note after an import (no VCS, or a failure). */
|
|
12718
|
+
const [importNote, setImportNote] = (0, react.useState)(void 0);
|
|
12719
|
+
/** Whether the last import note is a failure (drives the alert role). */
|
|
12720
|
+
const [importFailed, setImportFailed] = (0, react.useState)(false);
|
|
12721
|
+
/** A transient banner for an import that found nothing to bring in. */
|
|
12722
|
+
const [importToast, setImportToast] = (0, react.useState)(null);
|
|
12723
|
+
/** A transient banner for a keep/revert failure. */
|
|
12724
|
+
const [actionToast, setActionToast] = (0, react.useState)(null);
|
|
12725
|
+
/** Whether the redo-cleared notice is showing (bottom-right, OK to dismiss). */
|
|
12726
|
+
const [redoClearedNotice, setRedoClearedNotice] = (0, react.useState)(false);
|
|
12576
12727
|
/** Bottom offset tracking the chat composer's top edge so the input stays visible. */
|
|
12577
12728
|
const [bottomPx, setBottomPx] = (0, react.useState)(FALLBACK_BOTTOM_PX);
|
|
12578
12729
|
/** Fullscreen expanded: the panel bottom pins to the window edge, ignoring the composer offset. */
|
|
@@ -12589,6 +12740,15 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12589
12740
|
clearInterval(timer);
|
|
12590
12741
|
};
|
|
12591
12742
|
}, [current, onRefresh]);
|
|
12743
|
+
(0, react.useEffect)(() => {
|
|
12744
|
+
if (!open || !snapshot.redoCleared) return;
|
|
12745
|
+
onAckRedoCleared();
|
|
12746
|
+
setRedoClearedNotice(true);
|
|
12747
|
+
}, [
|
|
12748
|
+
open,
|
|
12749
|
+
snapshot.redoCleared,
|
|
12750
|
+
onAckRedoCleared
|
|
12751
|
+
]);
|
|
12592
12752
|
(0, react.useEffect)(() => {
|
|
12593
12753
|
if (!open) return;
|
|
12594
12754
|
const MEASURE_INTERVAL_MS = 400;
|
|
@@ -12633,6 +12793,22 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12633
12793
|
};
|
|
12634
12794
|
}, [open]);
|
|
12635
12795
|
const files = snapshot.files.filter((file) => file.sessionId === current);
|
|
12796
|
+
/** Per-file keep/revert failures, surfaced inline on the row and detail. */
|
|
12797
|
+
const failed = snapshot.failed ?? EMPTY_FAILED_MAP;
|
|
12798
|
+
const failedInitialized = (0, react.useRef)(false);
|
|
12799
|
+
const failedRef = (0, react.useRef)(void 0);
|
|
12800
|
+
(0, react.useEffect)(() => {
|
|
12801
|
+
const current = snapshot.failed;
|
|
12802
|
+
if (!failedInitialized.current) {
|
|
12803
|
+
failedInitialized.current = true;
|
|
12804
|
+
failedRef.current = current;
|
|
12805
|
+
return;
|
|
12806
|
+
}
|
|
12807
|
+
const previous = failedRef.current;
|
|
12808
|
+
const fresh = [...(current ?? EMPTY_FAILED_MAP).entries()].filter(([id]) => previous === void 0 || !previous.has(id));
|
|
12809
|
+
if (fresh.length > 0) setActionToast(fresh[0][1]);
|
|
12810
|
+
failedRef.current = current;
|
|
12811
|
+
}, [snapshot.failed]);
|
|
12636
12812
|
(0, react.useEffect)(() => {
|
|
12637
12813
|
if (!open) return;
|
|
12638
12814
|
if (selected !== "" && files.some((file) => file.id === selected)) return;
|
|
@@ -12644,25 +12820,44 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12644
12820
|
files,
|
|
12645
12821
|
selected
|
|
12646
12822
|
]);
|
|
12647
|
-
|
|
12648
|
-
if (
|
|
12649
|
-
|
|
12650
|
-
|
|
12823
|
+
const runImportVcs = async () => {
|
|
12824
|
+
if (current === void 0 || importBusy) return;
|
|
12825
|
+
setImportBusy(true);
|
|
12826
|
+
setImportNote(void 0);
|
|
12827
|
+
setImportFailed(false);
|
|
12828
|
+
setImportToast(null);
|
|
12829
|
+
try {
|
|
12830
|
+
const value = await onImportVcs(current, includeUntrackedEnabled());
|
|
12831
|
+
await onRefresh(current);
|
|
12832
|
+
if (!value.detected) setImportNote(t("panel.importNoVcs"));
|
|
12833
|
+
else if (value.imported === 0) setImportToast(t("panel.importNone"));
|
|
12834
|
+
} catch (error) {
|
|
12835
|
+
setImportFailed(true);
|
|
12836
|
+
setImportNote(t("panel.importFailed", { message: error instanceof Error ? error.message : String(error) }));
|
|
12837
|
+
} finally {
|
|
12838
|
+
setImportBusy(false);
|
|
12651
12839
|
}
|
|
12652
|
-
}
|
|
12653
|
-
open,
|
|
12654
|
-
openedCount,
|
|
12655
|
-
snapshot.read,
|
|
12656
|
-
snapshot.error,
|
|
12657
|
-
files.length
|
|
12658
|
-
]);
|
|
12840
|
+
};
|
|
12659
12841
|
const toggleOpen = () => {
|
|
12660
|
-
if (!open) setOpenedCount(files.length);
|
|
12661
12842
|
setOpen((value) => !value);
|
|
12662
12843
|
};
|
|
12844
|
+
(0, react.useEffect)(() => {
|
|
12845
|
+
if (noSession) setOpen(false);
|
|
12846
|
+
}, [noSession]);
|
|
12847
|
+
/** Run the same decision over every current-session file, sequentially. */
|
|
12848
|
+
const runBulk = async (kind) => {
|
|
12849
|
+
setBulkBusy(kind);
|
|
12850
|
+
try {
|
|
12851
|
+
for (const file of files) if (kind === "keep") await onKeep(file.sessionId, file.id);
|
|
12852
|
+
else await onRevert(file.sessionId, file.id);
|
|
12853
|
+
} finally {
|
|
12854
|
+
setBulkBusy(null);
|
|
12855
|
+
}
|
|
12856
|
+
};
|
|
12663
12857
|
const renderEntry = (entry) => (0, react_jsx_runtime.jsx)(PendingFileRow, {
|
|
12664
12858
|
file: entry,
|
|
12665
12859
|
selected: selected === entry.id,
|
|
12860
|
+
failedMessage: failed.get(entry.id),
|
|
12666
12861
|
t,
|
|
12667
12862
|
onSelect: (id) => {
|
|
12668
12863
|
if (id === selected) setJumpSignal((signal) => signal + 1);
|
|
@@ -12670,6 +12865,42 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12670
12865
|
}
|
|
12671
12866
|
}, entry.id);
|
|
12672
12867
|
const selectedFile = files.find((file) => file.id === selected);
|
|
12868
|
+
const handleUndo = async (sessionId) => {
|
|
12869
|
+
const id = await onUndo(sessionId);
|
|
12870
|
+
if (id === void 0) return;
|
|
12871
|
+
if (id === selected) setUndoFlash((signal) => signal + 1);
|
|
12872
|
+
else setSelected(id);
|
|
12873
|
+
};
|
|
12874
|
+
const handleRedo = async (sessionId) => {
|
|
12875
|
+
const id = await onRedo(sessionId);
|
|
12876
|
+
if (id === void 0) return;
|
|
12877
|
+
if (id === selected) setUndoFlash((signal) => signal + 1);
|
|
12878
|
+
else setSelected(id);
|
|
12879
|
+
};
|
|
12880
|
+
(0, react.useEffect)(() => {
|
|
12881
|
+
if (!open || current === void 0) return;
|
|
12882
|
+
const onKeyDown = (event) => {
|
|
12883
|
+
if (!(event.ctrlKey || event.metaKey) || event.altKey) return;
|
|
12884
|
+
const key = event.key.toLowerCase();
|
|
12885
|
+
if (key !== "z" && key !== "y") return;
|
|
12886
|
+
const target = event.target;
|
|
12887
|
+
if (target instanceof Element && target.closest("input, textarea, [contenteditable=\"true\"]") !== null) return;
|
|
12888
|
+
event.preventDefault();
|
|
12889
|
+
if (key === "z") {
|
|
12890
|
+
if (event.shiftKey) handleRedo(current);
|
|
12891
|
+
else handleUndo(current);
|
|
12892
|
+
} else handleRedo(current);
|
|
12893
|
+
};
|
|
12894
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
12895
|
+
return () => {
|
|
12896
|
+
window.removeEventListener("keydown", onKeyDown, true);
|
|
12897
|
+
};
|
|
12898
|
+
}, [
|
|
12899
|
+
open,
|
|
12900
|
+
current,
|
|
12901
|
+
handleUndo,
|
|
12902
|
+
handleRedo
|
|
12903
|
+
]);
|
|
12673
12904
|
/** Drag the list/detail divider; width follows the pointer within its bounds. */
|
|
12674
12905
|
const startResize = (event) => {
|
|
12675
12906
|
if (event.button !== 0) return;
|
|
@@ -12698,127 +12929,333 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12698
12929
|
};
|
|
12699
12930
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
12700
12931
|
className: wide ? PendingPanel_module_css_default.layer : `${PendingPanel_module_css_default.layer} ${PendingPanel_module_css_default.rail}`,
|
|
12701
|
-
children: [
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
|
|
12706
|
-
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12932
|
+
children: [
|
|
12933
|
+
importToast !== null && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
12934
|
+
text: importToast,
|
|
12935
|
+
onDone: () => {
|
|
12936
|
+
setImportToast(null);
|
|
12937
|
+
}
|
|
12938
|
+
}),
|
|
12939
|
+
actionToast !== null && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
12940
|
+
text: actionToast,
|
|
12941
|
+
onDone: () => {
|
|
12942
|
+
setActionToast(null);
|
|
12943
|
+
}
|
|
12944
|
+
}),
|
|
12945
|
+
open && expanded && (0, react_jsx_runtime.jsx)("div", {
|
|
12946
|
+
className: PendingPanel_module_css_default.fullscreenBackdrop,
|
|
12947
|
+
"data-diff-fullscreen-backdrop": true
|
|
12948
|
+
}),
|
|
12949
|
+
open && (0, react_jsx_runtime.jsxs)("section", {
|
|
12950
|
+
className: PendingPanel_module_css_default.panel,
|
|
12951
|
+
style: { bottom: expanded ? PANEL_INSET_PX : bottomPx },
|
|
12952
|
+
"data-diff-approval-panel": true,
|
|
12953
|
+
"aria-label": t("panel.title"),
|
|
12954
|
+
children: [(0, react_jsx_runtime.jsxs)("header", {
|
|
12955
|
+
className: PendingPanel_module_css_default.header,
|
|
12956
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
12957
|
+
className: PendingPanel_module_css_default.title,
|
|
12958
|
+
children: t("panel.title")
|
|
12959
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
12960
|
+
className: PendingPanel_module_css_default.headerActions,
|
|
12961
|
+
children: [
|
|
12962
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12963
|
+
label: t("action.settings"),
|
|
12964
|
+
side: "bottom",
|
|
12965
|
+
delayMs: 500,
|
|
12966
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
12967
|
+
type: "button",
|
|
12968
|
+
className: PendingPanel_module_css_default.expand,
|
|
12969
|
+
"data-diff-approval-settings": true,
|
|
12970
|
+
"aria-label": t("action.settings"),
|
|
12971
|
+
onClick: () => {
|
|
12972
|
+
setOpen(false);
|
|
12973
|
+
openSettingsSection(t("settings.tabLabel"));
|
|
12974
|
+
},
|
|
12975
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSettingsOutline16, { size: 14 })
|
|
12976
|
+
})
|
|
12977
|
+
}),
|
|
12978
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12979
|
+
label: t(expanded ? "action.exitFullscreen" : "action.expand"),
|
|
12980
|
+
side: "bottom",
|
|
12981
|
+
delayMs: 500,
|
|
12982
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
12983
|
+
type: "button",
|
|
12984
|
+
className: expanded ? `${PendingPanel_module_css_default.expand} ${PendingPanel_module_css_default.expandExpanded}` : PendingPanel_module_css_default.expand,
|
|
12985
|
+
"data-diff-approval-expand": true,
|
|
12986
|
+
"aria-label": t(expanded ? "action.exitFullscreen" : "action.expand"),
|
|
12987
|
+
onClick: () => {
|
|
12988
|
+
setExpanded((value) => !value);
|
|
12989
|
+
},
|
|
12990
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutline16, { size: 14 })
|
|
12991
|
+
})
|
|
12992
|
+
}),
|
|
12993
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
12994
|
+
label: t("action.close"),
|
|
12995
|
+
side: "bottom",
|
|
12996
|
+
delayMs: 500,
|
|
12997
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
12998
|
+
type: "button",
|
|
12999
|
+
className: PendingPanel_module_css_default.close,
|
|
13000
|
+
"data-diff-approval-close": true,
|
|
13001
|
+
"aria-label": t("action.close"),
|
|
13002
|
+
onClick: () => {
|
|
13003
|
+
setOpen(false);
|
|
13004
|
+
},
|
|
13005
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
|
|
13006
|
+
})
|
|
13007
|
+
})
|
|
13008
|
+
]
|
|
13009
|
+
})]
|
|
13010
|
+
}), snapshot.error !== void 0 || !snapshot.read || files.length === 0 ? (0, react_jsx_runtime.jsxs)("div", {
|
|
13011
|
+
className: PendingPanel_module_css_default.states,
|
|
13012
|
+
children: [
|
|
13013
|
+
snapshot.error !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
13014
|
+
className: PendingPanel_module_css_default.readError,
|
|
13015
|
+
role: "alert",
|
|
13016
|
+
children: t("panel.readFailed", { message: snapshot.error })
|
|
13017
|
+
}),
|
|
13018
|
+
!snapshot.read && snapshot.error === void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
13019
|
+
className: PendingPanel_module_css_default.note,
|
|
13020
|
+
children: t("panel.loading")
|
|
13021
|
+
}),
|
|
13022
|
+
snapshot.read && snapshot.error === void 0 && files.length === 0 && (0, react_jsx_runtime.jsxs)("div", {
|
|
13023
|
+
className: PendingPanel_module_css_default.emptyState,
|
|
13024
|
+
children: [
|
|
13025
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
13026
|
+
className: `${PendingPanel_module_css_default.note} ${PendingPanel_module_css_default.noteCentered}`,
|
|
13027
|
+
children: t("panel.empty")
|
|
13028
|
+
}),
|
|
13029
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
13030
|
+
type: "button",
|
|
13031
|
+
className: PendingPanel_module_css_default.importButton,
|
|
13032
|
+
"data-diff-import-vcs": true,
|
|
13033
|
+
disabled: importBusy,
|
|
13034
|
+
onClick: () => {
|
|
13035
|
+
runImportVcs();
|
|
13036
|
+
},
|
|
13037
|
+
children: importBusy ? t("action.importVcsBusy") : t("action.importVcs")
|
|
13038
|
+
}),
|
|
13039
|
+
importNote !== void 0 && (0, react_jsx_runtime.jsx)("p", {
|
|
13040
|
+
className: PendingPanel_module_css_default.importNote,
|
|
13041
|
+
role: importFailed ? "alert" : void 0,
|
|
13042
|
+
children: importNote
|
|
13043
|
+
})
|
|
13044
|
+
]
|
|
12726
13045
|
})
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
"data-diff-approval-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12739
|
-
|
|
13046
|
+
]
|
|
13047
|
+
}) : (0, react_jsx_runtime.jsxs)("div", {
|
|
13048
|
+
className: PendingPanel_module_css_default.split,
|
|
13049
|
+
children: [
|
|
13050
|
+
(0, react_jsx_runtime.jsxs)("nav", {
|
|
13051
|
+
className: PendingPanel_module_css_default.fileList,
|
|
13052
|
+
style: { width: listWidth },
|
|
13053
|
+
"data-diff-approval-file-list": true,
|
|
13054
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
13055
|
+
className: PendingPanel_module_css_default.listScroll,
|
|
13056
|
+
children: files.length > 0 && (0, react_jsx_runtime.jsxs)("section", { children: [(0, react_jsx_runtime.jsx)("h3", {
|
|
13057
|
+
className: PendingPanel_module_css_default.group,
|
|
13058
|
+
children: t("panel.group.current")
|
|
13059
|
+
}), (0, react_jsx_runtime.jsx)("ul", {
|
|
13060
|
+
className: PendingPanel_module_css_default.rows,
|
|
13061
|
+
children: files.map(renderEntry)
|
|
13062
|
+
})] })
|
|
13063
|
+
}), files.length > 0 && (0, react_jsx_runtime.jsxs)("div", {
|
|
13064
|
+
className: PendingPanel_module_css_default.bulkActions,
|
|
13065
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
13066
|
+
type: "button",
|
|
13067
|
+
className: `${PendingPanel_module_css_default.action} ${PendingPanel_module_css_default.actionPrimary}`,
|
|
13068
|
+
"data-diff-keep-all": true,
|
|
13069
|
+
disabled: bulkBusy !== null,
|
|
13070
|
+
onClick: () => {
|
|
13071
|
+
runBulk("keep");
|
|
13072
|
+
},
|
|
13073
|
+
children: bulkBusy === "keep" ? t("action.busy") : t("action.keepAll")
|
|
13074
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
13075
|
+
type: "button",
|
|
13076
|
+
className: PendingPanel_module_css_default.action,
|
|
13077
|
+
"data-diff-revert-all": true,
|
|
13078
|
+
disabled: bulkBusy !== null,
|
|
13079
|
+
onClick: () => {
|
|
13080
|
+
runBulk("revert");
|
|
13081
|
+
},
|
|
13082
|
+
children: bulkBusy === "revert" ? t("action.busy") : t("action.revertAll")
|
|
13083
|
+
})]
|
|
13084
|
+
})]
|
|
13085
|
+
}),
|
|
13086
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
13087
|
+
className: PendingPanel_module_css_default.resizeHandle,
|
|
13088
|
+
"data-diff-resize": true,
|
|
13089
|
+
onMouseDown: startResize
|
|
13090
|
+
}),
|
|
13091
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
13092
|
+
className: PendingPanel_module_css_default.detail,
|
|
13093
|
+
children: selectedFile === void 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
13094
|
+
className: PendingPanel_module_css_default.detailEmpty,
|
|
13095
|
+
children: t("panel.selectHint")
|
|
13096
|
+
}) : (0, react_jsx_runtime.jsx)(PendingDiff, {
|
|
13097
|
+
file: selectedFile,
|
|
13098
|
+
busy: snapshot.busy.has(selectedFile.id),
|
|
13099
|
+
workspacePath: snapshot.workspacePath,
|
|
13100
|
+
jumpSignal,
|
|
13101
|
+
undoFlash,
|
|
13102
|
+
failedMessage: failed.get(selectedFile.id),
|
|
13103
|
+
onPasteReference,
|
|
13104
|
+
t,
|
|
13105
|
+
onKeep,
|
|
13106
|
+
onRevert,
|
|
13107
|
+
onBlockKeep,
|
|
13108
|
+
onBlockRevert,
|
|
13109
|
+
onOpen
|
|
13110
|
+
})
|
|
12740
13111
|
})
|
|
12741
|
-
|
|
13112
|
+
]
|
|
12742
13113
|
})]
|
|
12743
|
-
}),
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
className: PendingPanel_module_css_default.fileList,
|
|
12765
|
-
style: { width: listWidth },
|
|
12766
|
-
"data-diff-approval-file-list": true,
|
|
12767
|
-
children: files.length > 0 && (0, react_jsx_runtime.jsxs)("section", { children: [(0, react_jsx_runtime.jsx)("h3", {
|
|
12768
|
-
className: PendingPanel_module_css_default.group,
|
|
12769
|
-
children: t("panel.group.current")
|
|
12770
|
-
}), (0, react_jsx_runtime.jsx)("ul", {
|
|
12771
|
-
className: PendingPanel_module_css_default.rows,
|
|
12772
|
-
children: files.map(renderEntry)
|
|
12773
|
-
})] })
|
|
12774
|
-
}),
|
|
12775
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
12776
|
-
className: PendingPanel_module_css_default.resizeHandle,
|
|
12777
|
-
"data-diff-resize": true,
|
|
12778
|
-
onMouseDown: startResize
|
|
12779
|
-
}),
|
|
12780
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
12781
|
-
className: PendingPanel_module_css_default.detail,
|
|
12782
|
-
children: selectedFile === void 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
12783
|
-
className: PendingPanel_module_css_default.detailEmpty,
|
|
12784
|
-
children: t("panel.selectHint")
|
|
12785
|
-
}) : (0, react_jsx_runtime.jsx)(PendingDiff, {
|
|
12786
|
-
file: selectedFile,
|
|
12787
|
-
busy: snapshot.busy.has(selectedFile.id),
|
|
12788
|
-
workspacePath: snapshot.workspacePath,
|
|
12789
|
-
jumpSignal,
|
|
12790
|
-
t,
|
|
12791
|
-
onKeep,
|
|
12792
|
-
onRevert,
|
|
12793
|
-
onBlockKeep,
|
|
12794
|
-
onBlockRevert,
|
|
12795
|
-
onOpen
|
|
13114
|
+
}),
|
|
13115
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
13116
|
+
className: PendingPanel_module_css_default.footerButtons,
|
|
13117
|
+
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
13118
|
+
type: "button",
|
|
13119
|
+
className: noSession ? `${PendingPanel_module_css_default.badge} ${PendingPanel_module_css_default.badgeDisabled}` : PendingPanel_module_css_default.badge,
|
|
13120
|
+
"data-diff-approval-badge": files.length,
|
|
13121
|
+
"data-active": open ? "" : void 0,
|
|
13122
|
+
"aria-label": t("panel.aria"),
|
|
13123
|
+
"aria-expanded": open,
|
|
13124
|
+
disabled: noSession,
|
|
13125
|
+
onClick: toggleOpen,
|
|
13126
|
+
children: [
|
|
13127
|
+
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconListPenOutline16, { size: wide ? 16 : 18 }),
|
|
13128
|
+
wide && (0, react_jsx_runtime.jsx)("span", {
|
|
13129
|
+
className: PendingPanel_module_css_default.badgeLabel,
|
|
13130
|
+
children: t("panel.aria")
|
|
13131
|
+
}),
|
|
13132
|
+
(wide || files.length > 0) && (0, react_jsx_runtime.jsx)("span", {
|
|
13133
|
+
className: PendingPanel_module_css_default.badgeCount,
|
|
13134
|
+
children: files.length
|
|
12796
13135
|
})
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
})
|
|
12800
|
-
|
|
12801
|
-
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
|
|
12807
|
-
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12811
|
-
(
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
(wide || files.length > 0) && (0, react_jsx_runtime.jsx)("span", {
|
|
12817
|
-
className: PendingPanel_module_css_default.badgeCount,
|
|
12818
|
-
children: files.length
|
|
12819
|
-
})
|
|
12820
|
-
]
|
|
13136
|
+
]
|
|
13137
|
+
})
|
|
13138
|
+
}),
|
|
13139
|
+
redoClearedNotice && (0, react_jsx_runtime.jsxs)("div", {
|
|
13140
|
+
className: PendingPanel_module_css_default.notice,
|
|
13141
|
+
role: "status",
|
|
13142
|
+
"data-diff-approval-notice": true,
|
|
13143
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
13144
|
+
className: PendingPanel_module_css_default.noticeText,
|
|
13145
|
+
children: t("panel.externalChanged")
|
|
13146
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
13147
|
+
type: "button",
|
|
13148
|
+
className: PendingPanel_module_css_default.noticeButton,
|
|
13149
|
+
"data-diff-notice-dismiss": true,
|
|
13150
|
+
onClick: () => {
|
|
13151
|
+
setRedoClearedNotice(false);
|
|
13152
|
+
},
|
|
13153
|
+
children: t("panel.dismiss")
|
|
13154
|
+
})]
|
|
12821
13155
|
})
|
|
13156
|
+
]
|
|
13157
|
+
});
|
|
13158
|
+
}
|
|
13159
|
+
//#endregion
|
|
13160
|
+
//#region lib/types/client/SettingsTab.js
|
|
13161
|
+
/** DSH Settings top-level section for this plugin's preferences. */
|
|
13162
|
+
/** A pill picker offering the two boolean states 打开 / 关闭. */
|
|
13163
|
+
function OnOffPicker({ value, open, onOpenChange, onSelect, dataAttribute, t }) {
|
|
13164
|
+
return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
13165
|
+
open,
|
|
13166
|
+
onClose: () => {
|
|
13167
|
+
onOpenChange(false);
|
|
13168
|
+
},
|
|
13169
|
+
items: [{
|
|
13170
|
+
id: "on",
|
|
13171
|
+
label: t("action.toggleOn")
|
|
13172
|
+
}, {
|
|
13173
|
+
id: "off",
|
|
13174
|
+
label: t("action.toggleOff")
|
|
13175
|
+
}],
|
|
13176
|
+
selectedId: value ? "on" : "off",
|
|
13177
|
+
onSelect: (id) => {
|
|
13178
|
+
onOpenChange(false);
|
|
13179
|
+
onSelect(id === "on");
|
|
13180
|
+
},
|
|
13181
|
+
align: "end",
|
|
13182
|
+
portal: true,
|
|
13183
|
+
anchor: (0, react_jsx_runtime.jsxs)("button", {
|
|
13184
|
+
type: "button",
|
|
13185
|
+
className: PendingPanel_module_css_default.settingsSelector,
|
|
13186
|
+
"aria-haspopup": "menu",
|
|
13187
|
+
"aria-expanded": open,
|
|
13188
|
+
onClick: () => {
|
|
13189
|
+
onOpenChange(!open);
|
|
13190
|
+
},
|
|
13191
|
+
[dataAttribute]: true,
|
|
13192
|
+
children: [value ? t("action.toggleOn") : t("action.toggleOff"), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: PendingPanel_module_css_default.settingsSelectorChevron })]
|
|
13193
|
+
})
|
|
13194
|
+
});
|
|
13195
|
+
}
|
|
13196
|
+
/** One Agent-preset-style preference row: title + description, pill picker right. */
|
|
13197
|
+
function PreferenceRow({ title, description, value, open, onOpenChange, onSelect, dataAttribute, t }) {
|
|
13198
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
13199
|
+
className: PendingPanel_module_css_default.settingsRow,
|
|
13200
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
13201
|
+
className: PendingPanel_module_css_default.settingsRowText,
|
|
13202
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
13203
|
+
className: PendingPanel_module_css_default.settingsRowTitle,
|
|
13204
|
+
children: title
|
|
13205
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
13206
|
+
className: PendingPanel_module_css_default.settingsRowDesc,
|
|
13207
|
+
children: description
|
|
13208
|
+
})]
|
|
13209
|
+
}), (0, react_jsx_runtime.jsx)(OnOffPicker, {
|
|
13210
|
+
value,
|
|
13211
|
+
open,
|
|
13212
|
+
onOpenChange,
|
|
13213
|
+
onSelect,
|
|
13214
|
+
dataAttribute,
|
|
13215
|
+
t
|
|
13216
|
+
})]
|
|
13217
|
+
});
|
|
13218
|
+
}
|
|
13219
|
+
/**
|
|
13220
|
+
* The plugin's preferences: auto-paste a copied reference into the input, and
|
|
13221
|
+
* whether importing workspace VCS changes includes untracked files. Each row
|
|
13222
|
+
* mirrors the harness's Agent-preset row (title + description on the left, a
|
|
13223
|
+
* pill picker on the right) with the two boolean states 打开 / 关闭.
|
|
13224
|
+
*/
|
|
13225
|
+
function DiffApprovalSettingsTab({ t }) {
|
|
13226
|
+
const [pasteOnCopy, setPasteOnCopyState] = (0, react.useState)(pasteOnCopyEnabled);
|
|
13227
|
+
const [pasteOnCopyOpen, setPasteOnCopyOpen] = (0, react.useState)(false);
|
|
13228
|
+
const [includeUntracked, setIncludeUntrackedState] = (0, react.useState)(includeUntrackedEnabled);
|
|
13229
|
+
const [includeUntrackedOpen, setIncludeUntrackedOpen] = (0, react.useState)(false);
|
|
13230
|
+
const setPasteOnCopy = (value) => {
|
|
13231
|
+
setPasteOnCopyState(value);
|
|
13232
|
+
setPasteOnCopyEnabled(value);
|
|
13233
|
+
};
|
|
13234
|
+
const setIncludeUntracked = (value) => {
|
|
13235
|
+
setIncludeUntrackedState(value);
|
|
13236
|
+
setIncludeUntrackedEnabled(value);
|
|
13237
|
+
};
|
|
13238
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
13239
|
+
className: PendingPanel_module_css_default.settingsPage,
|
|
13240
|
+
"data-diff-settings": true,
|
|
13241
|
+
children: [(0, react_jsx_runtime.jsx)(PreferenceRow, {
|
|
13242
|
+
title: t("panel.pasteOnCopy"),
|
|
13243
|
+
description: t("panel.pasteOnCopyDesc"),
|
|
13244
|
+
value: pasteOnCopy,
|
|
13245
|
+
open: pasteOnCopyOpen,
|
|
13246
|
+
onOpenChange: setPasteOnCopyOpen,
|
|
13247
|
+
onSelect: setPasteOnCopy,
|
|
13248
|
+
dataAttribute: "data-diff-paste-on-copy-select",
|
|
13249
|
+
t
|
|
13250
|
+
}), (0, react_jsx_runtime.jsx)(PreferenceRow, {
|
|
13251
|
+
title: t("panel.importUntracked"),
|
|
13252
|
+
description: t("panel.importUntrackedDesc"),
|
|
13253
|
+
value: includeUntracked,
|
|
13254
|
+
open: includeUntrackedOpen,
|
|
13255
|
+
onOpenChange: setIncludeUntrackedOpen,
|
|
13256
|
+
onSelect: setIncludeUntracked,
|
|
13257
|
+
dataAttribute: "data-diff-import-untracked-select",
|
|
13258
|
+
t
|
|
12822
13259
|
})]
|
|
12823
13260
|
});
|
|
12824
13261
|
}
|
|
@@ -12867,6 +13304,18 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12867
13304
|
block
|
|
12868
13305
|
}));
|
|
12869
13306
|
},
|
|
13307
|
+
async undo(sessionId) {
|
|
13308
|
+
return actionOf(await rpc.call(DIFF_APPROVAL_CHANNEL, "undo", { sessionId }));
|
|
13309
|
+
},
|
|
13310
|
+
async redo(sessionId) {
|
|
13311
|
+
return actionOf(await rpc.call(DIFF_APPROVAL_CHANNEL, "redo", { sessionId }));
|
|
13312
|
+
},
|
|
13313
|
+
async importVcs(sessionId, includeUntracked) {
|
|
13314
|
+
return importValueOf(await rpc.call(DIFF_APPROVAL_CHANNEL, "vcs-import", {
|
|
13315
|
+
sessionId,
|
|
13316
|
+
includeUntracked
|
|
13317
|
+
}));
|
|
13318
|
+
},
|
|
12870
13319
|
async open(sessionId, id, action) {
|
|
12871
13320
|
return openOf(await rpc.call(DIFF_APPROVAL_CHANNEL, "open", {
|
|
12872
13321
|
sessionId,
|
|
@@ -12912,7 +13361,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12912
13361
|
const file = pendingFileOf(row);
|
|
12913
13362
|
if (file !== void 0) files.push(file);
|
|
12914
13363
|
}
|
|
12915
|
-
return {
|
|
13364
|
+
return value.redoCleared === true ? {
|
|
13365
|
+
files,
|
|
13366
|
+
workspacePath,
|
|
13367
|
+
redoCleared: true
|
|
13368
|
+
} : {
|
|
12916
13369
|
files,
|
|
12917
13370
|
workspacePath
|
|
12918
13371
|
};
|
|
@@ -12923,8 +13376,25 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12923
13376
|
const value = result.value;
|
|
12924
13377
|
if (typeof value !== "object" || value === null) throw new Error("the action returned a malformed value");
|
|
12925
13378
|
const outcome = value.outcome;
|
|
12926
|
-
if (outcome !== "kept" && outcome !== "reverted" && outcome !== "missing") throw new Error("the action returned a malformed outcome");
|
|
12927
|
-
|
|
13379
|
+
if (outcome !== "kept" && outcome !== "reverted" && outcome !== "missing" && outcome !== "undone" && outcome !== "redone" && outcome !== "nothing") throw new Error("the action returned a malformed outcome");
|
|
13380
|
+
const id = value.id;
|
|
13381
|
+
return {
|
|
13382
|
+
outcome,
|
|
13383
|
+
id: typeof id === "string" && id.length > 0 ? id : void 0
|
|
13384
|
+
};
|
|
13385
|
+
}
|
|
13386
|
+
/** Narrow the vcs-import endpoint's value; a malformed wire value is a failure. */
|
|
13387
|
+
function importValueOf(result) {
|
|
13388
|
+
if (!result.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
|
|
13389
|
+
const value = result.value;
|
|
13390
|
+
if (typeof value !== "object" || value === null) throw new Error("the import returned a malformed value");
|
|
13391
|
+
const imported = value.imported;
|
|
13392
|
+
const detected = value.detected;
|
|
13393
|
+
if (typeof imported !== "number" || typeof detected !== "boolean") throw new Error("the import returned a malformed value");
|
|
13394
|
+
return {
|
|
13395
|
+
imported,
|
|
13396
|
+
detected
|
|
13397
|
+
};
|
|
12928
13398
|
}
|
|
12929
13399
|
/** Narrow the open endpoint's value; a malformed wire value is an open failure. */
|
|
12930
13400
|
function openOf(result) {
|
|
@@ -12946,6 +13416,10 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12946
13416
|
*/
|
|
12947
13417
|
/** An empty busy set reused as the snapshot's canonical absent value. */
|
|
12948
13418
|
const EMPTY_BUSY = /* @__PURE__ */ new Set();
|
|
13419
|
+
/** An empty failure map reused as the snapshot's canonical absent value. */
|
|
13420
|
+
const EMPTY_FAILED = /* @__PURE__ */ new Map();
|
|
13421
|
+
/** How long a failed keep/revert hint stays visible before it auto-clears. */
|
|
13422
|
+
const FAILED_HINT_MS = 5e3;
|
|
12949
13423
|
/**
|
|
12950
13424
|
* Create the store over the review-channel port.
|
|
12951
13425
|
* @param port - the typed channel port.
|
|
@@ -12958,26 +13432,59 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12958
13432
|
busy: EMPTY_BUSY
|
|
12959
13433
|
};
|
|
12960
13434
|
const listeners = /* @__PURE__ */ new Set();
|
|
13435
|
+
let redoCleared = false;
|
|
12961
13436
|
const publish = (next) => {
|
|
12962
|
-
snapshot =
|
|
13437
|
+
snapshot = redoCleared ? {
|
|
13438
|
+
...next,
|
|
13439
|
+
redoCleared: true
|
|
13440
|
+
} : next;
|
|
12963
13441
|
for (const listener of [...listeners]) listener();
|
|
12964
13442
|
};
|
|
13443
|
+
const failedOf = (value) => value.failed ?? EMPTY_FAILED;
|
|
13444
|
+
/** Record one entry's failed keep/revert with its message; auto-clears after a few seconds. */
|
|
13445
|
+
const markFailed = (id, message) => {
|
|
13446
|
+
publish({
|
|
13447
|
+
...snapshot,
|
|
13448
|
+
failed: new Map([...failedOf(snapshot), [id, message]])
|
|
13449
|
+
});
|
|
13450
|
+
window.setTimeout(() => {
|
|
13451
|
+
if (failedOf(snapshot).get(id) !== message) return;
|
|
13452
|
+
const next = new Map(failedOf(snapshot));
|
|
13453
|
+
next.delete(id);
|
|
13454
|
+
publish({
|
|
13455
|
+
...snapshot,
|
|
13456
|
+
failed: next
|
|
13457
|
+
});
|
|
13458
|
+
}, FAILED_HINT_MS);
|
|
13459
|
+
};
|
|
13460
|
+
/** Drop one entry's failure marker after a successful retry. */
|
|
13461
|
+
const clearFailed = (id) => {
|
|
13462
|
+
if (!failedOf(snapshot).has(id)) return;
|
|
13463
|
+
const next = new Map(failedOf(snapshot));
|
|
13464
|
+
next.delete(id);
|
|
13465
|
+
publish({
|
|
13466
|
+
...snapshot,
|
|
13467
|
+
failed: next
|
|
13468
|
+
});
|
|
13469
|
+
};
|
|
12965
13470
|
const withBusy = async (id, action) => {
|
|
12966
13471
|
const { error: _cleared, ...base } = snapshot;
|
|
12967
13472
|
publish({
|
|
12968
13473
|
...base,
|
|
13474
|
+
failed: failedOf(snapshot),
|
|
12969
13475
|
busy: /* @__PURE__ */ new Set([...snapshot.busy, id])
|
|
12970
13476
|
});
|
|
12971
13477
|
try {
|
|
12972
13478
|
await action();
|
|
12973
13479
|
} catch (error) {
|
|
13480
|
+
markFailed(id, error instanceof Error ? error.message : String(error));
|
|
12974
13481
|
publish({
|
|
12975
13482
|
...snapshot,
|
|
12976
|
-
error: error instanceof Error ? error.message : String(error),
|
|
12977
13483
|
busy: new Set([...snapshot.busy].filter((busy) => busy !== id))
|
|
12978
13484
|
});
|
|
12979
13485
|
return;
|
|
12980
13486
|
}
|
|
13487
|
+
clearFailed(id);
|
|
12981
13488
|
publish({
|
|
12982
13489
|
...snapshot,
|
|
12983
13490
|
files: snapshot.files.filter((file) => file.id !== id),
|
|
@@ -12997,17 +13504,20 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
12997
13504
|
publish({
|
|
12998
13505
|
read: true,
|
|
12999
13506
|
files: [],
|
|
13000
|
-
busy: EMPTY_BUSY
|
|
13507
|
+
busy: EMPTY_BUSY,
|
|
13508
|
+
failed: failedOf(snapshot)
|
|
13001
13509
|
});
|
|
13002
13510
|
return;
|
|
13003
13511
|
}
|
|
13004
13512
|
try {
|
|
13005
|
-
const { files, workspacePath } = await port.list(sessionId);
|
|
13513
|
+
const { files, workspacePath, redoCleared: cleared } = await port.list(sessionId);
|
|
13514
|
+
if (cleared) redoCleared = true;
|
|
13006
13515
|
publish({
|
|
13007
13516
|
read: true,
|
|
13008
13517
|
files,
|
|
13009
13518
|
workspacePath,
|
|
13010
|
-
busy: EMPTY_BUSY
|
|
13519
|
+
busy: EMPTY_BUSY,
|
|
13520
|
+
failed: failedOf(snapshot)
|
|
13011
13521
|
});
|
|
13012
13522
|
} catch (error) {
|
|
13013
13523
|
publish({
|
|
@@ -13015,7 +13525,8 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13015
13525
|
files: snapshot.files,
|
|
13016
13526
|
workspacePath: snapshot.workspacePath,
|
|
13017
13527
|
error: error instanceof Error ? error.message : String(error),
|
|
13018
|
-
busy: snapshot.busy
|
|
13528
|
+
busy: snapshot.busy,
|
|
13529
|
+
failed: failedOf(snapshot)
|
|
13019
13530
|
});
|
|
13020
13531
|
}
|
|
13021
13532
|
},
|
|
@@ -13038,13 +13549,14 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13038
13549
|
try {
|
|
13039
13550
|
await port.blockKeep(sessionId, id, block);
|
|
13040
13551
|
} catch (error) {
|
|
13552
|
+
markFailed(id, error instanceof Error ? error.message : String(error));
|
|
13041
13553
|
publish({
|
|
13042
13554
|
...snapshot,
|
|
13043
|
-
error: error instanceof Error ? error.message : String(error),
|
|
13044
13555
|
busy: new Set([...snapshot.busy].filter((busy) => busy !== id))
|
|
13045
13556
|
});
|
|
13046
13557
|
return;
|
|
13047
13558
|
}
|
|
13559
|
+
clearFailed(id);
|
|
13048
13560
|
await this.refresh(sessionId);
|
|
13049
13561
|
},
|
|
13050
13562
|
async blockRevert(sessionId, id, block) {
|
|
@@ -13056,15 +13568,41 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13056
13568
|
try {
|
|
13057
13569
|
await port.blockRevert(sessionId, id, block);
|
|
13058
13570
|
} catch (error) {
|
|
13571
|
+
markFailed(id, error instanceof Error ? error.message : String(error));
|
|
13059
13572
|
publish({
|
|
13060
13573
|
...snapshot,
|
|
13061
|
-
error: error instanceof Error ? error.message : String(error),
|
|
13062
13574
|
busy: new Set([...snapshot.busy].filter((busy) => busy !== id))
|
|
13063
13575
|
});
|
|
13064
13576
|
return;
|
|
13065
13577
|
}
|
|
13578
|
+
clearFailed(id);
|
|
13066
13579
|
await this.refresh(sessionId);
|
|
13067
13580
|
},
|
|
13581
|
+
async undo(sessionId) {
|
|
13582
|
+
try {
|
|
13583
|
+
const value = await port.undo(sessionId);
|
|
13584
|
+
await this.refresh(sessionId);
|
|
13585
|
+
const id = value.id;
|
|
13586
|
+
return id !== void 0 && snapshot.files.some((file) => file.id === id) ? id : void 0;
|
|
13587
|
+
} catch {
|
|
13588
|
+
return;
|
|
13589
|
+
}
|
|
13590
|
+
},
|
|
13591
|
+
async redo(sessionId) {
|
|
13592
|
+
try {
|
|
13593
|
+
const value = await port.redo(sessionId);
|
|
13594
|
+
await this.refresh(sessionId);
|
|
13595
|
+
const id = value.id;
|
|
13596
|
+
return id !== void 0 && snapshot.files.some((file) => file.id === id) ? id : void 0;
|
|
13597
|
+
} catch {
|
|
13598
|
+
return;
|
|
13599
|
+
}
|
|
13600
|
+
},
|
|
13601
|
+
async importVcs(sessionId, includeUntracked) {
|
|
13602
|
+
const value = await port.importVcs(sessionId, includeUntracked);
|
|
13603
|
+
await this.refresh(sessionId);
|
|
13604
|
+
return value;
|
|
13605
|
+
},
|
|
13068
13606
|
async open(sessionId, id, action) {
|
|
13069
13607
|
try {
|
|
13070
13608
|
await port.open(sessionId, id, action);
|
|
@@ -13081,6 +13619,11 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13081
13619
|
files: [],
|
|
13082
13620
|
busy: EMPTY_BUSY
|
|
13083
13621
|
});
|
|
13622
|
+
},
|
|
13623
|
+
clearRedoCleared() {
|
|
13624
|
+
redoCleared = false;
|
|
13625
|
+
const { redoCleared: _omit, ...rest } = snapshot;
|
|
13626
|
+
publish(rest);
|
|
13084
13627
|
}
|
|
13085
13628
|
};
|
|
13086
13629
|
}
|
|
@@ -13103,12 +13646,22 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13103
13646
|
"panel.searchPlaceholder": "搜索",
|
|
13104
13647
|
"panel.missing": "文件已不存在",
|
|
13105
13648
|
"panel.missingHint": "该文件已不存在,回退会恢复该文件。",
|
|
13649
|
+
"panel.externalChanged": "检测到文件在外部被修改,已更新对比并新建撤销点;重做历史已被重置。",
|
|
13650
|
+
"panel.dismiss": "知道了",
|
|
13106
13651
|
"panel.createHint": "回退会删除该新建的文件。",
|
|
13652
|
+
"panel.pasteOnCopy": "复制引用后自动粘贴到消息输入框",
|
|
13653
|
+
"panel.pasteOnCopyDesc": "开启后,复制的引用会自动填入消息输入框,输入框会获得焦点。",
|
|
13654
|
+
"panel.importUntracked": "导入未跟踪的文件改动",
|
|
13655
|
+
"panel.importUntrackedDesc": "开启后,导入工作区改动会包含未跟踪/未版本化的新增文件(Git 未跟踪、SVN 未版本化、Perforce 未版本化)。收集改动需要扫描整个工作区,文件数量大时可能较慢。",
|
|
13656
|
+
"settings.tabLabel": "改动审批",
|
|
13107
13657
|
"row.create": "新增文件",
|
|
13658
|
+
"row.failed": "失败",
|
|
13108
13659
|
"row.added": "+{added}",
|
|
13109
13660
|
"row.removed": "-{removed}",
|
|
13110
13661
|
"action.keep": "保留",
|
|
13111
13662
|
"action.revert": "回退",
|
|
13663
|
+
"action.keepAll": "全部保留",
|
|
13664
|
+
"action.revertAll": "全部回退",
|
|
13112
13665
|
"action.openFile": "打开文件",
|
|
13113
13666
|
"action.revealFile": "打开所在目录",
|
|
13114
13667
|
"action.busy": "处理中…",
|
|
@@ -13119,7 +13672,16 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13119
13672
|
"action.langAuto": "自动",
|
|
13120
13673
|
"action.langAutoDetected": "自动:{lang}",
|
|
13121
13674
|
"action.langSelect": "高亮语言",
|
|
13675
|
+
"action.toggleOn": "打开",
|
|
13676
|
+
"action.toggleOff": "关闭",
|
|
13677
|
+
"action.importVcs": "导入工作区改动",
|
|
13678
|
+
"action.importVcsBusy": "导入中…",
|
|
13679
|
+
"panel.importNone": "没有可导入的改动",
|
|
13680
|
+
"panel.importDone": "已导入 {count} 个改动",
|
|
13681
|
+
"panel.importNoVcs": "未检测到版本控制(Git / SVN / Perforce)",
|
|
13682
|
+
"panel.importFailed": "导入失败:{message}",
|
|
13122
13683
|
"action.search": "搜索 (Ctrl+F)",
|
|
13684
|
+
"action.settings": "设置",
|
|
13123
13685
|
"action.expand": "展开全屏",
|
|
13124
13686
|
"action.exitFullscreen": "退出全屏",
|
|
13125
13687
|
"action.close": "关闭",
|
|
@@ -13142,12 +13704,22 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13142
13704
|
"panel.searchPlaceholder": "Search",
|
|
13143
13705
|
"panel.missing": "File is gone",
|
|
13144
13706
|
"panel.missingHint": "This file no longer exists; reverting restores it.",
|
|
13707
|
+
"panel.externalChanged": "A file changed outside the review. The comparison was updated and a new undo point created; the redo history was reset.",
|
|
13708
|
+
"panel.dismiss": "Got it",
|
|
13145
13709
|
"panel.createHint": "Reverting removes this created file.",
|
|
13710
|
+
"panel.pasteOnCopy": "Paste the copied reference into the composer",
|
|
13711
|
+
"panel.pasteOnCopyDesc": "When enabled, a copied reference is pasted into the composer, which then receives focus.",
|
|
13712
|
+
"panel.importUntracked": "Import changes to untracked files",
|
|
13713
|
+
"panel.importUntrackedDesc": "When enabled, importing workspace changes includes new/untracked files (Git-untracked, SVN-unversioned, Perforce-unversioned). Collecting changes scans the whole workspace, which can be slow on large trees.",
|
|
13714
|
+
"settings.tabLabel": "Diff Approval",
|
|
13146
13715
|
"row.create": "New file",
|
|
13716
|
+
"row.failed": "Failed",
|
|
13147
13717
|
"row.added": "+{added}",
|
|
13148
13718
|
"row.removed": "-{removed}",
|
|
13149
13719
|
"action.keep": "Keep",
|
|
13150
13720
|
"action.revert": "Revert",
|
|
13721
|
+
"action.keepAll": "Keep all",
|
|
13722
|
+
"action.revertAll": "Revert all",
|
|
13151
13723
|
"action.openFile": "Open file",
|
|
13152
13724
|
"action.revealFile": "Reveal in folder",
|
|
13153
13725
|
"action.busy": "Working…",
|
|
@@ -13158,7 +13730,16 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13158
13730
|
"action.langAuto": "Auto",
|
|
13159
13731
|
"action.langAutoDetected": "Auto: {lang}",
|
|
13160
13732
|
"action.langSelect": "Highlight language",
|
|
13733
|
+
"action.toggleOn": "On",
|
|
13734
|
+
"action.toggleOff": "Off",
|
|
13735
|
+
"action.importVcs": "Import workspace changes",
|
|
13736
|
+
"action.importVcsBusy": "Importing…",
|
|
13737
|
+
"panel.importNone": "No changes to import",
|
|
13738
|
+
"panel.importDone": "Imported {count} changes",
|
|
13739
|
+
"panel.importNoVcs": "No version control detected (Git / SVN / Perforce)",
|
|
13740
|
+
"panel.importFailed": "Import failed: {message}",
|
|
13161
13741
|
"action.search": "Search (Ctrl+F)",
|
|
13742
|
+
"action.settings": "Settings",
|
|
13162
13743
|
"action.expand": "Expand fullscreen",
|
|
13163
13744
|
"action.exitFullscreen": "Exit fullscreen",
|
|
13164
13745
|
"action.close": "Close",
|
|
@@ -13185,6 +13766,7 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13185
13766
|
zh,
|
|
13186
13767
|
en
|
|
13187
13768
|
}), "ui-diff-approval: dictionaries");
|
|
13769
|
+
const t = ctx.locale.bind(NS);
|
|
13188
13770
|
const store = createPendingDiffStore(createDiffApprovalPort(ctx.get("connection").rpc));
|
|
13189
13771
|
ctx.on("connection/reset", () => {
|
|
13190
13772
|
store.reset();
|
|
@@ -13202,9 +13784,30 @@ XID_Start XIDS`.split(/\s/).map((p) => [w(p), p]));
|
|
|
13202
13784
|
onRevert: (sessionId, path) => store.revert(sessionId, path),
|
|
13203
13785
|
onBlockKeep: (sessionId, id, block) => store.blockKeep(sessionId, id, block),
|
|
13204
13786
|
onBlockRevert: (sessionId, id, block) => store.blockRevert(sessionId, id, block),
|
|
13205
|
-
onOpen: (sessionId, id, action) => store.open(sessionId, id, action)
|
|
13787
|
+
onOpen: (sessionId, id, action) => store.open(sessionId, id, action),
|
|
13788
|
+
onUndo: (sessionId) => store.undo(sessionId),
|
|
13789
|
+
onRedo: (sessionId) => store.redo(sessionId),
|
|
13790
|
+
onImportVcs: (sessionId, includeUntracked) => store.importVcs(sessionId, includeUntracked),
|
|
13791
|
+
onAckRedoCleared: () => store.clearRedoCleared(),
|
|
13792
|
+
onPasteReference: (sessionId, reference) => {
|
|
13793
|
+
const actx = ctx.get("sessions")?.scope(sessionId);
|
|
13794
|
+
if (actx === void 0) return;
|
|
13795
|
+
const conversation = actx.get("conversation");
|
|
13796
|
+
if (conversation?.input === void 0) return;
|
|
13797
|
+
const textarea = document.querySelector("[data-composer-card] textarea");
|
|
13798
|
+
const base = textarea?.value ?? "";
|
|
13799
|
+
conversation.input.for(actx).setDraft(base === "" ? reference : `${base} ${reference}`);
|
|
13800
|
+
textarea?.focus();
|
|
13801
|
+
}
|
|
13206
13802
|
})
|
|
13207
13803
|
}, PendingPanel));
|
|
13804
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
13805
|
+
name: "settings.section",
|
|
13806
|
+
id: "diff-approval",
|
|
13807
|
+
order: 100,
|
|
13808
|
+
label: () => t("settings.tabLabel"),
|
|
13809
|
+
locale: NS
|
|
13810
|
+
}, DiffApprovalSettingsTab));
|
|
13208
13811
|
}
|
|
13209
13812
|
//#endregion
|
|
13210
13813
|
exports.DIFF_APPROVAL_CHANNEL = DIFF_APPROVAL_CHANNEL;
|