git-stack-cli 0.5.0 → 0.5.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/app/MultiSelect.js +4 -0
- package/dist/app/SelectCommitRanges.js +1 -5
- package/dist/app/StatusTable.js +58 -60
- package/dist/app/Table.js +63 -0
- package/dist/app/Url.js +1 -1
- package/dist/core/invariant copy.js +5 -0
- package/dist/core/isFiniteValue.js +3 -0
- package/dist/core/is_finite_value.js +3 -0
- package/package.json +1 -1
package/dist/app/MultiSelect.js
CHANGED
|
@@ -53,6 +53,10 @@ export function MultiSelect(props) {
|
|
|
53
53
|
props.onSelect({ item, selected, state });
|
|
54
54
|
}, [selected_set]);
|
|
55
55
|
Ink.useInput((_input, key) => {
|
|
56
|
+
if (props.disabled) {
|
|
57
|
+
console.debug("[MultiSelect] disabled, ignoring input");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
56
60
|
if (key.return) {
|
|
57
61
|
selectRef.current = true;
|
|
58
62
|
const item = props.items[index];
|
|
@@ -135,12 +135,8 @@ function SelectCommitRangesInternal(props) {
|
|
|
135
135
|
max_item_width -= left_arrow.length + right_arrow.length;
|
|
136
136
|
return (React.createElement(Ink.Box, { flexDirection: "column" },
|
|
137
137
|
React.createElement(Ink.Box, { height: 1 }),
|
|
138
|
-
React.createElement(MultiSelect, { key: group.id, items: items, maxWidth: max_item_width, onSelect: (args) => {
|
|
138
|
+
React.createElement(MultiSelect, { key: group.id, items: items, maxWidth: max_item_width, disabled: group_input, onSelect: (args) => {
|
|
139
139
|
// console.debug("onSelect", args);
|
|
140
|
-
if (group_input) {
|
|
141
|
-
// console.debug("group_input is true, ignoring onSelect");
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
140
|
const key = args.item.sha;
|
|
145
141
|
let value;
|
|
146
142
|
if (args.selected) {
|
package/dist/app/StatusTable.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as Ink from "ink";
|
|
3
|
+
import { assertNever } from "../core/assertNever.js";
|
|
3
4
|
import { invariant } from "../core/invariant.js";
|
|
4
5
|
import { Store } from "./Store.js";
|
|
6
|
+
import { Table } from "./Table.js";
|
|
7
|
+
import { Url } from "./Url.js";
|
|
5
8
|
export function StatusTable() {
|
|
6
9
|
const commit_range = Store.useState((state) => state.commit_range);
|
|
7
10
|
invariant(commit_range, "commit_range must exist");
|
|
@@ -10,10 +13,9 @@ export function StatusTable() {
|
|
|
10
13
|
const row = {
|
|
11
14
|
icon: "",
|
|
12
15
|
count: "",
|
|
13
|
-
status: "",
|
|
16
|
+
status: "NEW",
|
|
14
17
|
title: "",
|
|
15
18
|
url: "",
|
|
16
|
-
id: group.id,
|
|
17
19
|
};
|
|
18
20
|
if (group.id === commit_range.UNASSIGNED) {
|
|
19
21
|
row.icon = "⭑";
|
|
@@ -41,69 +43,65 @@ export function StatusTable() {
|
|
|
41
43
|
row.url = group.pr.url;
|
|
42
44
|
}
|
|
43
45
|
else {
|
|
44
|
-
row.title = group.id;
|
|
46
|
+
row.title = group.title || group.id;
|
|
45
47
|
row.count = `0/${group.commits.length}`;
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
row_list.push(row);
|
|
49
51
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
52
|
+
return (React.createElement(Table, { data: row_list, fillColumn: "title",
|
|
53
|
+
// maxWidth={{
|
|
54
|
+
// title: 30,
|
|
55
|
+
// }}
|
|
56
|
+
columnGap: 3, columns: {
|
|
57
|
+
icon: IconColumn,
|
|
58
|
+
status: StatusColumn,
|
|
59
|
+
count: CountColumn,
|
|
60
|
+
title: TitleColumn,
|
|
61
|
+
url: UrlColumn,
|
|
62
|
+
} }));
|
|
63
|
+
}
|
|
64
|
+
function IconColumn(props) {
|
|
65
|
+
const value = props.row[props.column];
|
|
66
|
+
return (React.createElement(Ink.Text, { color: get_status_color(props.row), bold: get_status_bold(props.row) }, value));
|
|
67
|
+
}
|
|
68
|
+
function StatusColumn(props) {
|
|
69
|
+
const value = props.row[props.column];
|
|
70
|
+
return (React.createElement(Ink.Text, { color: get_status_color(props.row), bold: get_status_bold(props.row) }, value));
|
|
71
|
+
}
|
|
72
|
+
function CountColumn(props) {
|
|
73
|
+
const value = props.row[props.column];
|
|
74
|
+
return React.createElement(Ink.Text, { dimColor: true }, value);
|
|
75
|
+
}
|
|
76
|
+
function TitleColumn(props) {
|
|
77
|
+
const value = props.row[props.column];
|
|
78
|
+
return React.createElement(Ink.Text, { wrap: "truncate-end" }, value);
|
|
79
|
+
}
|
|
80
|
+
function UrlColumn(props) {
|
|
81
|
+
const value = props.row[props.column];
|
|
82
|
+
return React.createElement(Url, { dimColor: true }, value);
|
|
83
|
+
}
|
|
84
|
+
function get_status_color(row) {
|
|
85
|
+
switch (row.status) {
|
|
86
|
+
case "NEW":
|
|
87
|
+
return "yellow";
|
|
88
|
+
case "OUTDATED":
|
|
89
|
+
return "red";
|
|
90
|
+
case "MERGED":
|
|
91
|
+
return "purple";
|
|
92
|
+
case "SYNCED":
|
|
93
|
+
return "green";
|
|
94
|
+
default:
|
|
95
|
+
assertNever(row.status);
|
|
96
|
+
return "gray";
|
|
66
97
|
}
|
|
67
|
-
const { stdout } = Ink.useStdout();
|
|
68
|
-
const available_width = stdout.columns;
|
|
69
|
-
const columnGap = 2;
|
|
70
|
-
const breathing_room = 0;
|
|
71
|
-
const remaining_space = available_width -
|
|
72
|
-
// icon
|
|
73
|
-
max_col_width.icon -
|
|
74
|
-
// status
|
|
75
|
-
max_col_width.status -
|
|
76
|
-
// commits
|
|
77
|
-
max_col_width.count -
|
|
78
|
-
// url
|
|
79
|
-
max_col_width.url -
|
|
80
|
-
// gap * col count (minus one for row.id which is not shown but used at key)
|
|
81
|
-
columnGap * (col_list.length - 1) -
|
|
82
|
-
// remove some extra space
|
|
83
|
-
breathing_room;
|
|
84
|
-
// add one for ellipsis character
|
|
85
|
-
const title_width = Math.min(max_col_width.title, remaining_space + 1);
|
|
86
|
-
// prettier-ignore
|
|
87
|
-
// console.debug({ available_width, remaining_space, title_width, max_col_width });
|
|
88
|
-
return (React.createElement(Container, null, row_list.map((row) => {
|
|
89
|
-
return (React.createElement(Ink.Box, { key: row.id,
|
|
90
|
-
// borderStyle="round"
|
|
91
|
-
flexDirection: "row", columnGap: columnGap, width: available_width },
|
|
92
|
-
React.createElement(Ink.Box, { width: max_col_width.icon },
|
|
93
|
-
React.createElement(Ink.Text, null, row.icon)),
|
|
94
|
-
React.createElement(Ink.Box, { width: max_col_width.status },
|
|
95
|
-
React.createElement(Ink.Text, null, row.status)),
|
|
96
|
-
React.createElement(Ink.Box, { width: max_col_width.count },
|
|
97
|
-
React.createElement(Ink.Text, null, row.count)),
|
|
98
|
-
React.createElement(Ink.Box, { width: title_width },
|
|
99
|
-
React.createElement(Ink.Text, { wrap: "truncate-end" }, row.title)),
|
|
100
|
-
React.createElement(Ink.Box, { width: max_col_width.url },
|
|
101
|
-
React.createElement(Ink.Text, null, row.url))));
|
|
102
|
-
})));
|
|
103
98
|
}
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
function get_status_bold(row) {
|
|
100
|
+
switch (row.status) {
|
|
101
|
+
case "NEW":
|
|
102
|
+
case "OUTDATED":
|
|
103
|
+
return true;
|
|
104
|
+
default:
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
109
107
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as Ink from "ink";
|
|
3
|
+
import { is_finite_value } from "../core/is_finite_value.js";
|
|
4
|
+
export function Table(props) {
|
|
5
|
+
if (!props.data.length) {
|
|
6
|
+
return (React.createElement(Container, null,
|
|
7
|
+
React.createElement(Ink.Text, { dimColor: true }, "No data found.")));
|
|
8
|
+
}
|
|
9
|
+
const sample_row = props.data[0];
|
|
10
|
+
const RowColumnList = Object.keys(sample_row);
|
|
11
|
+
// walk data and discover max width for each column
|
|
12
|
+
const max_col_width = {};
|
|
13
|
+
for (const col of RowColumnList) {
|
|
14
|
+
max_col_width[col] = 0;
|
|
15
|
+
}
|
|
16
|
+
for (const row of props.data) {
|
|
17
|
+
for (const col of RowColumnList) {
|
|
18
|
+
const row_col = row[col];
|
|
19
|
+
max_col_width[col] = Math.max(String(row_col).length, max_col_width[col]);
|
|
20
|
+
const maxWidth = props.maxWidth?.[col];
|
|
21
|
+
if (is_finite_value(maxWidth)) {
|
|
22
|
+
max_col_width[col] = Math.min(maxWidth - 1, max_col_width[col]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const { stdout } = Ink.useStdout();
|
|
27
|
+
const available_width = stdout.columns;
|
|
28
|
+
const columnGap = is_finite_value(props.columnGap) ? props.columnGap : 2;
|
|
29
|
+
const breathing_room = 0;
|
|
30
|
+
if (props.fillColumn) {
|
|
31
|
+
let remaining_space = available_width;
|
|
32
|
+
for (const col of RowColumnList) {
|
|
33
|
+
// skip fill column from calculation
|
|
34
|
+
if (props.fillColumn === col) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
remaining_space -= max_col_width[col];
|
|
38
|
+
}
|
|
39
|
+
// gap * col count
|
|
40
|
+
remaining_space -= columnGap * (RowColumnList.length - 1);
|
|
41
|
+
// remove some extra space
|
|
42
|
+
remaining_space -= breathing_room;
|
|
43
|
+
if (props.fillColumn) {
|
|
44
|
+
max_col_width[props.fillColumn] = Math.min(max_col_width[props.fillColumn], remaining_space);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// console.debug({ available_width, remaining_space, max_col_width });
|
|
48
|
+
return (React.createElement(Container, null, props.data.map((row, i) => {
|
|
49
|
+
return (React.createElement(Ink.Box, { key: i,
|
|
50
|
+
// borderStyle="round"
|
|
51
|
+
flexDirection: "row", columnGap: columnGap, width: available_width }, RowColumnList.map((column) => {
|
|
52
|
+
const ColumnComponent = props.columns[column];
|
|
53
|
+
return (React.createElement(Ink.Box, { key: String(column), width: max_col_width[column] },
|
|
54
|
+
React.createElement(ColumnComponent, { row: row, column: column })));
|
|
55
|
+
})));
|
|
56
|
+
})));
|
|
57
|
+
}
|
|
58
|
+
function Container(props) {
|
|
59
|
+
return (React.createElement(Ink.Box, { flexDirection: "column" },
|
|
60
|
+
React.createElement(Ink.Box, { height: 1 }),
|
|
61
|
+
props.children,
|
|
62
|
+
React.createElement(Ink.Box, { height: 1 })));
|
|
63
|
+
}
|
package/dist/app/Url.js
CHANGED
|
@@ -2,5 +2,5 @@ import * as React from "react";
|
|
|
2
2
|
import * as Ink from "ink";
|
|
3
3
|
export function Url(props) {
|
|
4
4
|
const text_color = "#38bdf8";
|
|
5
|
-
return (React.createElement(Ink.Text, { bold: true, color: text_color }, props.children));
|
|
5
|
+
return (React.createElement(Ink.Text, { bold: true, color: text_color, ...props }, props.children));
|
|
6
6
|
}
|