azp-cli 0.0.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/.vscode/extensions.json +3 -0
- package/.vscode/launch.json +25 -0
- package/.vscode/settings.json +25 -0
- package/.vscode/tasks.json +28 -0
- package/README.md +203 -0
- package/dist/auth.d.ts +11 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +52 -0
- package/dist/auth.js.map +1 -0
- package/dist/azure-pim.d.ts +44 -0
- package/dist/azure-pim.d.ts.map +1 -0
- package/dist/azure-pim.js +183 -0
- package/dist/azure-pim.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +339 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/App.d.ts +9 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +85 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/components.d.ts +18 -0
- package/dist/ui/components.d.ts.map +1 -0
- package/dist/ui/components.js +13 -0
- package/dist/ui/components.js.map +1 -0
- package/dist/ui/router.d.ts +22 -0
- package/dist/ui/router.d.ts.map +1 -0
- package/dist/ui/router.js +19 -0
- package/dist/ui/router.js.map +1 -0
- package/dist/ui/screens/ActivateFlow.d.ts +25 -0
- package/dist/ui/screens/ActivateFlow.d.ts.map +1 -0
- package/dist/ui/screens/ActivateFlow.js +195 -0
- package/dist/ui/screens/ActivateFlow.js.map +1 -0
- package/dist/ui/screens/DeactivateFlow.d.ts +22 -0
- package/dist/ui/screens/DeactivateFlow.d.ts.map +1 -0
- package/dist/ui/screens/DeactivateFlow.js +115 -0
- package/dist/ui/screens/DeactivateFlow.js.map +1 -0
- package/dist/ui/useExitConfirmation.d.ts +7 -0
- package/dist/ui/useExitConfirmation.d.ts.map +1 -0
- package/dist/ui/useExitConfirmation.js +17 -0
- package/dist/ui/useExitConfirmation.js.map +1 -0
- package/dist/ui/widgets/CheckboxList.d.ts +14 -0
- package/dist/ui/widgets/CheckboxList.d.ts.map +1 -0
- package/dist/ui/widgets/CheckboxList.js +59 -0
- package/dist/ui/widgets/CheckboxList.js.map +1 -0
- package/dist/ui/widgets/ConfirmPrompt.d.ts +8 -0
- package/dist/ui/widgets/ConfirmPrompt.d.ts.map +1 -0
- package/dist/ui/widgets/ConfirmPrompt.js +19 -0
- package/dist/ui/widgets/ConfirmPrompt.js.map +1 -0
- package/dist/ui/widgets/NumberPrompt.d.ts +10 -0
- package/dist/ui/widgets/NumberPrompt.d.ts.map +1 -0
- package/dist/ui/widgets/NumberPrompt.js +38 -0
- package/dist/ui/widgets/NumberPrompt.js.map +1 -0
- package/dist/ui/widgets/SelectList.d.ts +14 -0
- package/dist/ui/widgets/SelectList.d.ts.map +1 -0
- package/dist/ui/widgets/SelectList.js +34 -0
- package/dist/ui/widgets/SelectList.js.map +1 -0
- package/dist/ui/widgets/TextPrompt.d.ts +10 -0
- package/dist/ui/widgets/TextPrompt.d.ts.map +1 -0
- package/dist/ui/widgets/TextPrompt.js +30 -0
- package/dist/ui/widgets/TextPrompt.js.map +1 -0
- package/dist/ui.d.ts +26 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +183 -0
- package/dist/ui.js.map +1 -0
- package/package.json +47 -0
- package/pnpm-workspace.yaml +2 -0
- package/src/auth.ts +66 -0
- package/src/azure-pim.ts +262 -0
- package/src/cli.ts +401 -0
- package/src/index.ts +65 -0
- package/src/ui.ts +253 -0
- package/tsconfig.json +45 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { AuthContext } from "../../auth";
|
|
3
|
+
import { type AzureSubscription, type EligibleAzureRole } from "../../azure-pim";
|
|
4
|
+
import type { NavigateAction, ScreenId } from "../router";
|
|
5
|
+
export type ActivateFlowState = {
|
|
6
|
+
subscription?: AzureSubscription;
|
|
7
|
+
eligibleRoles?: EligibleAzureRole[];
|
|
8
|
+
selectedRoleIds: string[];
|
|
9
|
+
durationHours?: number;
|
|
10
|
+
justification?: string;
|
|
11
|
+
results?: Array<{
|
|
12
|
+
roleId: string;
|
|
13
|
+
ok: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
export type ActivateFlowProps = {
|
|
18
|
+
authContext: AuthContext;
|
|
19
|
+
screen: ScreenId;
|
|
20
|
+
state: ActivateFlowState;
|
|
21
|
+
setState: (updater: (prev: ActivateFlowState) => ActivateFlowState) => void;
|
|
22
|
+
navigate: (action: NavigateAction) => void;
|
|
23
|
+
};
|
|
24
|
+
export declare const ActivateFlow: React.FC<ActivateFlowProps>;
|
|
25
|
+
//# sourceMappingURL=ActivateFlow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActivateFlow.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/ActivateFlow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAGvB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,iBAAiB,KAAK,IAAI,CAAC;IAC5E,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqQpD,CAAC"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { activateAzureRole, fetchEligibleRolesForSubscription, fetchSubscriptions, } from "../../azure-pim";
|
|
5
|
+
import { EmptyState, ErrorState } from "../components";
|
|
6
|
+
import { CheckboxList } from "../widgets/CheckboxList";
|
|
7
|
+
import { ConfirmPrompt } from "../widgets/ConfirmPrompt";
|
|
8
|
+
import { NumberPrompt } from "../widgets/NumberPrompt";
|
|
9
|
+
import { SelectList } from "../widgets/SelectList";
|
|
10
|
+
import { TextPrompt } from "../widgets/TextPrompt";
|
|
11
|
+
export const ActivateFlow = ({ authContext, screen, state, setState, navigate }) => {
|
|
12
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
const [subscriptions, setSubscriptions] = useState(null);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (screen !== "activate/subscriptions")
|
|
17
|
+
return;
|
|
18
|
+
let cancelled = false;
|
|
19
|
+
(async () => {
|
|
20
|
+
setIsLoading(true);
|
|
21
|
+
setError(null);
|
|
22
|
+
try {
|
|
23
|
+
const subs = await fetchSubscriptions(authContext.credential);
|
|
24
|
+
if (cancelled)
|
|
25
|
+
return;
|
|
26
|
+
setSubscriptions(subs);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
if (cancelled)
|
|
30
|
+
return;
|
|
31
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
if (!cancelled)
|
|
35
|
+
setIsLoading(false);
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
return () => {
|
|
39
|
+
cancelled = true;
|
|
40
|
+
};
|
|
41
|
+
}, [screen, authContext.credential]);
|
|
42
|
+
const subscriptionItems = useMemo(() => {
|
|
43
|
+
return (subscriptions ?? []).map((s) => ({
|
|
44
|
+
key: s.subscriptionId,
|
|
45
|
+
label: s.displayName,
|
|
46
|
+
meta: s.subscriptionId,
|
|
47
|
+
value: s,
|
|
48
|
+
}));
|
|
49
|
+
}, [subscriptions]);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (screen !== "activate/eligible-roles")
|
|
52
|
+
return;
|
|
53
|
+
const subscription = state.subscription;
|
|
54
|
+
if (!subscription) {
|
|
55
|
+
navigate({ type: "replace", route: { id: "activate/subscriptions" } });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
let cancelled = false;
|
|
59
|
+
(async () => {
|
|
60
|
+
setIsLoading(true);
|
|
61
|
+
setError(null);
|
|
62
|
+
try {
|
|
63
|
+
const roles = await fetchEligibleRolesForSubscription(authContext.credential, subscription.subscriptionId, subscription.displayName, authContext.userId);
|
|
64
|
+
if (cancelled)
|
|
65
|
+
return;
|
|
66
|
+
setState((prev) => ({ ...prev, eligibleRoles: roles }));
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
if (cancelled)
|
|
70
|
+
return;
|
|
71
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
if (!cancelled)
|
|
75
|
+
setIsLoading(false);
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
return () => {
|
|
79
|
+
cancelled = true;
|
|
80
|
+
};
|
|
81
|
+
}, [screen, state.subscription, authContext.credential, authContext.userId, navigate, setState]);
|
|
82
|
+
const roleItems = useMemo(() => {
|
|
83
|
+
const roles = state.eligibleRoles ?? [];
|
|
84
|
+
return roles.map((r) => ({
|
|
85
|
+
key: r.id,
|
|
86
|
+
label: `${r.roleName} — ${r.scopeDisplayName}`,
|
|
87
|
+
}));
|
|
88
|
+
}, [state.eligibleRoles]);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (screen !== "activate/progress")
|
|
91
|
+
return;
|
|
92
|
+
if (!state.subscription || !state.eligibleRoles || state.selectedRoleIds.length === 0 || !state.durationHours || !state.justification) {
|
|
93
|
+
navigate({ type: "home" });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const subscription = state.subscription;
|
|
97
|
+
const eligibleRoles = state.eligibleRoles;
|
|
98
|
+
const durationHours = state.durationHours;
|
|
99
|
+
const justification = state.justification;
|
|
100
|
+
let cancelled = false;
|
|
101
|
+
(async () => {
|
|
102
|
+
setIsLoading(true);
|
|
103
|
+
setError(null);
|
|
104
|
+
setState((prev) => ({ ...prev, results: [] }));
|
|
105
|
+
const results = [];
|
|
106
|
+
for (const roleId of state.selectedRoleIds) {
|
|
107
|
+
if (cancelled)
|
|
108
|
+
return;
|
|
109
|
+
const role = eligibleRoles.find((r) => r.id === roleId);
|
|
110
|
+
if (!role) {
|
|
111
|
+
results.push({ roleId, ok: false, error: "Role not found" });
|
|
112
|
+
setState((prev) => ({ ...prev, results: [...results] }));
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const req = {
|
|
116
|
+
principalId: authContext.userId,
|
|
117
|
+
roleDefinitionId: role.roleDefinitionId,
|
|
118
|
+
roleName: `${role.roleName} - ${role.scopeDisplayName}`,
|
|
119
|
+
roleEligibilityScheduleId: role.roleEligibilityScheduleId,
|
|
120
|
+
scope: role.scope,
|
|
121
|
+
durationHours,
|
|
122
|
+
justification,
|
|
123
|
+
};
|
|
124
|
+
try {
|
|
125
|
+
await activateAzureRole(authContext.credential, req, subscription.subscriptionId);
|
|
126
|
+
results.push({ roleId, ok: true });
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
results.push({ roleId, ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
130
|
+
}
|
|
131
|
+
setState((prev) => ({ ...prev, results: [...results] }));
|
|
132
|
+
}
|
|
133
|
+
setIsLoading(false);
|
|
134
|
+
})();
|
|
135
|
+
return () => {
|
|
136
|
+
cancelled = true;
|
|
137
|
+
};
|
|
138
|
+
}, [screen, state.subscription, state.eligibleRoles, state.selectedRoleIds, state.durationHours, state.justification, authContext, navigate, setState]);
|
|
139
|
+
if (error) {
|
|
140
|
+
return _jsx(ErrorState, { message: "Activation flow error", details: error });
|
|
141
|
+
}
|
|
142
|
+
if (screen === "activate/subscriptions") {
|
|
143
|
+
if (isLoading && !subscriptions)
|
|
144
|
+
return _jsx(Text, { dimColor: true, children: "Loading subscriptions\u2026" });
|
|
145
|
+
if (!subscriptions)
|
|
146
|
+
return _jsx(Text, { dimColor: true, children: "Loading\u2026" });
|
|
147
|
+
if (subscriptions.length === 0)
|
|
148
|
+
return _jsx(EmptyState, { message: "No subscriptions found." });
|
|
149
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: "Select a subscription:" }), _jsx(SelectList, { items: subscriptionItems, isLoading: isLoading, onSelect: (sub) => {
|
|
150
|
+
setState((prev) => ({ ...prev, subscription: sub, eligibleRoles: undefined, selectedRoleIds: [] }));
|
|
151
|
+
navigate({ type: "push", route: { id: "activate/eligible-roles" } });
|
|
152
|
+
} })] }));
|
|
153
|
+
}
|
|
154
|
+
if (screen === "activate/eligible-roles") {
|
|
155
|
+
const roles = state.eligibleRoles;
|
|
156
|
+
if (!roles && isLoading)
|
|
157
|
+
return _jsx(Text, { dimColor: true, children: "Loading eligible roles\u2026" });
|
|
158
|
+
if (!roles)
|
|
159
|
+
return _jsx(Text, { dimColor: true, children: "Loading\u2026" });
|
|
160
|
+
if (roles.length === 0)
|
|
161
|
+
return _jsx(EmptyState, { message: "No eligible roles found for this subscription." });
|
|
162
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: "Pick eligible roles to activate:" }), _jsx(CheckboxList, { items: roleItems, onSubmit: (selectedKeys) => {
|
|
163
|
+
if (selectedKeys.length === 0)
|
|
164
|
+
return;
|
|
165
|
+
setState((prev) => ({ ...prev, selectedRoleIds: selectedKeys }));
|
|
166
|
+
navigate({ type: "push", route: { id: "activate/duration" } });
|
|
167
|
+
} }), _jsx(Text, { dimColor: true, children: "Tip: press \u201Ca\u201D to toggle all." })] }));
|
|
168
|
+
}
|
|
169
|
+
if (screen === "activate/duration") {
|
|
170
|
+
return (_jsx(NumberPrompt, { label: "Duration in hours (1-8):", initialValue: state.durationHours ?? 8, min: 1, max: 8, onSubmit: (hours) => {
|
|
171
|
+
setState((prev) => ({ ...prev, durationHours: hours }));
|
|
172
|
+
navigate({ type: "push", route: { id: "activate/justification" } });
|
|
173
|
+
} }));
|
|
174
|
+
}
|
|
175
|
+
if (screen === "activate/justification") {
|
|
176
|
+
return (_jsx(TextPrompt, { label: "Justification:", initialValue: state.justification ?? "Activated via azp-cli", validate: (v) => (v.trim().length >= 5 ? true : "Justification should be at least 5 characters"), onSubmit: (value) => {
|
|
177
|
+
setState((prev) => ({ ...prev, justification: value }));
|
|
178
|
+
navigate({ type: "push", route: { id: "activate/confirm" } });
|
|
179
|
+
} }));
|
|
180
|
+
}
|
|
181
|
+
if (screen === "activate/confirm") {
|
|
182
|
+
const subscriptionName = state.subscription?.displayName ?? "(unknown)";
|
|
183
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { children: ["Activate ", _jsx(Text, { bold: true, children: state.selectedRoleIds.length }), " role(s) on ", _jsx(Text, { bold: true, children: subscriptionName }), "?"] }), _jsxs(Text, { dimColor: true, children: ["Duration: ", state.durationHours ?? "?", "h"] }), _jsxs(Text, { dimColor: true, children: ["Justification: ", state.justification ?? "?"] }), _jsx(ConfirmPrompt, { message: "Confirm activation?", onConfirm: () => navigate({ type: "push", route: { id: "activate/progress" } }), onCancel: () => navigate({ type: "back" }) })] }));
|
|
184
|
+
}
|
|
185
|
+
if (screen === "activate/progress") {
|
|
186
|
+
const results = state.results ?? [];
|
|
187
|
+
const total = state.selectedRoleIds.length;
|
|
188
|
+
const done = results.length;
|
|
189
|
+
const ok = results.filter((r) => r.ok).length;
|
|
190
|
+
const fail = results.filter((r) => !r.ok).length;
|
|
191
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { children: ["Progress: ", done, "/", total, " (ok: ", ok, ", failed: ", fail, ")"] }), _jsx(Box, { flexDirection: "column", children: results.slice(-8).map((r) => (_jsxs(Text, { color: r.ok ? "green" : "red", children: [r.ok ? "✓" : "✗", " ", r.roleId] }, r.roleId))) }), done === total && !isLoading ? _jsx(Text, { dimColor: true, children: "Done. Press m for menu." }) : _jsx(Text, { dimColor: true, children: "Working\u2026" })] }));
|
|
192
|
+
}
|
|
193
|
+
return _jsx(Text, { dimColor: true, children: "Unknown activate screen." });
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=ActivateFlow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActivateFlow.js","sourceRoot":"","sources":["../../../src/ui/screens/ActivateFlow.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EACL,iBAAiB,EAIjB,iCAAiC,EACjC,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAuB,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAoBnD,MAAM,CAAC,MAAM,YAAY,GAAgC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC9G,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAGxD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAA6B,IAAI,CAAC,CAAC;IAErF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,wBAAwB;YAAE,OAAO;QAChD,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,CAAC,KAAK,IAAI,EAAE;YACV,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;gBAC9D,IAAI,SAAS;oBAAE,OAAO;gBACtB,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,CAAU,EAAE,CAAC;gBACpB,IAAI,SAAS;oBAAE,OAAO;gBACtB,QAAQ,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACvD,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,SAAS;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAErC,MAAM,iBAAiB,GAAwC,OAAO,CAAC,GAAG,EAAE;QAC1E,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvC,GAAG,EAAE,CAAC,CAAC,cAAc;YACrB,KAAK,EAAE,CAAC,CAAC,WAAW;YACpB,IAAI,EAAE,CAAC,CAAC,cAAc;YACtB,KAAK,EAAE,CAAC;SACT,CAAC,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAGpB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,yBAAyB;YAAE,OAAO;QACjD,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,wBAAwB,EAAE,EAAE,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,CAAC,KAAK,IAAI,EAAE;YACV,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,iCAAiC,CACnD,WAAW,CAAC,UAAU,EACtB,YAAY,CAAC,cAAc,EAC3B,YAAY,CAAC,WAAW,EACxB,WAAW,CAAC,MAAM,CACnB,CAAC;gBACF,IAAI,SAAS;oBAAE,OAAO;gBACtB,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,CAAU,EAAE,CAAC;gBACpB,IAAI,SAAS;oBAAE,OAAO;gBACtB,QAAQ,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACvD,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,SAAS;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEjG,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvB,GAAG,EAAE,CAAC,CAAC,EAAE;YACT,KAAK,EAAE,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,gBAAgB,EAAE;SAC/C,CAAC,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAG1B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,mBAAmB;YAAE,OAAO;QAC3C,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YACtI,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QAC1C,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QAC1C,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QAE1C,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,CAAC,KAAK,IAAI,EAAE;YACV,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YAE/C,MAAM,OAAO,GAA2D,EAAE,CAAC;YAE3E,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;gBAC3C,IAAI,SAAS;oBAAE,OAAO;gBACtB,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;gBACxD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;oBAC7D,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;oBACzD,SAAS;gBACX,CAAC;gBAED,MAAM,GAAG,GAA2B;oBAClC,WAAW,EAAE,WAAW,CAAC,MAAM;oBAC/B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;oBACvC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,gBAAgB,EAAE;oBACvD,yBAAyB,EAAE,IAAI,CAAC,yBAAyB;oBACzD,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,aAAa;oBACb,aAAa;iBACd,CAAC;gBAEF,IAAI,CAAC;oBACH,MAAM,iBAAiB,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;oBAClF,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrC,CAAC;gBAAC,OAAO,CAAU,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACzF,CAAC;gBAED,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3D,CAAC;YAED,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAGxJ,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAC,UAAU,IAAC,OAAO,EAAC,uBAAuB,EAAC,OAAO,EAAE,KAAK,GAAI,CAAC;IACxE,CAAC;IAED,IAAI,MAAM,KAAK,wBAAwB,EAAE,CAAC;QACxC,IAAI,SAAS,IAAI,CAAC,aAAa;YAAE,OAAO,KAAC,IAAI,IAAC,QAAQ,kDAA8B,CAAC;QACrF,IAAI,CAAC,aAAa;YAAE,OAAO,KAAC,IAAI,IAAC,QAAQ,oCAAgB,CAAC;QAC1D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAC,UAAU,IAAC,OAAO,EAAC,yBAAyB,GAAG,CAAC;QAExF,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,KAAC,IAAI,yCAA8B,EACnC,KAAC,UAAU,IACT,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;wBAChB,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;wBACpG,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,yBAAyB,EAAE,EAAE,CAAC,CAAC;oBACvE,CAAC,GACD,IACE,CACP,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,yBAAyB,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC;QAClC,IAAI,CAAC,KAAK,IAAI,SAAS;YAAE,OAAO,KAAC,IAAI,IAAC,QAAQ,mDAA+B,CAAC;QAC9E,IAAI,CAAC,KAAK;YAAE,OAAO,KAAC,IAAI,IAAC,QAAQ,oCAAgB,CAAC;QAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAC,UAAU,IAAC,OAAO,EAAC,gDAAgD,GAAG,CAAC;QAEvG,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,KAAC,IAAI,mDAAwC,EAC7C,KAAC,YAAY,IACX,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,CAAC,YAAY,EAAE,EAAE;wBACzB,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;4BAAE,OAAO;wBACtC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;wBACjE,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAC;oBACjE,CAAC,GACD,EACF,KAAC,IAAI,IAAC,QAAQ,8DAAqC,IAC/C,CACP,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,mBAAmB,EAAE,CAAC;QACnC,OAAO,CACL,KAAC,YAAY,IACX,KAAK,EAAC,0BAA0B,EAChC,YAAY,EAAE,KAAK,CAAC,aAAa,IAAI,CAAC,EACtC,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,CAAC,EACN,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;gBACxD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,wBAAwB,EAAE,EAAE,CAAC,CAAC;YACtE,CAAC,GACD,CACH,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,wBAAwB,EAAE,CAAC;QACxC,OAAO,CACL,KAAC,UAAU,IACT,KAAK,EAAC,gBAAgB,EACtB,YAAY,EAAE,KAAK,CAAC,aAAa,IAAI,uBAAuB,EAC5D,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,+CAA+C,CAAC,EAChG,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;gBACxD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;YAChE,CAAC,GACD,CACH,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,kBAAkB,EAAE,CAAC;QAClC,MAAM,gBAAgB,GAAG,KAAK,CAAC,YAAY,EAAE,WAAW,IAAI,WAAW,CAAC;QACxE,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,MAAC,IAAI,4BACM,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,CAAC,eAAe,CAAC,MAAM,GAAQ,kBAAY,KAAC,IAAI,IAAC,IAAI,kBAAE,gBAAgB,GAAQ,SACpG,EACP,MAAC,IAAI,IAAC,QAAQ,iCAAY,KAAK,CAAC,aAAa,IAAI,GAAG,SAAS,EAC7D,MAAC,IAAI,IAAC,QAAQ,sCAAiB,KAAK,CAAC,aAAa,IAAI,GAAG,IAAQ,EACjE,KAAC,aAAa,IACZ,OAAO,EAAC,qBAAqB,EAC7B,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,CAAC,EAC/E,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,GAC1C,IACE,CACP,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,mBAAmB,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;QAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;QAEjD,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,MAAC,IAAI,6BACQ,IAAI,OAAG,KAAK,YAAQ,EAAE,gBAAY,IAAI,SAC5C,EACP,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAC5B,MAAC,IAAI,IAAgB,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,aAC/C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAG,CAAC,CAAC,MAAM,KADnB,CAAC,CAAC,MAAM,CAEZ,CACR,CAAC,GACE,EACL,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,QAAQ,8CAA+B,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,QAAQ,oCAAgB,IAC1G,CACP,CAAC;IACJ,CAAC;IAED,OAAO,KAAC,IAAI,IAAC,QAAQ,+CAAgC,CAAC;AACxD,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { AuthContext } from "../../auth";
|
|
3
|
+
import { type ActiveAzureRole } from "../../azure-pim";
|
|
4
|
+
import type { NavigateAction, ScreenId } from "../router";
|
|
5
|
+
export type DeactivateFlowState = {
|
|
6
|
+
activeRoles?: ActiveAzureRole[];
|
|
7
|
+
selectedLinkedIds: string[];
|
|
8
|
+
results?: Array<{
|
|
9
|
+
linkedId: string;
|
|
10
|
+
ok: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
export type DeactivateFlowProps = {
|
|
15
|
+
authContext: AuthContext;
|
|
16
|
+
screen: ScreenId;
|
|
17
|
+
state: DeactivateFlowState;
|
|
18
|
+
setState: (updater: (prev: DeactivateFlowState) => DeactivateFlowState) => void;
|
|
19
|
+
navigate: (action: NavigateAction) => void;
|
|
20
|
+
};
|
|
21
|
+
export declare const DeactivateFlow: React.FC<DeactivateFlowProps>;
|
|
22
|
+
//# sourceMappingURL=DeactivateFlow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeactivateFlow.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/DeactivateFlow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1D,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,mBAAmB,KAAK,IAAI,CAAC;IAChF,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAsJxD,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { deactivateAzureRole, listActiveAzureRolesForUser, } from "../../azure-pim";
|
|
5
|
+
import { EmptyState, ErrorState } from "../components";
|
|
6
|
+
import { CheckboxList } from "../widgets/CheckboxList";
|
|
7
|
+
import { ConfirmPrompt } from "../widgets/ConfirmPrompt";
|
|
8
|
+
export const DeactivateFlow = ({ authContext, screen, state, setState, navigate }) => {
|
|
9
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
10
|
+
const [error, setError] = useState(null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (screen !== "deactivate/roles")
|
|
13
|
+
return;
|
|
14
|
+
let cancelled = false;
|
|
15
|
+
(async () => {
|
|
16
|
+
setIsLoading(true);
|
|
17
|
+
setError(null);
|
|
18
|
+
try {
|
|
19
|
+
const roles = await listActiveAzureRolesForUser(authContext.credential, authContext.userId);
|
|
20
|
+
if (cancelled)
|
|
21
|
+
return;
|
|
22
|
+
setState((prev) => ({ ...prev, activeRoles: roles }));
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
if (cancelled)
|
|
26
|
+
return;
|
|
27
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
if (!cancelled)
|
|
31
|
+
setIsLoading(false);
|
|
32
|
+
}
|
|
33
|
+
})();
|
|
34
|
+
return () => {
|
|
35
|
+
cancelled = true;
|
|
36
|
+
};
|
|
37
|
+
}, [screen, authContext.credential, authContext.userId, setState]);
|
|
38
|
+
const roleItems = useMemo(() => {
|
|
39
|
+
const roles = state.activeRoles ?? [];
|
|
40
|
+
return roles.map((r) => ({
|
|
41
|
+
key: r.linkedRoleEligibilityScheduleId,
|
|
42
|
+
label: `${r.roleName} — ${r.scopeDisplayName}`,
|
|
43
|
+
meta: `${r.subscriptionName} (${r.subscriptionId})`,
|
|
44
|
+
}));
|
|
45
|
+
}, [state.activeRoles]);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (screen !== "deactivate/progress")
|
|
48
|
+
return;
|
|
49
|
+
if (!state.activeRoles || state.selectedLinkedIds.length === 0) {
|
|
50
|
+
navigate({ type: "home" });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const activeRoles = state.activeRoles;
|
|
54
|
+
let cancelled = false;
|
|
55
|
+
(async () => {
|
|
56
|
+
setIsLoading(true);
|
|
57
|
+
setError(null);
|
|
58
|
+
setState((prev) => ({ ...prev, results: [] }));
|
|
59
|
+
const results = [];
|
|
60
|
+
for (const linkedId of state.selectedLinkedIds) {
|
|
61
|
+
if (cancelled)
|
|
62
|
+
return;
|
|
63
|
+
const role = activeRoles.find((r) => r.linkedRoleEligibilityScheduleId === linkedId);
|
|
64
|
+
if (!role) {
|
|
65
|
+
results.push({ linkedId, ok: false, error: "Role not found" });
|
|
66
|
+
setState((prev) => ({ ...prev, results: [...results] }));
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
await deactivateAzureRole(authContext.credential, role.scope, role.linkedRoleEligibilityScheduleId, role.subscriptionId, authContext.userId, role.roleDefinitionId);
|
|
71
|
+
results.push({ linkedId, ok: true });
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
results.push({ linkedId, ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
75
|
+
}
|
|
76
|
+
setState((prev) => ({ ...prev, results: [...results] }));
|
|
77
|
+
}
|
|
78
|
+
setIsLoading(false);
|
|
79
|
+
})();
|
|
80
|
+
return () => {
|
|
81
|
+
cancelled = true;
|
|
82
|
+
};
|
|
83
|
+
}, [screen, state.activeRoles, state.selectedLinkedIds, authContext, navigate, setState]);
|
|
84
|
+
if (error) {
|
|
85
|
+
return _jsx(ErrorState, { message: "Deactivation flow error", details: error });
|
|
86
|
+
}
|
|
87
|
+
if (screen === "deactivate/roles") {
|
|
88
|
+
const roles = state.activeRoles;
|
|
89
|
+
if (!roles && isLoading)
|
|
90
|
+
return _jsx(Text, { dimColor: true, children: "Loading active roles\u2026" });
|
|
91
|
+
if (!roles)
|
|
92
|
+
return _jsx(Text, { dimColor: true, children: "Loading\u2026" });
|
|
93
|
+
if (roles.length === 0)
|
|
94
|
+
return _jsx(EmptyState, { message: "No active roles found." });
|
|
95
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: "Select active roles to deactivate:" }), _jsx(CheckboxList, { items: roleItems, onSubmit: (selectedKeys) => {
|
|
96
|
+
if (selectedKeys.length === 0)
|
|
97
|
+
return;
|
|
98
|
+
setState((prev) => ({ ...prev, selectedLinkedIds: selectedKeys }));
|
|
99
|
+
navigate({ type: "push", route: { id: "deactivate/confirm" } });
|
|
100
|
+
} }), _jsx(Text, { dimColor: true, children: "Tip: press \u201Ca\u201D to toggle all." })] }));
|
|
101
|
+
}
|
|
102
|
+
if (screen === "deactivate/confirm") {
|
|
103
|
+
return (_jsx(ConfirmPrompt, { message: `Deactivate ${state.selectedLinkedIds.length} role(s)?`, onConfirm: () => navigate({ type: "push", route: { id: "deactivate/progress" } }), onCancel: () => navigate({ type: "back" }) }));
|
|
104
|
+
}
|
|
105
|
+
if (screen === "deactivate/progress") {
|
|
106
|
+
const results = state.results ?? [];
|
|
107
|
+
const total = state.selectedLinkedIds.length;
|
|
108
|
+
const done = results.length;
|
|
109
|
+
const ok = results.filter((r) => r.ok).length;
|
|
110
|
+
const fail = results.filter((r) => !r.ok).length;
|
|
111
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { children: ["Progress: ", done, "/", total, " (ok: ", ok, ", failed: ", fail, ")"] }), _jsx(Box, { flexDirection: "column", children: results.slice(-8).map((r) => (_jsxs(Text, { color: r.ok ? "green" : "red", children: [r.ok ? "✓" : "✗", " ", r.linkedId] }, r.linkedId))) }), done === total && !isLoading ? _jsx(Text, { dimColor: true, children: "Done. Press m for menu." }) : _jsx(Text, { dimColor: true, children: "Working\u2026" })] }));
|
|
112
|
+
}
|
|
113
|
+
return _jsx(Text, { dimColor: true, children: "Unknown deactivate screen." });
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=DeactivateFlow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeactivateFlow.js","sourceRoot":"","sources":["../../../src/ui/screens/DeactivateFlow.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useExitConfirmation.d.ts","sourceRoot":"","sources":["../../src/ui/useExitConfirmation.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,SAkBtC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
export const useExitConfirmation = () => {
|
|
3
|
+
const [isExitConfirmOpen, setIsExitConfirmOpen] = useState(false);
|
|
4
|
+
const openExitConfirm = () => setIsExitConfirmOpen(true);
|
|
5
|
+
const closeExitConfirm = () => setIsExitConfirmOpen(false);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const onSigint = () => {
|
|
8
|
+
setIsExitConfirmOpen(true);
|
|
9
|
+
};
|
|
10
|
+
process.on("SIGINT", onSigint);
|
|
11
|
+
return () => {
|
|
12
|
+
process.off("SIGINT", onSigint);
|
|
13
|
+
};
|
|
14
|
+
}, []);
|
|
15
|
+
return { isExitConfirmOpen, openExitConfirm, closeExitConfirm };
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useExitConfirmation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useExitConfirmation.js","sourceRoot":"","sources":["../../src/ui/useExitConfirmation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAQ5C,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAc,EAAE;IACjD,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElE,MAAM,eAAe,GAAG,GAAS,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,gBAAgB,GAAG,GAAS,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,GAAS,EAAE;YAC1B,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC;AAClE,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type CheckboxItem = {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
meta?: string;
|
|
6
|
+
};
|
|
7
|
+
export type CheckboxListProps = {
|
|
8
|
+
items: CheckboxItem[];
|
|
9
|
+
isLoading?: boolean;
|
|
10
|
+
emptyLabel?: string;
|
|
11
|
+
onSubmit: (selectedKeys: string[]) => void;
|
|
12
|
+
};
|
|
13
|
+
export declare const CheckboxList: React.FC<CheckboxListProps>;
|
|
14
|
+
//# sourceMappingURL=CheckboxList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckboxList.d.ts","sourceRoot":"","sources":["../../../src/ui/widgets/CheckboxList.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA4FpD,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from "ink";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
|
+
export const CheckboxList = ({ items, isLoading, emptyLabel, onSubmit }) => {
|
|
5
|
+
const [cursor, setCursor] = useState(0);
|
|
6
|
+
const [selected, setSelected] = useState({});
|
|
7
|
+
const safeItems = useMemo(() => items ?? [], [items]);
|
|
8
|
+
const maxIndex = Math.max(0, safeItems.length - 1);
|
|
9
|
+
const selectedKeys = useMemo(() => Object.keys(selected).filter((k) => selected[k]), [selected]);
|
|
10
|
+
useInput((input, key) => {
|
|
11
|
+
if (isLoading)
|
|
12
|
+
return;
|
|
13
|
+
if (safeItems.length === 0)
|
|
14
|
+
return;
|
|
15
|
+
if (key.upArrow)
|
|
16
|
+
setCursor((i) => (i <= 0 ? maxIndex : i - 1));
|
|
17
|
+
if (key.downArrow)
|
|
18
|
+
setCursor((i) => (i >= maxIndex ? 0 : i + 1));
|
|
19
|
+
if (input === " ") {
|
|
20
|
+
const item = safeItems[cursor];
|
|
21
|
+
if (!item)
|
|
22
|
+
return;
|
|
23
|
+
setSelected((prev) => ({ ...prev, [item.key]: !prev[item.key] }));
|
|
24
|
+
}
|
|
25
|
+
if (input === "a") {
|
|
26
|
+
const allSelected = safeItems.every((it) => selected[it.key]);
|
|
27
|
+
if (allSelected) {
|
|
28
|
+
setSelected({});
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const next = {};
|
|
32
|
+
for (const it of safeItems)
|
|
33
|
+
next[it.key] = true;
|
|
34
|
+
setSelected(next);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (input === "i") {
|
|
38
|
+
const next = {};
|
|
39
|
+
for (const it of safeItems)
|
|
40
|
+
next[it.key] = !selected[it.key];
|
|
41
|
+
setSelected(next);
|
|
42
|
+
}
|
|
43
|
+
if (key.return) {
|
|
44
|
+
onSubmit(selectedKeys);
|
|
45
|
+
}
|
|
46
|
+
}, { isActive: !isLoading });
|
|
47
|
+
if (isLoading) {
|
|
48
|
+
return (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Loading\u2026" }) }));
|
|
49
|
+
}
|
|
50
|
+
if (safeItems.length === 0) {
|
|
51
|
+
return (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: emptyLabel ?? "No items." }) }));
|
|
52
|
+
}
|
|
53
|
+
return (_jsxs(Box, { flexDirection: "column", children: [safeItems.map((item, i) => {
|
|
54
|
+
const isActive = i === cursor;
|
|
55
|
+
const isChecked = !!selected[item.key];
|
|
56
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: isActive ? "green" : undefined, children: isActive ? "❯" : " " }), _jsx(Text, { children: " " }), _jsx(Text, { children: isChecked ? "◉" : "◯" }), _jsx(Text, { children: " " }), _jsx(Text, { children: item.label }), item.meta ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: item.meta })] })) : null] }, item.key));
|
|
57
|
+
}), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate \u00B7 Space toggle \u00B7 a all \u00B7 i invert \u00B7 Enter submit" }) }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["Selected: ", selectedKeys.length] }) })] }));
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=CheckboxList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckboxList.js","sourceRoot":"","sources":["../../../src/ui/widgets/CheckboxList.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAejD,MAAM,CAAC,MAAM,YAAY,GAAgC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;IACtG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAA0B,EAAE,CAAC,CAAC;IAEtE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEjG,QAAQ,CACN,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACb,IAAI,SAAS;YAAE,OAAO;QACtB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEnC,IAAI,GAAG,CAAC,OAAO;YAAE,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/D,IAAI,GAAG,CAAC,SAAS;YAAE,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEjE,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9D,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAA4B,EAAE,CAAC;gBACzC,KAAK,MAAM,EAAE,IAAI,SAAS;oBAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBAChD,WAAW,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;QAED,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,MAAM,IAAI,GAA4B,EAAE,CAAC;YACzC,KAAK,MAAM,EAAE,IAAI,SAAS;gBAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;YAC7D,WAAW,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,QAAQ,CAAC,YAAY,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,EACD,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,CACzB,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CACL,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,QAAQ,oCAAgB,GAC1B,CACP,CAAC;IACJ,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CACL,KAAC,GAAG,cACF,KAAC,IAAI,IAAC,QAAQ,kBAAE,UAAU,IAAI,WAAW,GAAQ,GAC7C,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACzB,MAAM,QAAQ,GAAG,CAAC,KAAK,MAAM,CAAC;gBAC9B,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACvC,OAAO,CACL,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,YAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAQ,EAC1E,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,cAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAQ,EACpC,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,cAAE,IAAI,CAAC,KAAK,GAAQ,EACxB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CACX,8BACE,KAAC,IAAI,oBAAS,EACd,KAAC,IAAI,IAAC,QAAQ,kBAAE,IAAI,CAAC,IAAI,GAAQ,IAChC,CACJ,CAAC,CAAC,CAAC,IAAI,KAXA,IAAI,CAAC,GAAG,CAYZ,CACP,CAAC;YACJ,CAAC,CAAC,EACF,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,QAAQ,iHAAoE,GAC9E,EACN,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,QAAQ,iCAAY,YAAY,CAAC,MAAM,IAAQ,GACjD,IACF,CACP,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmPrompt.d.ts","sourceRoot":"","sources":["../../../src/ui/widgets/ConfirmPrompt.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuBtD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from "ink";
|
|
3
|
+
export const ConfirmPrompt = ({ message, onConfirm, onCancel }) => {
|
|
4
|
+
useInput((input, key) => {
|
|
5
|
+
if (key.return) {
|
|
6
|
+
onConfirm();
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (input.toLowerCase() === "y") {
|
|
10
|
+
onConfirm();
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (input.toLowerCase() === "n") {
|
|
14
|
+
onCancel();
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: message }), _jsx(Text, { dimColor: true, children: "y = confirm \u00B7 n = cancel \u00B7 Enter = confirm" })] }));
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=ConfirmPrompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmPrompt.js","sourceRoot":"","sources":["../../../src/ui/widgets/ConfirmPrompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAS1C,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC9F,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YAChC,SAAS,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YAChC,QAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,KAAC,IAAI,cAAE,OAAO,GAAQ,EACtB,KAAC,IAAI,IAAC,QAAQ,2EAAkD,IAC5D,CACP,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type NumberPromptProps = {
|
|
3
|
+
label: string;
|
|
4
|
+
initialValue?: number;
|
|
5
|
+
min?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
onSubmit: (value: number) => void;
|
|
8
|
+
};
|
|
9
|
+
export declare const NumberPrompt: React.FC<NumberPromptProps>;
|
|
10
|
+
//# sourceMappingURL=NumberPrompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NumberPrompt.d.ts","sourceRoot":"","sources":["../../../src/ui/widgets/NumberPrompt.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8CpD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from "ink";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
export const NumberPrompt = ({ label, initialValue, min, max, onSubmit }) => {
|
|
5
|
+
const [value, setValue] = useState(initialValue ?? 0);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
useInput((input, key) => {
|
|
8
|
+
if (key.upArrow)
|
|
9
|
+
setValue((v) => v + 1);
|
|
10
|
+
if (key.downArrow)
|
|
11
|
+
setValue((v) => v - 1);
|
|
12
|
+
if (input >= "0" && input <= "9") {
|
|
13
|
+
setValue((v) => {
|
|
14
|
+
const next = Number(String(v) === "0" ? input : `${v}${input}`);
|
|
15
|
+
return Number.isFinite(next) ? next : v;
|
|
16
|
+
});
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (key.backspace || key.delete) {
|
|
20
|
+
setValue((v) => Math.floor(v / 10));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (key.return) {
|
|
24
|
+
if (min !== undefined && value < min) {
|
|
25
|
+
setError(`Must be ≥ ${min}`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (max !== undefined && value > max) {
|
|
29
|
+
setError(`Must be ≤ ${max}`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
setError(null);
|
|
33
|
+
onSubmit(value);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: label }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "\u203A " }), _jsx(Text, { children: value })] }), error ? _jsx(Text, { color: "red", children: error }) : null, _jsx(Text, { dimColor: true, children: "Digits / \u2191\u2193 adjust / Backspace / Enter submit" })] }));
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=NumberPrompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NumberPrompt.js","sourceRoot":"","sources":["../../../src/ui/widgets/NumberPrompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAUxC,MAAM,CAAC,MAAM,YAAY,GAAgC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE;IACvG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,YAAY,IAAI,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO;YAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,IAAI,GAAG,CAAC,SAAS;YAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAE1C,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE;gBACb,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;gBAChE,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAChC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;gBACrC,QAAQ,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;gBACrC,QAAQ,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,KAAC,IAAI,cAAE,KAAK,GAAQ,EACpB,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wBAAU,EAC5B,KAAC,IAAI,cAAE,KAAK,GAAQ,IACf,EACN,KAAK,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,YAAE,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI,EAChD,KAAC,IAAI,IAAC,QAAQ,8EAAqD,IAC/D,CACP,CAAC;AACJ,CAAC,CAAC"}
|