@kud/gh-ink 0.61.3 → 0.62.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +49 -2
- package/dist/index.js +158 -69
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -242,7 +242,54 @@ type PrRowProps = {
|
|
|
242
242
|
motion?: RowMotion;
|
|
243
243
|
/** In order, left to right. Charged against the width budget either way. */
|
|
244
244
|
announcements?: readonly RowAnnouncement[];
|
|
245
|
+
/**
|
|
246
|
+
* The trailing columns' widths across the section — see `trailingColumnsOf`.
|
|
247
|
+
* Absent, the row measures itself, which aligns nothing but draws the same
|
|
248
|
+
* cells a host that never measured always got.
|
|
249
|
+
*/
|
|
250
|
+
columns?: TrailingColumns;
|
|
251
|
+
/** Trailing columns the section has given up — see `sectionShedOf`. */
|
|
252
|
+
shed?: TrailingShed;
|
|
245
253
|
};
|
|
254
|
+
/**
|
|
255
|
+
* The trailing block, in reading order: how contested, how big, how recent.
|
|
256
|
+
* Threads lead because they are the one cell that makes a claim on you; age
|
|
257
|
+
* ends the row so every row ends on the date.
|
|
258
|
+
*/
|
|
259
|
+
declare const TRAILING: readonly ["threads", "size", "age"];
|
|
260
|
+
/** Width of each trailing column, in terminal cells. Zero draws no column. */
|
|
261
|
+
type TrailingColumns = Record<(typeof TRAILING)[number], number>;
|
|
262
|
+
/** Which trailing columns a whole section has given up. */
|
|
263
|
+
type TrailingShed = Partial<Record<(typeof TRAILING)[number], boolean>>;
|
|
264
|
+
/**
|
|
265
|
+
* The widest value each trailing column holds across these rows, measured once
|
|
266
|
+
* by the list — the same move as `uniformLabels` and `markerCols`. It is what
|
|
267
|
+
* makes the numbers line up: a column as wide as its widest value, right-
|
|
268
|
+
* aligned, so digits sit under digits and the eye can run straight down it.
|
|
269
|
+
* A column no row fills measures zero and is not drawn at all, which is what
|
|
270
|
+
* keeps this from becoming GitHub's grid of `—`.
|
|
271
|
+
*
|
|
272
|
+
* Code points rather than `.length`: every value here is ASCII or a single
|
|
273
|
+
* BMP glyph, so the two agree today, and a surrogate pair is the day they
|
|
274
|
+
* would not.
|
|
275
|
+
*/
|
|
276
|
+
declare const trailingColumnsOf: (items: readonly GHItem[]) => TrailingColumns;
|
|
277
|
+
type LayoutInput = Pick<PrRowProps, "item" | "login" | "cols" | "prefix" | "uniformLabels" | "announcements" | "columns" | "shed">;
|
|
278
|
+
/**
|
|
279
|
+
* Which trailing columns the section has to give up, so that every row gives up
|
|
280
|
+
* the same ones. Each row is laid out alone and the drops are unioned: if any
|
|
281
|
+
* row needs its size cell gone to keep a readable title, the size column goes
|
|
282
|
+
* for all of them.
|
|
283
|
+
*
|
|
284
|
+
* Forcing a drop on a row that did not need it only ever hands that row more
|
|
285
|
+
* room, so it can never push the row further down the ladder than it went on
|
|
286
|
+
* its own — the union is stable in one pass.
|
|
287
|
+
*
|
|
288
|
+
* Announcements are left out on purpose. A MERGED pill lives for three seconds
|
|
289
|
+
* on a row already leaving, and letting it reshape the whole section for those
|
|
290
|
+
* three seconds would move every row under the one you just acted on.
|
|
291
|
+
*/
|
|
292
|
+
declare const sectionShedOf: (rows: readonly Pick<LayoutInput, "item" | "prefix">[], context: Omit<LayoutInput, "item" | "prefix" | "announcements" | "shed">) => TrailingShed;
|
|
246
293
|
/**
|
|
247
294
|
* One pull request or issue, as a single line of a list.
|
|
248
295
|
*
|
|
@@ -253,7 +300,7 @@ type PrRowProps = {
|
|
|
253
300
|
* arrival, merge and departure belongs to whoever owns the list, and reaches
|
|
254
301
|
* the row as `icon`, `motion` and `announcements` after the decisions are made.
|
|
255
302
|
*/
|
|
256
|
-
declare const PrRow: ({ item, active, login, cols, icon: iconOverride, prefix, uniformLabels, motion, announcements, }: PrRowProps) => React.JSX.Element;
|
|
303
|
+
declare const PrRow: ({ item, active, login, cols, icon: iconOverride, prefix, uniformLabels, motion, announcements, columns, shed, }: PrRowProps) => React.JSX.Element;
|
|
257
304
|
|
|
258
305
|
/**
|
|
259
306
|
* One state per thing, from a closed set the strip knows how to draw. The host
|
|
@@ -713,4 +760,4 @@ declare const matchesFilter: (repo: string, filter: RepoFilter) => boolean;
|
|
|
713
760
|
*/
|
|
714
761
|
declare const parsePatterns: (value: string) => string[];
|
|
715
762
|
|
|
716
|
-
export { type Action, ActionMenu, App, COLS, CiStatusLine, type CiStatusState, type Command, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraTransition, type LiveLabel, MIN_SIDEBAR_COLS, PrRow, type PrRowProps, type Rails, type RepoFilter, type RowAnnouncement, type RowMotion, SIDEBAR_COLS, SidePanel, type Sidebar, type SidebarRow, type StatusStrip, StatusStripLine, type StripItem, type StripState, type StripStatusState, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
|
763
|
+
export { type Action, ActionMenu, App, COLS, CiStatusLine, type CiStatusState, type Command, CommentsPanel, type CommentsPanelProps, type DetailContext, type ExplainSection, type ExtensionTarget, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraTransition, type LiveLabel, MIN_SIDEBAR_COLS, PrRow, type PrRowProps, type Rails, type RepoFilter, type RowAnnouncement, type RowMotion, SIDEBAR_COLS, SidePanel, type Sidebar, type SidebarRow, type StatusStrip, StatusStripLine, type StripItem, type StripState, type StripStatusState, type TrailingColumns, type TrailingShed, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, sectionShedOf, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, trailingColumnsOf, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React2, { createContext, useState, useRef, useEffect, useMemo, useContext } from 'react';
|
|
2
2
|
import { useWindowSize, useInput, Text, Box } from 'ink';
|
|
3
|
-
import { colors, ScrollView, TextInput, Pill, useAppKeys, LoadingScreen, StatusMessage, FooterHints, useListCursor, CommandPalette, Tabs, ProgressBar, pillWidth } from '@kud/ink-ui';
|
|
3
|
+
import { colors, ScrollView, TextInput, Pill, useAppKeys, LoadingScreen, StatusMessage, FooterHints, useFilterMode, useListCursor, CommandPalette, Tabs, ProgressBar, pillWidth } from '@kud/ink-ui';
|
|
4
4
|
import { isPassCheck, isFailCheck, isInconclusiveCheck, resolveThread, unresolveThread, replyToThread, rerunFailedRun, mergePr, reRequestReviewer } from '@kud/gh';
|
|
5
5
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
6
6
|
import { PIN_MARK, sizeOf, sizePartsOf, depthOf, impliedLabels, labelPriority, checkoutDirs, profileOf, inboxConfig, relativeTime, filterBySearch, filterByRepos, filterByOrigin } from '@kud/gh-workflow';
|
|
@@ -833,41 +833,56 @@ var Backdrop = ({
|
|
|
833
833
|
children
|
|
834
834
|
}
|
|
835
835
|
) : children });
|
|
836
|
-
var
|
|
836
|
+
var threadsLabelOf = (item) => item.unresolved > 0 ? `\uF086 ${item.unresolved}` : "";
|
|
837
|
+
var agePairOf = (item) => item.activityAge && item.activityAge !== item.age ? { activity: item.activityAge, lifetime: item.age } : null;
|
|
838
|
+
var ageLabelOf = (item) => {
|
|
839
|
+
const pair = agePairOf(item);
|
|
840
|
+
return pair ? `${pair.activity} (${pair.lifetime})` : item.age;
|
|
841
|
+
};
|
|
842
|
+
var TRAILING = ["threads", "size", "age"];
|
|
843
|
+
var cellsOf = (s) => [...s].length;
|
|
844
|
+
var trailingColumnsOf = (items) => items.reduce(
|
|
845
|
+
(w, item) => ({
|
|
846
|
+
threads: Math.max(w.threads, cellsOf(threadsLabelOf(item))),
|
|
847
|
+
size: Math.max(w.size, cellsOf(sizeOf(item) ?? "")),
|
|
848
|
+
age: Math.max(w.age, cellsOf(ageLabelOf(item) ?? ""))
|
|
849
|
+
}),
|
|
850
|
+
{ threads: 0, size: 0, age: 0 }
|
|
851
|
+
);
|
|
852
|
+
var sectionShedOf = (rows, context) => rows.reduce((shed, row) => {
|
|
853
|
+
const { givingUp } = layoutOf({ ...context, ...row });
|
|
854
|
+
return {
|
|
855
|
+
threads: shed.threads || givingUp.threads,
|
|
856
|
+
size: shed.size || givingUp.size,
|
|
857
|
+
age: shed.age || givingUp.age
|
|
858
|
+
};
|
|
859
|
+
}, {});
|
|
860
|
+
var layoutOf = ({
|
|
837
861
|
item,
|
|
838
|
-
active,
|
|
839
862
|
login,
|
|
840
863
|
cols,
|
|
841
|
-
icon: iconOverride,
|
|
842
864
|
prefix = "",
|
|
843
865
|
uniformLabels = [],
|
|
844
|
-
|
|
845
|
-
|
|
866
|
+
announcements = [],
|
|
867
|
+
columns,
|
|
868
|
+
shed = {}
|
|
846
869
|
}) => {
|
|
847
|
-
const backdropped = useBackdropped();
|
|
848
|
-
const { glyph: healthIcon, color: healthColor2 } = displayFor(item.health);
|
|
849
|
-
const { glyph: icon, color } = iconOverride ?? {
|
|
850
|
-
glyph: healthIcon,
|
|
851
|
-
color: healthColor2
|
|
852
|
-
};
|
|
853
|
-
const spokeLast = !!login && !!item.lastActor && item.lastActor === login;
|
|
854
|
-
const [turnIcon, turnColor] = item.pinned ? [PIN_MARK, colors.accent] : !login || !item.lastActor || spokeLast ? [" ", colors.muted] : ["\u2190", colors.accent];
|
|
855
870
|
const numStr = `#${item.number}`.padEnd(7);
|
|
856
871
|
const showAuthor = !!item.author && item.author !== login;
|
|
857
|
-
const sizeLabel = sizeOf(item);
|
|
858
872
|
const sizeParts = sizePartsOf(item);
|
|
859
|
-
const unresolvedLabel = item
|
|
860
|
-
const agePair = item
|
|
861
|
-
const ageLabel2 =
|
|
873
|
+
const unresolvedLabel = threadsLabelOf(item);
|
|
874
|
+
const agePair = agePairOf(item);
|
|
875
|
+
const ageLabel2 = ageLabelOf(item);
|
|
876
|
+
const own = columns ?? trailingColumnsOf([item]);
|
|
862
877
|
const pillCaps = announcements.length * 2;
|
|
863
878
|
const repoLabel = depthOf(item) > 0 ? item.repo : "";
|
|
864
879
|
const implied = [...impliedLabels(item.repo), ...uniformLabels];
|
|
865
880
|
const labelNames = (item.labels ?? []).filter((l) => !implied.includes(l)).sort((a, b) => labelPriority(a) - labelPriority(b) || a.localeCompare(b)).slice(0, 2);
|
|
866
881
|
const givingUp = {
|
|
867
882
|
author: false,
|
|
868
|
-
size:
|
|
869
|
-
threads:
|
|
870
|
-
age:
|
|
883
|
+
size: !!shed.size,
|
|
884
|
+
threads: !!shed.threads,
|
|
885
|
+
age: !!shed.age,
|
|
871
886
|
repo: false,
|
|
872
887
|
labels: 0
|
|
873
888
|
};
|
|
@@ -889,16 +904,14 @@ var PrRow = ({
|
|
|
889
904
|
return `\uF02B ${fitted.join(", ")}`;
|
|
890
905
|
};
|
|
891
906
|
const widthOf2 = () => {
|
|
892
|
-
const
|
|
893
|
-
givingUp
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
...announcements.map((a) => a.label)
|
|
899
|
-
].filter(Boolean).join(" ");
|
|
907
|
+
const block = TRAILING.reduce(
|
|
908
|
+
(w, k) => givingUp[k] || own[k] === 0 ? w : w + 2 + own[k],
|
|
909
|
+
0
|
|
910
|
+
);
|
|
911
|
+
const author = showAuthor && !givingUp.author ? ` by ${item.author}`.length : 0;
|
|
912
|
+
const pills = announcements.reduce((w, a) => w + 2 + a.label.length, 0);
|
|
900
913
|
const cell = labelCell();
|
|
901
|
-
return 2 + prefix.length + 2 + 2 + 7 + (cell ? 2 + cell.length + 1 : 0) + (givingUp.repo ? 0 : repoLabel.length) +
|
|
914
|
+
return 2 + prefix.length + 2 + 2 + 7 + (cell ? 2 + cell.length + 1 : 0) + (givingUp.repo ? 0 : repoLabel.length) + author + block + pills + pillCaps + 4;
|
|
902
915
|
};
|
|
903
916
|
const MIN_TITLE = 24;
|
|
904
917
|
for (const give of [
|
|
@@ -915,7 +928,64 @@ var PrRow = ({
|
|
|
915
928
|
}
|
|
916
929
|
const labelLabel = labelCell();
|
|
917
930
|
const titleMax = Math.max(1, cols - widthOf2());
|
|
918
|
-
return
|
|
931
|
+
return {
|
|
932
|
+
numStr,
|
|
933
|
+
showAuthor,
|
|
934
|
+
sizeParts,
|
|
935
|
+
unresolvedLabel,
|
|
936
|
+
agePair,
|
|
937
|
+
ageLabel: ageLabel2,
|
|
938
|
+
repoLabel,
|
|
939
|
+
givingUp,
|
|
940
|
+
labelLabel,
|
|
941
|
+
titleMax,
|
|
942
|
+
columns: own
|
|
943
|
+
};
|
|
944
|
+
};
|
|
945
|
+
var PrRow = ({
|
|
946
|
+
item,
|
|
947
|
+
active,
|
|
948
|
+
login,
|
|
949
|
+
cols,
|
|
950
|
+
icon: iconOverride,
|
|
951
|
+
prefix = "",
|
|
952
|
+
uniformLabels = [],
|
|
953
|
+
motion,
|
|
954
|
+
announcements = [],
|
|
955
|
+
columns,
|
|
956
|
+
shed
|
|
957
|
+
}) => {
|
|
958
|
+
const backdropped = useBackdropped();
|
|
959
|
+
const { glyph: healthIcon, color: healthColor2 } = displayFor(item.health);
|
|
960
|
+
const { glyph: icon, color } = iconOverride ?? {
|
|
961
|
+
glyph: healthIcon,
|
|
962
|
+
color: healthColor2
|
|
963
|
+
};
|
|
964
|
+
const spokeLast = !!login && !!item.lastActor && item.lastActor === login;
|
|
965
|
+
const [turnIcon, turnColor] = item.pinned ? [PIN_MARK, colors.accent] : !login || !item.lastActor || spokeLast ? [" ", colors.muted] : ["\u2190", colors.accent];
|
|
966
|
+
const {
|
|
967
|
+
numStr,
|
|
968
|
+
showAuthor,
|
|
969
|
+
sizeParts,
|
|
970
|
+
unresolvedLabel,
|
|
971
|
+
agePair,
|
|
972
|
+
ageLabel: ageLabel2,
|
|
973
|
+
repoLabel,
|
|
974
|
+
givingUp,
|
|
975
|
+
labelLabel,
|
|
976
|
+
titleMax,
|
|
977
|
+
columns: block
|
|
978
|
+
} = layoutOf({
|
|
979
|
+
item,
|
|
980
|
+
login,
|
|
981
|
+
cols,
|
|
982
|
+
prefix,
|
|
983
|
+
uniformLabels,
|
|
984
|
+
announcements,
|
|
985
|
+
columns,
|
|
986
|
+
shed
|
|
987
|
+
});
|
|
988
|
+
return /* @__PURE__ */ jsxs(Box, { width: cols, children: [
|
|
919
989
|
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
|
|
920
990
|
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
|
|
921
991
|
/* @__PURE__ */ jsx(Text3, { color, bold: true, children: icon + " " }),
|
|
@@ -932,25 +1002,43 @@ var PrRow = ({
|
|
|
932
1002
|
),
|
|
933
1003
|
labelLabel ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: labelLabel + " " }) : null,
|
|
934
1004
|
repoLabel && !givingUp.repo ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: repoLabel }) : null,
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
/* @__PURE__ */ jsx(Text3, { color: colors.error, children: sizeParts.removed })
|
|
940
|
-
] }) : null,
|
|
941
|
-
unresolvedLabel && !givingUp.threads ? /* @__PURE__ */ jsx(
|
|
942
|
-
Text3,
|
|
1005
|
+
showAuthor && !givingUp.author ? /* @__PURE__ */ jsx(Text3, { dimColor: true, italic: true, children: " by " + item.author }) : null,
|
|
1006
|
+
/* @__PURE__ */ jsx(Box, { flexGrow: 1 }),
|
|
1007
|
+
block.threads > 0 && !givingUp.threads ? /* @__PURE__ */ jsx(
|
|
1008
|
+
Box,
|
|
943
1009
|
{
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1010
|
+
marginLeft: 2,
|
|
1011
|
+
width: block.threads,
|
|
1012
|
+
justifyContent: "flex-end",
|
|
1013
|
+
flexShrink: 0,
|
|
1014
|
+
children: unresolvedLabel ? /* @__PURE__ */ jsx(
|
|
1015
|
+
Text3,
|
|
1016
|
+
{
|
|
1017
|
+
bold: !spokeLast,
|
|
1018
|
+
color: spokeLast ? colors.secondary : colors.accent,
|
|
1019
|
+
children: unresolvedLabel
|
|
1020
|
+
}
|
|
1021
|
+
) : null
|
|
947
1022
|
}
|
|
948
1023
|
) : null,
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1024
|
+
block.size > 0 && !givingUp.size ? /* @__PURE__ */ jsx(
|
|
1025
|
+
Box,
|
|
1026
|
+
{
|
|
1027
|
+
marginLeft: 2,
|
|
1028
|
+
width: block.size,
|
|
1029
|
+
justifyContent: "flex-end",
|
|
1030
|
+
flexShrink: 0,
|
|
1031
|
+
children: sizeParts ? /* @__PURE__ */ jsxs(Text3, { children: [
|
|
1032
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.success, children: sizeParts.added }),
|
|
1033
|
+
" ",
|
|
1034
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.error, children: sizeParts.removed })
|
|
1035
|
+
] }) : null
|
|
1036
|
+
}
|
|
1037
|
+
) : null,
|
|
1038
|
+
block.age > 0 && !givingUp.age ? /* @__PURE__ */ jsx(Box, { marginLeft: 2, width: block.age, flexShrink: 0, children: agePair ? /* @__PURE__ */ jsxs(Text3, { children: [
|
|
1039
|
+
/* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: agePair.activity }),
|
|
952
1040
|
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` (${agePair.lifetime})` })
|
|
953
|
-
] }) : /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children:
|
|
1041
|
+
] }) : ageLabel2 ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: ageLabel2 }) : null }) : null,
|
|
954
1042
|
backdropped ? null : announcements.map((a) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
|
|
955
1043
|
/* @__PURE__ */ jsx(Text3, { children: " " }),
|
|
956
1044
|
/* @__PURE__ */ jsx(Pill, { color: a.color, children: a.label })
|
|
@@ -2242,7 +2330,9 @@ var ItemRow = ({
|
|
|
2242
2330
|
sparkFrame = 0,
|
|
2243
2331
|
cols = COLS,
|
|
2244
2332
|
markerCols = 0,
|
|
2245
|
-
uniformLabels = []
|
|
2333
|
+
uniformLabels = [],
|
|
2334
|
+
columns,
|
|
2335
|
+
shed
|
|
2246
2336
|
}) => {
|
|
2247
2337
|
const backdropped = useBackdropped();
|
|
2248
2338
|
const transient = leaving ? "out" : refreshMark;
|
|
@@ -2333,6 +2423,8 @@ var ItemRow = ({
|
|
|
2333
2423
|
cols,
|
|
2334
2424
|
prefix,
|
|
2335
2425
|
uniformLabels,
|
|
2426
|
+
columns,
|
|
2427
|
+
shed,
|
|
2336
2428
|
icon,
|
|
2337
2429
|
motion,
|
|
2338
2430
|
announcements
|
|
@@ -2376,6 +2468,7 @@ var ActionMenu = ({
|
|
|
2376
2468
|
Box,
|
|
2377
2469
|
{
|
|
2378
2470
|
flexDirection: "column",
|
|
2471
|
+
flexShrink: 0,
|
|
2379
2472
|
borderStyle: "round",
|
|
2380
2473
|
borderColor: colors.info,
|
|
2381
2474
|
backgroundColor: OVERLAY_BG,
|
|
@@ -2705,8 +2798,6 @@ var BrowseScreen = ({
|
|
|
2705
2798
|
}, [activeId]);
|
|
2706
2799
|
const [flash, setFlash] = useState(null);
|
|
2707
2800
|
const menu = useActionMenu();
|
|
2708
|
-
const [search, setSearch] = useState(null);
|
|
2709
|
-
const [searchInput, setSearchInput] = useState(false);
|
|
2710
2801
|
const [repoFilter, setRepoFilter] = useState(/* @__PURE__ */ new Set());
|
|
2711
2802
|
const [repoPicker, setRepoPicker] = useState(false);
|
|
2712
2803
|
const [help, setHelp] = useState(false);
|
|
@@ -2714,6 +2805,11 @@ var BrowseScreen = ({
|
|
|
2714
2805
|
const [helpRange, setHelpRange] = useState({ max: 0, page: 1 });
|
|
2715
2806
|
const [explain, setExplain] = useState(false);
|
|
2716
2807
|
const [palette, setPalette] = useState(null);
|
|
2808
|
+
const filter = useFilterMode({
|
|
2809
|
+
isActive: !hidden && palette === null && !help && !explain && !repoPicker && menu.actions === null
|
|
2810
|
+
});
|
|
2811
|
+
const search = filter.term;
|
|
2812
|
+
const searchInput = filter.typing;
|
|
2717
2813
|
const filterActive = search != null || repoFilter.size > 0;
|
|
2718
2814
|
const reserveCiRow = ciStatusState != null;
|
|
2719
2815
|
const reserveStripRow = stripState != null;
|
|
@@ -2834,7 +2930,7 @@ var BrowseScreen = ({
|
|
|
2834
2930
|
if (repoPicker) return setRepoPicker(false), true;
|
|
2835
2931
|
if (railActive) return setRailFocus(false), true;
|
|
2836
2932
|
if (menu.actions !== null) return menu.close(), true;
|
|
2837
|
-
if (search != null) return
|
|
2933
|
+
if (search != null) return filter.clear(), true;
|
|
2838
2934
|
if (repoFilter.size > 0) return setRepoFilter(/* @__PURE__ */ new Set()), true;
|
|
2839
2935
|
return false;
|
|
2840
2936
|
};
|
|
@@ -2850,6 +2946,13 @@ var BrowseScreen = ({
|
|
|
2850
2946
|
}, [searchInput, palette, onTyping]);
|
|
2851
2947
|
const railCols = railWidth(COLS);
|
|
2852
2948
|
const listCols = showRail ? COLS - railCols : COLS;
|
|
2949
|
+
const trailingColumns = trailingColumnsOf(labelBearing);
|
|
2950
|
+
const trailingShed = sectionShedOf(
|
|
2951
|
+
section.items.flatMap(
|
|
2952
|
+
(item, i) => item.kind === "pr" || item.kind === "issue" ? [{ item, prefix: treePrefix(section.items, i) }] : []
|
|
2953
|
+
),
|
|
2954
|
+
{ login, cols: listCols, uniformLabels, columns: trailingColumns }
|
|
2955
|
+
);
|
|
2853
2956
|
const [sparkFrame, setSparkFrame] = useState(0);
|
|
2854
2957
|
const sparkling = (mergedUrls?.length ?? 0) > 0 || (leavingUrls?.length ?? 0) > 0 || // Any MARKED TAB, not just rows on screen. The scope used to be this tab's
|
|
2855
2958
|
// own items, which was right while the animation lived on the rows and is
|
|
@@ -2976,23 +3079,7 @@ var BrowseScreen = ({
|
|
|
2976
3079
|
}
|
|
2977
3080
|
return;
|
|
2978
3081
|
}
|
|
2979
|
-
if (searchInput && !key.upArrow && !key.downArrow)
|
|
2980
|
-
if (key.return) return setSearchInput(false);
|
|
2981
|
-
if (key.escape) {
|
|
2982
|
-
setSearch(null);
|
|
2983
|
-
return setSearchInput(false);
|
|
2984
|
-
}
|
|
2985
|
-
if (key.backspace || key.delete)
|
|
2986
|
-
return setSearch((s) => (s ?? "").slice(0, -1));
|
|
2987
|
-
if (input && !key.ctrl && !key.meta && !key.tab)
|
|
2988
|
-
return setSearch((s) => (s ?? "") + input);
|
|
2989
|
-
return;
|
|
2990
|
-
}
|
|
2991
|
-
if (input === "/") {
|
|
2992
|
-
setSearch("");
|
|
2993
|
-
setSearchInput(true);
|
|
2994
|
-
return;
|
|
2995
|
-
}
|
|
3082
|
+
if (searchInput && !key.upArrow && !key.downArrow) return;
|
|
2996
3083
|
if (input === "f" && allRepos.length > 0) {
|
|
2997
3084
|
setRepoCursor(0);
|
|
2998
3085
|
setRepoPicker(true);
|
|
@@ -3520,7 +3607,7 @@ var BrowseScreen = ({
|
|
|
3520
3607
|
/* @__PURE__ */ jsx(Text3, { color: colors.info, children: " / " }),
|
|
3521
3608
|
/* @__PURE__ */ jsx(Text3, { children: search }),
|
|
3522
3609
|
searchInput ? /* @__PURE__ */ jsx(Text3, { color: colors.info, children: "\u258F" }) : null,
|
|
3523
|
-
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` ${matchCount} match${matchCount !== 1 ? "es" : ""}${
|
|
3610
|
+
/* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` ${matchCount} match${matchCount !== 1 ? "es" : ""} ${filter.hints.map(([k, label]) => `${k} ${label}`).join(" \xB7 ")}` })
|
|
3524
3611
|
] }) : repoFilter.size > 0 ? /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
3525
3612
|
/* @__PURE__ */ jsx(Text3, { color: colors.accent, children: " \u25C9 " }),
|
|
3526
3613
|
/* @__PURE__ */ jsx(Text3, { children: `${repoFilter.size} repo${repoFilter.size !== 1 ? "s" : ""}` }),
|
|
@@ -3558,6 +3645,8 @@ var BrowseScreen = ({
|
|
|
3558
3645
|
cols: listCols,
|
|
3559
3646
|
markerCols,
|
|
3560
3647
|
uniformLabels,
|
|
3648
|
+
columns: trailingColumns,
|
|
3649
|
+
shed: trailingShed,
|
|
3561
3650
|
gap: i > 0 && gapsAbove(section.items, viewStart + i)
|
|
3562
3651
|
},
|
|
3563
3652
|
`${viewStart + i}:${rowKey(item)}`
|
|
@@ -4144,4 +4233,4 @@ var matchesFilter = (repo, filter) => {
|
|
|
4144
4233
|
};
|
|
4145
4234
|
var parsePatterns = (value) => value.split(",").map((p) => p.trim()).filter(Boolean);
|
|
4146
4235
|
|
|
4147
|
-
export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, HealthPanel, MIN_SIDEBAR_COLS, PrRow, SIDEBAR_COLS, SidePanel, StatusStripLine, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
|
4236
|
+
export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, HealthPanel, MIN_SIDEBAR_COLS, PrRow, SIDEBAR_COLS, SidePanel, StatusStripLine, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, moveCursor, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, sectionShedOf, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, trailingColumnsOf, truncate, useActionMenu, windowCount, withHeaders, withoutItem, workCount, writeCache };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.62.1",
|
|
4
4
|
"description": "Ink components for rendering GitHub PR review comments and health — controlled, presentation-only, built on @kud/ink-ui and fed by @kud/gh.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@kud/gh": "0.18.0",
|
|
52
52
|
"@kud/gh-workflow": "0.13.1",
|
|
53
|
-
"@kud/ink-ui": "0.
|
|
53
|
+
"@kud/ink-ui": "0.31.0",
|
|
54
54
|
"zx": "8.8.5"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|