tycono 0.1.96-beta.11 → 0.1.96-beta.13
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/package.json +1 -1
- package/src/tui/app.tsx +6 -6
- package/src/tui/components/OrgTree.tsx +1 -14
- package/src/tui/store.ts +12 -0
package/package.json
CHANGED
package/src/tui/app.tsx
CHANGED
|
@@ -17,7 +17,7 @@ import { SetupWizard } from './components/SetupWizard';
|
|
|
17
17
|
import { useApi } from './hooks/useApi';
|
|
18
18
|
import { useSSE } from './hooks/useSSE';
|
|
19
19
|
import { useCommand } from './hooks/useCommand';
|
|
20
|
-
import { buildOrgTree } from './store';
|
|
20
|
+
import { buildOrgTree, flattenOrgRoleIds } from './store';
|
|
21
21
|
|
|
22
22
|
type Mode = 'command' | 'panel';
|
|
23
23
|
type View = 'loading' | 'setup' | 'dashboard';
|
|
@@ -57,12 +57,12 @@ export const App: React.FC = () => {
|
|
|
57
57
|
// System messages (command feedback displayed in stream area)
|
|
58
58
|
const [systemMessages, setSystemMessages] = useState<StreamLine[]>([]);
|
|
59
59
|
|
|
60
|
-
// Terminal full height with resize tracking
|
|
61
|
-
const [termHeight, setTermHeight] = useState(process.stdout.rows || 30);
|
|
60
|
+
// Terminal full height with resize tracking (minus 1 for wide-char overflow safety)
|
|
61
|
+
const [termHeight, setTermHeight] = useState((process.stdout.rows || 30) - 1);
|
|
62
62
|
|
|
63
63
|
useEffect(() => {
|
|
64
64
|
const onResize = () => {
|
|
65
|
-
setTermHeight(process.stdout.rows || 30);
|
|
65
|
+
setTermHeight((process.stdout.rows || 30) - 1);
|
|
66
66
|
};
|
|
67
67
|
process.stdout.on('resize', onResize);
|
|
68
68
|
return () => {
|
|
@@ -90,11 +90,11 @@ export const App: React.FC = () => {
|
|
|
90
90
|
// SSE subscription
|
|
91
91
|
const sse = useSSE(effectiveWaveId);
|
|
92
92
|
|
|
93
|
-
// Build org tree
|
|
93
|
+
// Build org tree — flatRoleIds follows visual top-to-bottom order
|
|
94
94
|
const roles = api.company?.roles ?? [];
|
|
95
|
-
const flatRoleIds = useMemo(() => roles.map(r => r.id), [roles]);
|
|
96
95
|
const statuses = api.execStatus?.statuses ?? {};
|
|
97
96
|
const orgTree = useMemo(() => buildOrgTree(roles, statuses), [roles, statuses]);
|
|
97
|
+
const flatRoleIds = useMemo(() => flattenOrgRoleIds(orgTree), [orgTree]);
|
|
98
98
|
|
|
99
99
|
// Active count
|
|
100
100
|
const activeCount = Object.values(statuses).filter(
|
|
@@ -32,7 +32,6 @@ function statusColor(status: string): string {
|
|
|
32
32
|
|
|
33
33
|
interface FlatEntry {
|
|
34
34
|
roleId: string;
|
|
35
|
-
name: string;
|
|
36
35
|
level: string;
|
|
37
36
|
status: string;
|
|
38
37
|
prefix: string;
|
|
@@ -55,7 +54,6 @@ function flattenTree(nodes: OrgNode[], prefix: string = '', isLast: boolean[] =
|
|
|
55
54
|
|
|
56
55
|
result.push({
|
|
57
56
|
roleId: node.role.id,
|
|
58
|
-
name: node.role.name || node.role.id,
|
|
59
57
|
level: node.role.level,
|
|
60
58
|
status: node.status,
|
|
61
59
|
prefix: linePrefix,
|
|
@@ -72,16 +70,6 @@ function flattenTree(nodes: OrgNode[], prefix: string = '', isLast: boolean[] =
|
|
|
72
70
|
export const OrgTree: React.FC<OrgTreeProps> = ({ tree, focused, selectedIndex, flatRoles }) => {
|
|
73
71
|
const entries = flattenTree(tree);
|
|
74
72
|
|
|
75
|
-
// Map flatRoles index to entries
|
|
76
|
-
const flatRoleIdToEntryIdx = new Map<number, number>();
|
|
77
|
-
let roleIdx = 0;
|
|
78
|
-
for (let i = 0; i < entries.length; i++) {
|
|
79
|
-
if (roleIdx < flatRoles.length && flatRoles[roleIdx] === entries[i].roleId) {
|
|
80
|
-
flatRoleIdToEntryIdx.set(roleIdx, i);
|
|
81
|
-
roleIdx++;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
73
|
return (
|
|
86
74
|
<Box flexDirection="column" paddingX={1}>
|
|
87
75
|
<Text bold color={focused ? 'cyan' : 'gray'}>{'── Org Tree ──'}</Text>
|
|
@@ -108,9 +96,8 @@ export const OrgTree: React.FC<OrgTreeProps> = ({ tree, focused, selectedIndex,
|
|
|
108
96
|
bold={isSelected}
|
|
109
97
|
inverse={isSelected}
|
|
110
98
|
>
|
|
111
|
-
{entry.
|
|
99
|
+
{entry.roleId}
|
|
112
100
|
</Text>
|
|
113
|
-
<Text color="gray" dimColor> {entry.roleId}</Text>
|
|
114
101
|
</Box>
|
|
115
102
|
);
|
|
116
103
|
})}
|
package/src/tui/store.ts
CHANGED
|
@@ -97,3 +97,15 @@ export function buildOrgTree(roles: RoleInfo[], statuses: Record<string, string>
|
|
|
97
97
|
|
|
98
98
|
return roots;
|
|
99
99
|
}
|
|
100
|
+
|
|
101
|
+
/** Flatten org tree into visual top-to-bottom order of role IDs */
|
|
102
|
+
export function flattenOrgRoleIds(nodes: OrgNode[]): string[] {
|
|
103
|
+
const result: string[] = [];
|
|
104
|
+
for (const node of nodes) {
|
|
105
|
+
result.push(node.role.id);
|
|
106
|
+
if (node.children.length > 0) {
|
|
107
|
+
result.push(...flattenOrgRoleIds(node.children));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|