@tutti-os/workspace-user-project 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/LICENSE +202 -0
- package/README.md +14 -0
- package/dist/chunk-JUPVLSYH.js +134 -0
- package/dist/chunk-JUPVLSYH.js.map +1 -0
- package/dist/chunk-P4PYYT3Y.js +97 -0
- package/dist/chunk-P4PYYT3Y.js.map +1 -0
- package/dist/contracts/index.d.ts +101 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.js +19 -0
- package/dist/core/index.js.map +1 -0
- package/dist/i18n/index.d.ts +65 -0
- package/dist/i18n/index.js +15 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/index.d.ts +60 -0
- package/dist/ui/index.js +575 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +69 -0
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
import {
|
|
2
|
+
basenameWorkspaceUserProjectPath,
|
|
3
|
+
getWorkspaceUserProjectErrorCode,
|
|
4
|
+
prepareWorkspaceUserProjectSelection,
|
|
5
|
+
resolveWorkspaceUserProjectDisplayLabel,
|
|
6
|
+
upsertWorkspaceUserProject
|
|
7
|
+
} from "../chunk-JUPVLSYH.js";
|
|
8
|
+
import {
|
|
9
|
+
createDefaultWorkspaceUserProjectI18nRuntime
|
|
10
|
+
} from "../chunk-P4PYYT3Y.js";
|
|
11
|
+
|
|
12
|
+
// src/ui/internal/project/WorkspaceUserProjectSelect.tsx
|
|
13
|
+
import {
|
|
14
|
+
useCallback,
|
|
15
|
+
useEffect,
|
|
16
|
+
useEffectEvent,
|
|
17
|
+
useMemo,
|
|
18
|
+
useState
|
|
19
|
+
} from "react";
|
|
20
|
+
import { useSnapshot } from "valtio";
|
|
21
|
+
import { proxy } from "valtio/vanilla";
|
|
22
|
+
import {
|
|
23
|
+
Button,
|
|
24
|
+
Dialog,
|
|
25
|
+
DialogContent,
|
|
26
|
+
DialogDescription,
|
|
27
|
+
DialogFooter,
|
|
28
|
+
DialogHeader,
|
|
29
|
+
DialogTitle,
|
|
30
|
+
FolderIcon,
|
|
31
|
+
Input,
|
|
32
|
+
LinkIcon,
|
|
33
|
+
NewWorkspaceLinedIcon,
|
|
34
|
+
NoWorkspaceLinedIcon,
|
|
35
|
+
Select,
|
|
36
|
+
SelectContent,
|
|
37
|
+
SelectItem,
|
|
38
|
+
SelectSeparator,
|
|
39
|
+
SelectTrigger
|
|
40
|
+
} from "@tutti-os/ui-system";
|
|
41
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
42
|
+
var noProjectOptionValue = "__nextop_no_project__";
|
|
43
|
+
var addProjectOptionValue = "__nextop_add_project__";
|
|
44
|
+
var linkExistingProjectOptionValue = "__nextop_link_existing_project__";
|
|
45
|
+
var defaultWorkspaceUserProjectSelectI18n = createDefaultWorkspaceUserProjectI18nRuntime();
|
|
46
|
+
var emptyWorkspaceUserProjectServiceSnapshot = proxy({
|
|
47
|
+
error: null,
|
|
48
|
+
initialized: false,
|
|
49
|
+
isLoading: false,
|
|
50
|
+
projects: [],
|
|
51
|
+
revision: 0
|
|
52
|
+
});
|
|
53
|
+
function WorkspaceUserProjectSelect({
|
|
54
|
+
api,
|
|
55
|
+
classNames,
|
|
56
|
+
contentAlign = "start",
|
|
57
|
+
contentSide = "top",
|
|
58
|
+
contentSideOffset = 4,
|
|
59
|
+
disabled: disabledProp = false,
|
|
60
|
+
i18n = defaultWorkspaceUserProjectSelectI18n,
|
|
61
|
+
labels,
|
|
62
|
+
onProjectMissingChange,
|
|
63
|
+
onProjectPathChange,
|
|
64
|
+
projectLocked = false,
|
|
65
|
+
renderAddProjectIcon,
|
|
66
|
+
shouldApplyPreparedSelection = true,
|
|
67
|
+
showKnownProjectOptions = true,
|
|
68
|
+
service,
|
|
69
|
+
selectedProjectPath,
|
|
70
|
+
showCreateProjectAction = hasWorkspaceUserProjectMethod(
|
|
71
|
+
service,
|
|
72
|
+
"createProject"
|
|
73
|
+
) || hasWorkspaceUserProjectMethod(api, "create"),
|
|
74
|
+
showNoProjectAction = true,
|
|
75
|
+
unlistedProjectLabel
|
|
76
|
+
}) {
|
|
77
|
+
"use memo";
|
|
78
|
+
const serviceSnapshot = useSnapshot(
|
|
79
|
+
service?.store ?? emptyWorkspaceUserProjectServiceSnapshot
|
|
80
|
+
);
|
|
81
|
+
const effectiveApi = useMemo(
|
|
82
|
+
() => createWorkspaceUserProjectApiAdapter(api, service),
|
|
83
|
+
[api, service]
|
|
84
|
+
);
|
|
85
|
+
const resolvedLabels = useMemo(
|
|
86
|
+
() => resolveWorkspaceUserProjectSelectLabels(i18n, labels),
|
|
87
|
+
[i18n, labels]
|
|
88
|
+
);
|
|
89
|
+
const [apiProjects, setApiProjects] = useState([]);
|
|
90
|
+
const [isApiLoading, setIsApiLoading] = useState(false);
|
|
91
|
+
const [isApiUnavailable, setIsApiUnavailable] = useState(!effectiveApi);
|
|
92
|
+
const [isProjectDialogOpen, setIsProjectDialogOpen] = useState(false);
|
|
93
|
+
const [draftProjectName, setDraftProjectName] = useState("");
|
|
94
|
+
const [projectCreationError, setProjectCreationError] = useState(null);
|
|
95
|
+
const [isCreatingProject, setIsCreatingProject] = useState(false);
|
|
96
|
+
const [suppressedSelectedPath, setSuppressedSelectedPath] = useState(null);
|
|
97
|
+
const [hasPinnedNoProjectSelection, setHasPinnedNoProjectSelection] = useState(false);
|
|
98
|
+
const [isSelectedPathMissing, setIsSelectedPathMissing] = useState(false);
|
|
99
|
+
const rawSelectedPath = selectedProjectPath?.trim() ?? "";
|
|
100
|
+
const selectedPath = rawSelectedPath && rawSelectedPath === suppressedSelectedPath ? "" : rawSelectedPath;
|
|
101
|
+
const projects = service ? [...serviceSnapshot.projects] : apiProjects;
|
|
102
|
+
const visibleProjects = showKnownProjectOptions ? projects : [];
|
|
103
|
+
const isLoading = service ? serviceSnapshot.isLoading && !serviceSnapshot.initialized : isApiLoading;
|
|
104
|
+
const isUnavailable = service ? Boolean(serviceSnapshot.error) && !serviceSnapshot.initialized : isApiUnavailable;
|
|
105
|
+
const selectedPathLabel = basenameWorkspaceUserProjectPath(selectedPath) || selectedPath;
|
|
106
|
+
const selectedProject = showKnownProjectOptions ? projects.find((project) => project.path === selectedPath) ?? null : null;
|
|
107
|
+
const selectedProjectLabel = selectedProject ? resolveWorkspaceUserProjectDisplayLabel(selectedProject) : "";
|
|
108
|
+
const isSelectedNoProjectPath = projectLocked && Boolean(selectedPath) && Boolean(effectiveApi?.isNoProjectPath?.({ path: selectedPath }));
|
|
109
|
+
const shouldShowMissingProjectNotice = isSelectedPathMissing;
|
|
110
|
+
const shouldShowLockedProjectPath = projectLocked && selectedPath !== "" && !isSelectedNoProjectPath && !selectedProject && !isSelectedPathMissing;
|
|
111
|
+
const selectValue = selectedProject ? selectedProject.path : noProjectOptionValue;
|
|
112
|
+
const triggerLabel = shouldShowMissingProjectNotice ? resolvedLabels.projectMissingTitle : isSelectedNoProjectPath ? resolvedLabels.noProject : shouldShowLockedProjectPath ? selectedPathLabel : selectedProject ? selectedProjectLabel : selectedPath ? unlistedProjectLabel || selectedPathLabel : isLoading ? resolvedLabels.loadingProjects : resolvedLabels.noProject;
|
|
113
|
+
const shouldDisableWhileLoading = showKnownProjectOptions || shouldApplyPreparedSelection;
|
|
114
|
+
const disabled = disabledProp || projectLocked || shouldDisableWhileLoading && isLoading || !effectiveApi;
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
onProjectMissingChange?.(shouldShowMissingProjectNotice);
|
|
117
|
+
}, [onProjectMissingChange, shouldShowMissingProjectNotice]);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (rawSelectedPath) {
|
|
120
|
+
setHasPinnedNoProjectSelection(false);
|
|
121
|
+
}
|
|
122
|
+
if (suppressedSelectedPath && (!rawSelectedPath || rawSelectedPath !== suppressedSelectedPath)) {
|
|
123
|
+
setSuppressedSelectedPath(null);
|
|
124
|
+
}
|
|
125
|
+
}, [rawSelectedPath, suppressedSelectedPath]);
|
|
126
|
+
const applyPreparedSelection = useEffectEvent(
|
|
127
|
+
(prepared) => {
|
|
128
|
+
if (!service) {
|
|
129
|
+
setApiProjects(prepared.projects);
|
|
130
|
+
}
|
|
131
|
+
setIsSelectedPathMissing(prepared.isSelectedPathMissing);
|
|
132
|
+
if (!shouldApplyPreparedSelection) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (prepared.selection.kind === "clear") {
|
|
136
|
+
setHasPinnedNoProjectSelection(true);
|
|
137
|
+
setSuppressedSelectedPath(prepared.selection.suppressedPath);
|
|
138
|
+
onProjectPathChange(null);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (prepared.selection.kind === "select") {
|
|
142
|
+
setHasPinnedNoProjectSelection(false);
|
|
143
|
+
onProjectPathChange(prepared.selection.path);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
let canceled = false;
|
|
149
|
+
if (!effectiveApi) {
|
|
150
|
+
setApiUnavailableUnlessService(setIsApiUnavailable, service);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (hasPinnedNoProjectSelection) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
setIsApiLoading(true);
|
|
157
|
+
setApiUnavailableUnlessService(setIsApiUnavailable, service, false);
|
|
158
|
+
const input = {
|
|
159
|
+
projectLocked,
|
|
160
|
+
selectedPath
|
|
161
|
+
};
|
|
162
|
+
void prepareWorkspaceUserProjectSelection(effectiveApi, input).then((prepared) => {
|
|
163
|
+
if (!canceled) {
|
|
164
|
+
applyPreparedSelection(prepared);
|
|
165
|
+
}
|
|
166
|
+
}).catch(() => {
|
|
167
|
+
if (!canceled) {
|
|
168
|
+
setApiUnavailableUnlessService(setIsApiUnavailable, service);
|
|
169
|
+
}
|
|
170
|
+
}).finally(() => {
|
|
171
|
+
if (!canceled) {
|
|
172
|
+
setIsApiLoading(false);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
return () => {
|
|
176
|
+
canceled = true;
|
|
177
|
+
};
|
|
178
|
+
}, [
|
|
179
|
+
effectiveApi,
|
|
180
|
+
hasPinnedNoProjectSelection,
|
|
181
|
+
projectLocked,
|
|
182
|
+
selectedPath,
|
|
183
|
+
serviceSnapshot.revision,
|
|
184
|
+
service
|
|
185
|
+
]);
|
|
186
|
+
const refreshPreparedSelection = useCallback(() => {
|
|
187
|
+
if (!effectiveApi) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const input = {
|
|
191
|
+
projectLocked,
|
|
192
|
+
selectedPath
|
|
193
|
+
};
|
|
194
|
+
void prepareWorkspaceUserProjectSelection(effectiveApi, input).then(
|
|
195
|
+
applyPreparedSelection,
|
|
196
|
+
() => {
|
|
197
|
+
setApiUnavailableUnlessService(setIsApiUnavailable, service);
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}, [
|
|
201
|
+
effectiveApi,
|
|
202
|
+
projectLocked,
|
|
203
|
+
selectedPath,
|
|
204
|
+
service,
|
|
205
|
+
shouldApplyPreparedSelection
|
|
206
|
+
]);
|
|
207
|
+
const useProjectPath = useCallback(
|
|
208
|
+
async (path, action) => {
|
|
209
|
+
if (!effectiveApi) {
|
|
210
|
+
setApiUnavailableUnlessService(setIsApiUnavailable, service);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const project = await effectiveApi.use?.({ path }) ?? {
|
|
215
|
+
id: path,
|
|
216
|
+
label: path,
|
|
217
|
+
path
|
|
218
|
+
};
|
|
219
|
+
setApiProjects(
|
|
220
|
+
(current) => upsertWorkspaceUserProject(current, project)
|
|
221
|
+
);
|
|
222
|
+
setHasPinnedNoProjectSelection(false);
|
|
223
|
+
onProjectPathChange(project.path, { action });
|
|
224
|
+
refreshPreparedSelection();
|
|
225
|
+
} catch {
|
|
226
|
+
setApiUnavailableUnlessService(setIsApiUnavailable, service);
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
[effectiveApi, onProjectPathChange, refreshPreparedSelection, service]
|
|
230
|
+
);
|
|
231
|
+
const createProject = useCallback(async () => {
|
|
232
|
+
const name = draftProjectName.trim();
|
|
233
|
+
if (!effectiveApi?.create) {
|
|
234
|
+
setProjectCreationError(resolvedLabels.createProjectFailed);
|
|
235
|
+
setApiUnavailableUnlessService(setIsApiUnavailable, service);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (!name) {
|
|
239
|
+
setProjectCreationError(resolvedLabels.createProjectNameRequired);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
setIsCreatingProject(true);
|
|
243
|
+
setProjectCreationError(null);
|
|
244
|
+
try {
|
|
245
|
+
const project = await effectiveApi.create({ name });
|
|
246
|
+
setApiProjects((current) => upsertWorkspaceUserProject(current, project));
|
|
247
|
+
setHasPinnedNoProjectSelection(false);
|
|
248
|
+
onProjectPathChange(project.path, { action: "create_new" });
|
|
249
|
+
setDraftProjectName("");
|
|
250
|
+
setIsProjectDialogOpen(false);
|
|
251
|
+
refreshPreparedSelection();
|
|
252
|
+
} catch (error) {
|
|
253
|
+
setProjectCreationError(
|
|
254
|
+
resolveProjectCreationErrorLabel(error, resolvedLabels)
|
|
255
|
+
);
|
|
256
|
+
} finally {
|
|
257
|
+
setIsCreatingProject(false);
|
|
258
|
+
}
|
|
259
|
+
}, [
|
|
260
|
+
effectiveApi,
|
|
261
|
+
draftProjectName,
|
|
262
|
+
onProjectPathChange,
|
|
263
|
+
refreshPreparedSelection,
|
|
264
|
+
resolvedLabels,
|
|
265
|
+
service
|
|
266
|
+
]);
|
|
267
|
+
const submitProjectDialog = (event) => {
|
|
268
|
+
event.preventDefault();
|
|
269
|
+
void createProject();
|
|
270
|
+
};
|
|
271
|
+
const closeProjectDialog = () => {
|
|
272
|
+
setIsProjectDialogOpen(false);
|
|
273
|
+
setProjectCreationError(null);
|
|
274
|
+
};
|
|
275
|
+
const handleProjectValueChange = (nextValue) => {
|
|
276
|
+
if (!effectiveApi || projectLocked) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (nextValue === noProjectOptionValue) {
|
|
280
|
+
void effectiveApi.rememberDefaultSelection?.({ path: null });
|
|
281
|
+
setHasPinnedNoProjectSelection(true);
|
|
282
|
+
onProjectPathChange(null, { action: "clear" });
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (nextValue === addProjectOptionValue) {
|
|
286
|
+
setDraftProjectName("");
|
|
287
|
+
setProjectCreationError(null);
|
|
288
|
+
setIsProjectDialogOpen(true);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (nextValue === linkExistingProjectOptionValue) {
|
|
292
|
+
void Promise.resolve(effectiveApi.selectDirectory?.()).then((selection) => {
|
|
293
|
+
const path = selection?.path?.trim() ?? "";
|
|
294
|
+
if (!path) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
void useProjectPath(path, "select_existing");
|
|
298
|
+
}).catch(() => {
|
|
299
|
+
});
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
void useProjectPath(nextValue, "select_existing");
|
|
303
|
+
};
|
|
304
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
305
|
+
/* @__PURE__ */ jsxs(
|
|
306
|
+
Select,
|
|
307
|
+
{
|
|
308
|
+
disabled,
|
|
309
|
+
value: selectValue,
|
|
310
|
+
onValueChange: handleProjectValueChange,
|
|
311
|
+
children: [
|
|
312
|
+
/* @__PURE__ */ jsx(
|
|
313
|
+
SelectTrigger,
|
|
314
|
+
{
|
|
315
|
+
"aria-label": projectLocked ? resolvedLabels.projectLocked : isUnavailable ? resolvedLabels.projectUnavailable : resolvedLabels.projectLabel,
|
|
316
|
+
className: classNames?.trigger,
|
|
317
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
318
|
+
selectedProject || shouldShowLockedProjectPath ? /* @__PURE__ */ jsx(FolderIcon, { "aria-hidden": true, className: "shrink-0", size: 15 }) : /* @__PURE__ */ jsx(
|
|
319
|
+
NoWorkspaceLinedIcon,
|
|
320
|
+
{
|
|
321
|
+
"aria-hidden": true,
|
|
322
|
+
className: "shrink-0",
|
|
323
|
+
"data-agent-project-trigger-no-workspace-icon": "true",
|
|
324
|
+
size: 15
|
|
325
|
+
}
|
|
326
|
+
),
|
|
327
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: triggerLabel })
|
|
328
|
+
] })
|
|
329
|
+
}
|
|
330
|
+
),
|
|
331
|
+
/* @__PURE__ */ jsxs(
|
|
332
|
+
SelectContent,
|
|
333
|
+
{
|
|
334
|
+
align: contentAlign,
|
|
335
|
+
className: classNames?.content,
|
|
336
|
+
collisionPadding: 16,
|
|
337
|
+
side: contentSide,
|
|
338
|
+
sideOffset: contentSideOffset,
|
|
339
|
+
children: [
|
|
340
|
+
visibleProjects.map((project) => {
|
|
341
|
+
const projectLabel = resolveWorkspaceUserProjectDisplayLabel(project);
|
|
342
|
+
return /* @__PURE__ */ jsx(
|
|
343
|
+
SelectItem,
|
|
344
|
+
{
|
|
345
|
+
className: classNames?.item,
|
|
346
|
+
value: project.path,
|
|
347
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
|
|
348
|
+
/* @__PURE__ */ jsx(FolderIcon, { "aria-hidden": true, size: 15 }),
|
|
349
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: /* @__PURE__ */ jsx("span", { children: projectLabel }) })
|
|
350
|
+
] })
|
|
351
|
+
},
|
|
352
|
+
project.id || project.path
|
|
353
|
+
);
|
|
354
|
+
}),
|
|
355
|
+
visibleProjects.length > 0 ? /* @__PURE__ */ jsx(SelectSeparator, {}) : null,
|
|
356
|
+
effectiveApi?.selectDirectory ? /* @__PURE__ */ jsx(
|
|
357
|
+
SelectItem,
|
|
358
|
+
{
|
|
359
|
+
className: classNames?.item,
|
|
360
|
+
value: linkExistingProjectOptionValue,
|
|
361
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
|
|
362
|
+
/* @__PURE__ */ jsx(LinkIcon, { "aria-hidden": true, size: 15 }),
|
|
363
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: resolvedLabels.linkExistingProject })
|
|
364
|
+
] })
|
|
365
|
+
}
|
|
366
|
+
) : null,
|
|
367
|
+
showCreateProjectAction ? /* @__PURE__ */ jsx(
|
|
368
|
+
SelectItem,
|
|
369
|
+
{
|
|
370
|
+
className: classNames?.item,
|
|
371
|
+
value: addProjectOptionValue,
|
|
372
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
|
|
373
|
+
renderAddProjectIcon?.() ?? /* @__PURE__ */ jsx(
|
|
374
|
+
NewWorkspaceLinedIcon,
|
|
375
|
+
{
|
|
376
|
+
"aria-hidden": true,
|
|
377
|
+
"data-workspace-user-project-add-icon": "true",
|
|
378
|
+
size: 15
|
|
379
|
+
}
|
|
380
|
+
),
|
|
381
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: resolvedLabels.addProject })
|
|
382
|
+
] })
|
|
383
|
+
}
|
|
384
|
+
) : null,
|
|
385
|
+
showNoProjectAction ? /* @__PURE__ */ jsx(
|
|
386
|
+
SelectItem,
|
|
387
|
+
{
|
|
388
|
+
className: classNames?.item,
|
|
389
|
+
value: noProjectOptionValue,
|
|
390
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
|
|
391
|
+
/* @__PURE__ */ jsx(
|
|
392
|
+
NoWorkspaceLinedIcon,
|
|
393
|
+
{
|
|
394
|
+
"aria-hidden": true,
|
|
395
|
+
"data-agent-project-no-workspace-icon": "true",
|
|
396
|
+
size: 15
|
|
397
|
+
}
|
|
398
|
+
),
|
|
399
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: resolvedLabels.noProject })
|
|
400
|
+
] })
|
|
401
|
+
}
|
|
402
|
+
) : null
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
)
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
),
|
|
409
|
+
isProjectDialogOpen ? /* @__PURE__ */ jsx(
|
|
410
|
+
Dialog,
|
|
411
|
+
{
|
|
412
|
+
open: true,
|
|
413
|
+
onOpenChange: (nextOpen) => !nextOpen && closeProjectDialog(),
|
|
414
|
+
children: /* @__PURE__ */ jsx(
|
|
415
|
+
DialogContent,
|
|
416
|
+
{
|
|
417
|
+
className: "w-[480px] max-w-[calc(100vw-32px)] sm:max-w-[480px]",
|
|
418
|
+
showCloseButton: false,
|
|
419
|
+
children: /* @__PURE__ */ jsxs("form", { className: "grid gap-4", onSubmit: submitProjectDialog, children: [
|
|
420
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
421
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: resolvedLabels.createProjectTitle }),
|
|
422
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: resolvedLabels.createProjectNameLabel })
|
|
423
|
+
] }),
|
|
424
|
+
/* @__PURE__ */ jsxs("label", { className: "grid gap-1.5", children: [
|
|
425
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: resolvedLabels.createProjectNameLabel }),
|
|
426
|
+
/* @__PURE__ */ jsx(
|
|
427
|
+
Input,
|
|
428
|
+
{
|
|
429
|
+
autoFocus: true,
|
|
430
|
+
className: "h-10",
|
|
431
|
+
disabled: isCreatingProject,
|
|
432
|
+
placeholder: resolvedLabels.createProjectNamePlaceholder,
|
|
433
|
+
value: draftProjectName,
|
|
434
|
+
onChange: (event) => {
|
|
435
|
+
setDraftProjectName(event.target.value);
|
|
436
|
+
if (projectCreationError) {
|
|
437
|
+
setProjectCreationError(null);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
)
|
|
442
|
+
] }),
|
|
443
|
+
projectCreationError ? /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--state-danger)]", children: projectCreationError }) : null,
|
|
444
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
445
|
+
/* @__PURE__ */ jsx(
|
|
446
|
+
Button,
|
|
447
|
+
{
|
|
448
|
+
disabled: isCreatingProject,
|
|
449
|
+
size: "dialog",
|
|
450
|
+
type: "button",
|
|
451
|
+
variant: "secondary",
|
|
452
|
+
onClick: closeProjectDialog,
|
|
453
|
+
onPointerDown: (event) => {
|
|
454
|
+
if (event.button === 0 && !isCreatingProject) {
|
|
455
|
+
closeProjectDialog();
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
children: resolvedLabels.createProjectCancel
|
|
459
|
+
}
|
|
460
|
+
),
|
|
461
|
+
/* @__PURE__ */ jsx(
|
|
462
|
+
Button,
|
|
463
|
+
{
|
|
464
|
+
disabled: isCreatingProject || !draftProjectName.trim(),
|
|
465
|
+
size: "dialog",
|
|
466
|
+
type: "submit",
|
|
467
|
+
children: resolvedLabels.createProjectConfirm
|
|
468
|
+
}
|
|
469
|
+
)
|
|
470
|
+
] })
|
|
471
|
+
] })
|
|
472
|
+
}
|
|
473
|
+
)
|
|
474
|
+
}
|
|
475
|
+
) : null
|
|
476
|
+
] });
|
|
477
|
+
}
|
|
478
|
+
function createWorkspaceUserProjectApiAdapter(api, service) {
|
|
479
|
+
if (!service) {
|
|
480
|
+
return api ?? null;
|
|
481
|
+
}
|
|
482
|
+
const apiCheckPath = hasWorkspaceUserProjectMethod(api, "checkPath") ? (input) => api.checkPath(input) : void 0;
|
|
483
|
+
const apiCreate = hasWorkspaceUserProjectMethod(api, "create") ? (input) => api.create(input) : void 0;
|
|
484
|
+
const apiGetDefaultSelection = hasWorkspaceUserProjectMethod(
|
|
485
|
+
api,
|
|
486
|
+
"getDefaultSelection"
|
|
487
|
+
) ? () => api.getDefaultSelection() : void 0;
|
|
488
|
+
const apiIsNoProjectPath = hasWorkspaceUserProjectMethod(
|
|
489
|
+
api,
|
|
490
|
+
"isNoProjectPath"
|
|
491
|
+
) ? (input) => api.isNoProjectPath(input) : void 0;
|
|
492
|
+
const apiRememberDefaultSelection = hasWorkspaceUserProjectMethod(
|
|
493
|
+
api,
|
|
494
|
+
"rememberDefaultSelection"
|
|
495
|
+
) ? (input) => api.rememberDefaultSelection(input) : void 0;
|
|
496
|
+
const apiSelectDirectory = hasWorkspaceUserProjectMethod(
|
|
497
|
+
api,
|
|
498
|
+
"selectDirectory"
|
|
499
|
+
) ? () => api.selectDirectory() : void 0;
|
|
500
|
+
const apiUse = hasWorkspaceUserProjectMethod(api, "use") ? (input) => api.use(input) : void 0;
|
|
501
|
+
return {
|
|
502
|
+
checkPath: hasWorkspaceUserProjectMethod(service, "checkProjectPath") ? ({ path }) => service.checkProjectPath(path) : apiCheckPath,
|
|
503
|
+
create: hasWorkspaceUserProjectMethod(service, "createProject") ? ({ name }) => service.createProject(name) : apiCreate,
|
|
504
|
+
getDefaultSelection: hasWorkspaceUserProjectMethod(
|
|
505
|
+
service,
|
|
506
|
+
"getDefaultSelection"
|
|
507
|
+
) ? () => service.getDefaultSelection() : apiGetDefaultSelection,
|
|
508
|
+
isNoProjectPath: hasWorkspaceUserProjectMethod(service, "isNoProjectPath") ? ({ path }) => service.isNoProjectPath(path) : apiIsNoProjectPath,
|
|
509
|
+
list: async () => {
|
|
510
|
+
await (service.ensureLoaded?.() ?? service.refresh());
|
|
511
|
+
return { projects: [...service.store.projects] };
|
|
512
|
+
},
|
|
513
|
+
prepareSelection: (input) => service.prepareSelection(input),
|
|
514
|
+
rememberDefaultSelection: hasWorkspaceUserProjectMethod(
|
|
515
|
+
service,
|
|
516
|
+
"rememberDefaultSelection"
|
|
517
|
+
) ? ({ path }) => service.rememberDefaultSelection({ path }) : apiRememberDefaultSelection,
|
|
518
|
+
selectDirectory: hasWorkspaceUserProjectMethod(service, "selectDirectory") ? () => service.selectDirectory() : apiSelectDirectory,
|
|
519
|
+
use: hasWorkspaceUserProjectMethod(service, "registerProjectPath") ? ({ path }) => service.registerProjectPath(path) : apiUse
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
function hasWorkspaceUserProjectMethod(value, key) {
|
|
523
|
+
return value ? typeof Reflect.get(value, key) === "function" : false;
|
|
524
|
+
}
|
|
525
|
+
function setApiUnavailableUnlessService(setIsApiUnavailable, service, value = true) {
|
|
526
|
+
if (!service) {
|
|
527
|
+
setIsApiUnavailable(value);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
function resolveWorkspaceUserProjectSelectLabels(i18n = defaultWorkspaceUserProjectSelectI18n, overrides) {
|
|
531
|
+
return {
|
|
532
|
+
addProject: overrides?.addProject ?? i18n.t("projectSelect.addProject"),
|
|
533
|
+
createProjectCancel: overrides?.createProjectCancel ?? i18n.t("projectSelect.createProjectCancel"),
|
|
534
|
+
createProjectConfirm: overrides?.createProjectConfirm ?? i18n.t("projectSelect.createProjectConfirm"),
|
|
535
|
+
createProjectDocumentsUnavailable: overrides?.createProjectDocumentsUnavailable ?? i18n.t("projectSelect.createProjectDocumentsUnavailable"),
|
|
536
|
+
createProjectFailed: overrides?.createProjectFailed ?? i18n.t("projectSelect.createProjectFailed"),
|
|
537
|
+
createProjectNameConflict: overrides?.createProjectNameConflict ?? i18n.t("projectSelect.createProjectNameConflict"),
|
|
538
|
+
createProjectNameInvalid: overrides?.createProjectNameInvalid ?? i18n.t("projectSelect.createProjectNameInvalid"),
|
|
539
|
+
createProjectNameLabel: overrides?.createProjectNameLabel ?? i18n.t("projectSelect.createProjectNameLabel"),
|
|
540
|
+
createProjectNamePlaceholder: overrides?.createProjectNamePlaceholder ?? i18n.t("projectSelect.createProjectNamePlaceholder"),
|
|
541
|
+
createProjectNameRequired: overrides?.createProjectNameRequired ?? i18n.t("projectSelect.createProjectNameRequired"),
|
|
542
|
+
createProjectPermissionDenied: overrides?.createProjectPermissionDenied ?? i18n.t("projectSelect.createProjectPermissionDenied"),
|
|
543
|
+
createProjectTitle: overrides?.createProjectTitle ?? i18n.t("projectSelect.createProjectTitle"),
|
|
544
|
+
linkExistingProject: overrides?.linkExistingProject ?? i18n.t("projectSelect.linkExistingProject"),
|
|
545
|
+
loadingProjects: overrides?.loadingProjects ?? i18n.t("projectSelect.loadingProjects"),
|
|
546
|
+
noProject: overrides?.noProject ?? i18n.t("projectSelect.noProject"),
|
|
547
|
+
projectLabel: overrides?.projectLabel ?? i18n.t("projectSelect.projectLabel"),
|
|
548
|
+
projectLocked: overrides?.projectLocked ?? i18n.t("projectSelect.projectLocked"),
|
|
549
|
+
projectMissingTitle: overrides?.projectMissingTitle ?? i18n.t("projectSelect.projectMissingTitle"),
|
|
550
|
+
projectUnavailable: overrides?.projectUnavailable ?? i18n.t("projectSelect.projectUnavailable")
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
function resolveProjectCreationErrorLabel(error, labels) {
|
|
554
|
+
switch (getWorkspaceUserProjectErrorCode(error)) {
|
|
555
|
+
case "EEXIST":
|
|
556
|
+
case "project_directory_already_exists":
|
|
557
|
+
return labels.createProjectNameConflict;
|
|
558
|
+
case "project_name_invalid":
|
|
559
|
+
return labels.createProjectNameInvalid;
|
|
560
|
+
case "EACCES":
|
|
561
|
+
case "EPERM":
|
|
562
|
+
case "project_directory_permission_denied":
|
|
563
|
+
return labels.createProjectPermissionDenied;
|
|
564
|
+
case "ENOENT":
|
|
565
|
+
case "project_documents_unavailable":
|
|
566
|
+
return labels.createProjectDocumentsUnavailable;
|
|
567
|
+
default:
|
|
568
|
+
return labels.createProjectFailed;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
export {
|
|
572
|
+
WorkspaceUserProjectSelect,
|
|
573
|
+
resolveWorkspaceUserProjectSelectLabels
|
|
574
|
+
};
|
|
575
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/ui/internal/project/WorkspaceUserProjectSelect.tsx"],"sourcesContent":["import {\n type FormEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useEffectEvent,\n useMemo,\n useState\n} from \"react\";\nimport { useSnapshot } from \"valtio\";\nimport { proxy } from \"valtio/vanilla\";\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n FolderIcon,\n Input,\n LinkIcon,\n NewWorkspaceLinedIcon,\n NoWorkspaceLinedIcon,\n Select,\n SelectContent,\n SelectItem,\n SelectSeparator,\n SelectTrigger\n} from \"@tutti-os/ui-system\";\nimport type {\n WorkspaceUserProject,\n WorkspaceUserProjectApi,\n WorkspaceUserProjectSelectionPreparation,\n WorkspaceUserProjectSelectionPreparationInput,\n WorkspaceUserProjectServiceLike\n} from \"../../../contracts/index.ts\";\nimport {\n basenameWorkspaceUserProjectPath,\n getWorkspaceUserProjectErrorCode,\n prepareWorkspaceUserProjectSelection,\n resolveWorkspaceUserProjectDisplayLabel,\n upsertWorkspaceUserProject\n} from \"../../../core/index.ts\";\nimport {\n createDefaultWorkspaceUserProjectI18nRuntime,\n type WorkspaceUserProjectI18nRuntime\n} from \"../../../i18n/index.ts\";\n\nexport type WorkspaceUserProjectSelectLabels = {\n addProject: string;\n createProjectCancel: string;\n createProjectConfirm: string;\n createProjectDocumentsUnavailable: string;\n createProjectFailed: string;\n createProjectNameConflict: string;\n createProjectNameInvalid: string;\n createProjectNameLabel: string;\n createProjectNamePlaceholder: string;\n createProjectNameRequired: string;\n createProjectPermissionDenied: string;\n createProjectTitle: string;\n linkExistingProject: string;\n loadingProjects: string;\n noProject: string;\n projectLabel: string;\n projectLocked: string;\n projectMissingTitle: string;\n projectUnavailable: string;\n};\n\nexport type WorkspaceUserProjectSelectLabelOverrides =\n Partial<WorkspaceUserProjectSelectLabels>;\n\nexport interface WorkspaceUserProjectSelectClassNames {\n content?: string;\n item?: string;\n trigger?: string;\n}\n\nexport type WorkspaceUserProjectSelectChangeAction =\n | \"clear\"\n | \"create_new\"\n | \"select_existing\";\n\nexport interface WorkspaceUserProjectSelectProps {\n api?: WorkspaceUserProjectApi | null;\n classNames?: WorkspaceUserProjectSelectClassNames;\n contentAlign?: \"center\" | \"end\" | \"start\";\n contentSide?: \"bottom\" | \"left\" | \"right\" | \"top\";\n contentSideOffset?: number;\n disabled?: boolean;\n i18n?: WorkspaceUserProjectI18nRuntime;\n labels?: WorkspaceUserProjectSelectLabelOverrides;\n onProjectMissingChange?: (isMissing: boolean) => void;\n onProjectPathChange: (\n path: string | null,\n metadata?: { action: WorkspaceUserProjectSelectChangeAction }\n ) => void;\n projectLocked?: boolean;\n renderAddProjectIcon?: () => ReactNode;\n shouldApplyPreparedSelection?: boolean;\n showKnownProjectOptions?: boolean;\n service?: WorkspaceUserProjectServiceLike | null;\n selectedProjectPath?: string | null;\n showCreateProjectAction?: boolean;\n showNoProjectAction?: boolean;\n unlistedProjectLabel?: string;\n}\n\nconst noProjectOptionValue = \"__nextop_no_project__\";\nconst addProjectOptionValue = \"__nextop_add_project__\";\nconst linkExistingProjectOptionValue = \"__nextop_link_existing_project__\";\nconst defaultWorkspaceUserProjectSelectI18n =\n createDefaultWorkspaceUserProjectI18nRuntime();\nconst emptyWorkspaceUserProjectServiceSnapshot = proxy({\n error: null,\n initialized: false,\n isLoading: false,\n projects: [],\n revision: 0\n});\n\nexport function WorkspaceUserProjectSelect({\n api,\n classNames,\n contentAlign = \"start\",\n contentSide = \"top\",\n contentSideOffset = 4,\n disabled: disabledProp = false,\n i18n = defaultWorkspaceUserProjectSelectI18n,\n labels,\n onProjectMissingChange,\n onProjectPathChange,\n projectLocked = false,\n renderAddProjectIcon,\n shouldApplyPreparedSelection = true,\n showKnownProjectOptions = true,\n service,\n selectedProjectPath,\n showCreateProjectAction = hasWorkspaceUserProjectMethod(\n service,\n \"createProject\"\n ) || hasWorkspaceUserProjectMethod(api, \"create\"),\n showNoProjectAction = true,\n unlistedProjectLabel\n}: WorkspaceUserProjectSelectProps): React.JSX.Element {\n \"use memo\";\n const serviceSnapshot = useSnapshot(\n service?.store ?? emptyWorkspaceUserProjectServiceSnapshot\n );\n const effectiveApi = useMemo(\n () => createWorkspaceUserProjectApiAdapter(api, service),\n [api, service]\n );\n const resolvedLabels = useMemo(\n () => resolveWorkspaceUserProjectSelectLabels(i18n, labels),\n [i18n, labels]\n );\n const [apiProjects, setApiProjects] = useState<WorkspaceUserProject[]>([]);\n const [isApiLoading, setIsApiLoading] = useState(false);\n const [isApiUnavailable, setIsApiUnavailable] = useState(!effectiveApi);\n const [isProjectDialogOpen, setIsProjectDialogOpen] = useState(false);\n const [draftProjectName, setDraftProjectName] = useState(\"\");\n const [projectCreationError, setProjectCreationError] = useState<\n string | null\n >(null);\n const [isCreatingProject, setIsCreatingProject] = useState(false);\n const [suppressedSelectedPath, setSuppressedSelectedPath] = useState<\n string | null\n >(null);\n const [hasPinnedNoProjectSelection, setHasPinnedNoProjectSelection] =\n useState(false);\n const [isSelectedPathMissing, setIsSelectedPathMissing] = useState(false);\n const rawSelectedPath = selectedProjectPath?.trim() ?? \"\";\n const selectedPath =\n rawSelectedPath && rawSelectedPath === suppressedSelectedPath\n ? \"\"\n : rawSelectedPath;\n const projects = service ? [...serviceSnapshot.projects] : apiProjects;\n const visibleProjects = showKnownProjectOptions ? projects : [];\n const isLoading = service\n ? serviceSnapshot.isLoading && !serviceSnapshot.initialized\n : isApiLoading;\n const isUnavailable = service\n ? Boolean(serviceSnapshot.error) && !serviceSnapshot.initialized\n : isApiUnavailable;\n const selectedPathLabel =\n basenameWorkspaceUserProjectPath(selectedPath) || selectedPath;\n const selectedProject = showKnownProjectOptions\n ? (projects.find((project) => project.path === selectedPath) ?? null)\n : null;\n const selectedProjectLabel = selectedProject\n ? resolveWorkspaceUserProjectDisplayLabel(selectedProject)\n : \"\";\n const isSelectedNoProjectPath =\n projectLocked &&\n Boolean(selectedPath) &&\n Boolean(effectiveApi?.isNoProjectPath?.({ path: selectedPath }));\n const shouldShowMissingProjectNotice = isSelectedPathMissing;\n const shouldShowLockedProjectPath =\n projectLocked &&\n selectedPath !== \"\" &&\n !isSelectedNoProjectPath &&\n !selectedProject &&\n !isSelectedPathMissing;\n const selectValue = selectedProject\n ? selectedProject.path\n : noProjectOptionValue;\n const triggerLabel = shouldShowMissingProjectNotice\n ? resolvedLabels.projectMissingTitle\n : isSelectedNoProjectPath\n ? resolvedLabels.noProject\n : shouldShowLockedProjectPath\n ? selectedPathLabel\n : selectedProject\n ? selectedProjectLabel\n : selectedPath\n ? unlistedProjectLabel || selectedPathLabel\n : isLoading\n ? resolvedLabels.loadingProjects\n : resolvedLabels.noProject;\n const shouldDisableWhileLoading =\n showKnownProjectOptions || shouldApplyPreparedSelection;\n const disabled =\n disabledProp ||\n projectLocked ||\n (shouldDisableWhileLoading && isLoading) ||\n !effectiveApi;\n\n useEffect(() => {\n onProjectMissingChange?.(shouldShowMissingProjectNotice);\n }, [onProjectMissingChange, shouldShowMissingProjectNotice]);\n\n useEffect(() => {\n if (rawSelectedPath) {\n setHasPinnedNoProjectSelection(false);\n }\n if (\n suppressedSelectedPath &&\n (!rawSelectedPath || rawSelectedPath !== suppressedSelectedPath)\n ) {\n setSuppressedSelectedPath(null);\n }\n }, [rawSelectedPath, suppressedSelectedPath]);\n\n const applyPreparedSelection = useEffectEvent(\n (prepared: WorkspaceUserProjectSelectionPreparation): void => {\n if (!service) {\n setApiProjects(prepared.projects);\n }\n setIsSelectedPathMissing(prepared.isSelectedPathMissing);\n if (!shouldApplyPreparedSelection) {\n return;\n }\n if (prepared.selection.kind === \"clear\") {\n setHasPinnedNoProjectSelection(true);\n setSuppressedSelectedPath(prepared.selection.suppressedPath);\n onProjectPathChange(null);\n return;\n }\n if (prepared.selection.kind === \"select\") {\n setHasPinnedNoProjectSelection(false);\n onProjectPathChange(prepared.selection.path);\n }\n }\n );\n\n useEffect(() => {\n let canceled = false;\n if (!effectiveApi) {\n setApiUnavailableUnlessService(setIsApiUnavailable, service);\n return;\n }\n if (hasPinnedNoProjectSelection) {\n return;\n }\n setIsApiLoading(true);\n setApiUnavailableUnlessService(setIsApiUnavailable, service, false);\n const input = {\n projectLocked,\n selectedPath\n } satisfies WorkspaceUserProjectSelectionPreparationInput;\n void prepareWorkspaceUserProjectSelection(effectiveApi, input)\n .then((prepared) => {\n if (!canceled) {\n applyPreparedSelection(prepared);\n }\n })\n .catch(() => {\n if (!canceled) {\n setApiUnavailableUnlessService(setIsApiUnavailable, service);\n }\n })\n .finally(() => {\n if (!canceled) {\n setIsApiLoading(false);\n }\n });\n return () => {\n canceled = true;\n };\n }, [\n effectiveApi,\n hasPinnedNoProjectSelection,\n projectLocked,\n selectedPath,\n serviceSnapshot.revision,\n service\n ]);\n\n const refreshPreparedSelection = useCallback((): void => {\n if (!effectiveApi) {\n return;\n }\n const input = {\n projectLocked,\n selectedPath\n } satisfies WorkspaceUserProjectSelectionPreparationInput;\n void prepareWorkspaceUserProjectSelection(effectiveApi, input).then(\n applyPreparedSelection,\n () => {\n setApiUnavailableUnlessService(setIsApiUnavailable, service);\n }\n );\n }, [\n effectiveApi,\n projectLocked,\n selectedPath,\n service,\n shouldApplyPreparedSelection\n ]);\n\n const useProjectPath = useCallback(\n async (\n path: string,\n action: WorkspaceUserProjectSelectChangeAction\n ): Promise<void> => {\n if (!effectiveApi) {\n setApiUnavailableUnlessService(setIsApiUnavailable, service);\n return;\n }\n try {\n const project =\n (await effectiveApi.use?.({ path })) ??\n ({\n id: path,\n label: path,\n path\n } satisfies WorkspaceUserProject);\n setApiProjects((current) =>\n upsertWorkspaceUserProject(current, project)\n );\n setHasPinnedNoProjectSelection(false);\n onProjectPathChange(project.path, { action });\n refreshPreparedSelection();\n } catch {\n setApiUnavailableUnlessService(setIsApiUnavailable, service);\n }\n },\n [effectiveApi, onProjectPathChange, refreshPreparedSelection, service]\n );\n\n const createProject = useCallback(async (): Promise<void> => {\n const name = draftProjectName.trim();\n if (!effectiveApi?.create) {\n setProjectCreationError(resolvedLabels.createProjectFailed);\n setApiUnavailableUnlessService(setIsApiUnavailable, service);\n return;\n }\n if (!name) {\n setProjectCreationError(resolvedLabels.createProjectNameRequired);\n return;\n }\n setIsCreatingProject(true);\n setProjectCreationError(null);\n try {\n const project = await effectiveApi.create({ name });\n setApiProjects((current) => upsertWorkspaceUserProject(current, project));\n setHasPinnedNoProjectSelection(false);\n onProjectPathChange(project.path, { action: \"create_new\" });\n setDraftProjectName(\"\");\n setIsProjectDialogOpen(false);\n refreshPreparedSelection();\n } catch (error) {\n setProjectCreationError(\n resolveProjectCreationErrorLabel(error, resolvedLabels)\n );\n } finally {\n setIsCreatingProject(false);\n }\n }, [\n effectiveApi,\n draftProjectName,\n onProjectPathChange,\n refreshPreparedSelection,\n resolvedLabels,\n service\n ]);\n\n const submitProjectDialog = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault();\n void createProject();\n };\n\n const closeProjectDialog = (): void => {\n setIsProjectDialogOpen(false);\n setProjectCreationError(null);\n };\n\n const handleProjectValueChange = (nextValue: string): void => {\n if (!effectiveApi || projectLocked) {\n return;\n }\n if (nextValue === noProjectOptionValue) {\n void effectiveApi.rememberDefaultSelection?.({ path: null });\n setHasPinnedNoProjectSelection(true);\n onProjectPathChange(null, { action: \"clear\" });\n return;\n }\n if (nextValue === addProjectOptionValue) {\n setDraftProjectName(\"\");\n setProjectCreationError(null);\n setIsProjectDialogOpen(true);\n return;\n }\n if (nextValue === linkExistingProjectOptionValue) {\n void Promise.resolve(effectiveApi.selectDirectory?.())\n .then((selection) => {\n const path = selection?.path?.trim() ?? \"\";\n if (!path) {\n return;\n }\n void useProjectPath(path, \"select_existing\");\n })\n .catch(() => {});\n return;\n }\n void useProjectPath(nextValue, \"select_existing\");\n };\n\n return (\n <>\n <Select\n disabled={disabled}\n value={selectValue}\n onValueChange={handleProjectValueChange}\n >\n <SelectTrigger\n aria-label={\n projectLocked\n ? resolvedLabels.projectLocked\n : isUnavailable\n ? resolvedLabels.projectUnavailable\n : resolvedLabels.projectLabel\n }\n className={classNames?.trigger}\n >\n <span className=\"flex min-w-0 flex-1 items-center gap-2\">\n {selectedProject || shouldShowLockedProjectPath ? (\n <FolderIcon aria-hidden className=\"shrink-0\" size={15} />\n ) : (\n <NoWorkspaceLinedIcon\n aria-hidden\n className=\"shrink-0\"\n data-agent-project-trigger-no-workspace-icon=\"true\"\n size={15}\n />\n )}\n <span className=\"truncate\">{triggerLabel}</span>\n </span>\n </SelectTrigger>\n <SelectContent\n align={contentAlign}\n className={classNames?.content}\n collisionPadding={16}\n side={contentSide}\n sideOffset={contentSideOffset}\n >\n {visibleProjects.map((project) => {\n const projectLabel =\n resolveWorkspaceUserProjectDisplayLabel(project);\n return (\n <SelectItem\n className={classNames?.item}\n key={project.id || project.path}\n value={project.path}\n >\n <span className=\"flex min-w-0 flex-1 items-center gap-2 pr-1\">\n <FolderIcon aria-hidden size={15} />\n <span className=\"min-w-0 flex-1 truncate\">\n <span>{projectLabel}</span>\n </span>\n </span>\n </SelectItem>\n );\n })}\n {visibleProjects.length > 0 ? <SelectSeparator /> : null}\n {effectiveApi?.selectDirectory ? (\n <SelectItem\n className={classNames?.item}\n value={linkExistingProjectOptionValue}\n >\n <span className=\"flex min-w-0 flex-1 items-center gap-2 pr-1\">\n <LinkIcon aria-hidden size={15} />\n <span className=\"truncate\">\n {resolvedLabels.linkExistingProject}\n </span>\n </span>\n </SelectItem>\n ) : null}\n {showCreateProjectAction ? (\n <SelectItem\n className={classNames?.item}\n value={addProjectOptionValue}\n >\n <span className=\"flex min-w-0 flex-1 items-center gap-2 pr-1\">\n {renderAddProjectIcon?.() ?? (\n <NewWorkspaceLinedIcon\n aria-hidden\n data-workspace-user-project-add-icon=\"true\"\n size={15}\n />\n )}\n <span className=\"truncate\">{resolvedLabels.addProject}</span>\n </span>\n </SelectItem>\n ) : null}\n {showNoProjectAction ? (\n <SelectItem\n className={classNames?.item}\n value={noProjectOptionValue}\n >\n <span className=\"flex min-w-0 flex-1 items-center gap-2 pr-1\">\n <NoWorkspaceLinedIcon\n aria-hidden\n data-agent-project-no-workspace-icon=\"true\"\n size={15}\n />\n <span className=\"truncate\">{resolvedLabels.noProject}</span>\n </span>\n </SelectItem>\n ) : null}\n </SelectContent>\n </Select>\n {isProjectDialogOpen ? (\n <Dialog\n open\n onOpenChange={(nextOpen) => !nextOpen && closeProjectDialog()}\n >\n <DialogContent\n className=\"w-[480px] max-w-[calc(100vw-32px)] sm:max-w-[480px]\"\n showCloseButton={false}\n >\n <form className=\"grid gap-4\" onSubmit={submitProjectDialog}>\n <DialogHeader>\n <DialogTitle>{resolvedLabels.createProjectTitle}</DialogTitle>\n <DialogDescription>\n {resolvedLabels.createProjectNameLabel}\n </DialogDescription>\n </DialogHeader>\n <label className=\"grid gap-1.5\">\n <span className=\"sr-only\">\n {resolvedLabels.createProjectNameLabel}\n </span>\n <Input\n autoFocus\n className=\"h-10\"\n disabled={isCreatingProject}\n placeholder={resolvedLabels.createProjectNamePlaceholder}\n value={draftProjectName}\n onChange={(event) => {\n setDraftProjectName(event.target.value);\n if (projectCreationError) {\n setProjectCreationError(null);\n }\n }}\n />\n </label>\n {projectCreationError ? (\n <p className=\"text-sm text-[var(--state-danger)]\">\n {projectCreationError}\n </p>\n ) : null}\n <DialogFooter>\n <Button\n disabled={isCreatingProject}\n size=\"dialog\"\n type=\"button\"\n variant=\"secondary\"\n onClick={closeProjectDialog}\n onPointerDown={(event) => {\n if (event.button === 0 && !isCreatingProject) {\n closeProjectDialog();\n }\n }}\n >\n {resolvedLabels.createProjectCancel}\n </Button>\n <Button\n disabled={isCreatingProject || !draftProjectName.trim()}\n size=\"dialog\"\n type=\"submit\"\n >\n {resolvedLabels.createProjectConfirm}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n ) : null}\n </>\n );\n}\n\nfunction createWorkspaceUserProjectApiAdapter(\n api: WorkspaceUserProjectApi | null | undefined,\n service: WorkspaceUserProjectServiceLike | null | undefined\n): WorkspaceUserProjectApi | null {\n if (!service) {\n return api ?? null;\n }\n const apiCheckPath = hasWorkspaceUserProjectMethod(api, \"checkPath\")\n ? (input: { path: string }) => api!.checkPath!(input)\n : undefined;\n const apiCreate = hasWorkspaceUserProjectMethod(api, \"create\")\n ? (input: { name: string }) => api!.create!(input)\n : undefined;\n const apiGetDefaultSelection = hasWorkspaceUserProjectMethod(\n api,\n \"getDefaultSelection\"\n )\n ? () => api!.getDefaultSelection!()\n : undefined;\n const apiIsNoProjectPath = hasWorkspaceUserProjectMethod(\n api,\n \"isNoProjectPath\"\n )\n ? (input: { path: string }) => api!.isNoProjectPath!(input)\n : undefined;\n const apiRememberDefaultSelection = hasWorkspaceUserProjectMethod(\n api,\n \"rememberDefaultSelection\"\n )\n ? (input: { path: string | null }) => api!.rememberDefaultSelection!(input)\n : undefined;\n const apiSelectDirectory = hasWorkspaceUserProjectMethod(\n api,\n \"selectDirectory\"\n )\n ? () => api!.selectDirectory!()\n : undefined;\n const apiUse = hasWorkspaceUserProjectMethod(api, \"use\")\n ? (input: { path: string }) => api!.use!(input)\n : undefined;\n return {\n checkPath: hasWorkspaceUserProjectMethod(service, \"checkProjectPath\")\n ? ({ path }) => service.checkProjectPath!(path)\n : apiCheckPath,\n create: hasWorkspaceUserProjectMethod(service, \"createProject\")\n ? ({ name }) => service.createProject!(name)\n : apiCreate,\n getDefaultSelection: hasWorkspaceUserProjectMethod(\n service,\n \"getDefaultSelection\"\n )\n ? () => service.getDefaultSelection!()\n : apiGetDefaultSelection,\n isNoProjectPath: hasWorkspaceUserProjectMethod(service, \"isNoProjectPath\")\n ? ({ path }) => service.isNoProjectPath!(path)\n : apiIsNoProjectPath,\n list: async () => {\n await (service.ensureLoaded?.() ?? service.refresh());\n return { projects: [...service.store.projects] };\n },\n prepareSelection: (input) => service.prepareSelection(input),\n rememberDefaultSelection: hasWorkspaceUserProjectMethod(\n service,\n \"rememberDefaultSelection\"\n )\n ? ({ path }) => service.rememberDefaultSelection!({ path })\n : apiRememberDefaultSelection,\n selectDirectory: hasWorkspaceUserProjectMethod(service, \"selectDirectory\")\n ? () => service.selectDirectory!()\n : apiSelectDirectory,\n use: hasWorkspaceUserProjectMethod(service, \"registerProjectPath\")\n ? ({ path }) => service.registerProjectPath!(path)\n : apiUse\n };\n}\n\nfunction hasWorkspaceUserProjectMethod(\n value: object | null | undefined,\n key: string\n): boolean {\n return value ? typeof Reflect.get(value, key) === \"function\" : false;\n}\n\nfunction setApiUnavailableUnlessService(\n setIsApiUnavailable: (value: boolean) => void,\n service: WorkspaceUserProjectServiceLike | null | undefined,\n value = true\n): void {\n if (!service) {\n setIsApiUnavailable(value);\n }\n}\n\nexport function resolveWorkspaceUserProjectSelectLabels(\n i18n: WorkspaceUserProjectI18nRuntime = defaultWorkspaceUserProjectSelectI18n,\n overrides?: WorkspaceUserProjectSelectLabelOverrides\n): WorkspaceUserProjectSelectLabels {\n return {\n addProject: overrides?.addProject ?? i18n.t(\"projectSelect.addProject\"),\n createProjectCancel:\n overrides?.createProjectCancel ??\n i18n.t(\"projectSelect.createProjectCancel\"),\n createProjectConfirm:\n overrides?.createProjectConfirm ??\n i18n.t(\"projectSelect.createProjectConfirm\"),\n createProjectDocumentsUnavailable:\n overrides?.createProjectDocumentsUnavailable ??\n i18n.t(\"projectSelect.createProjectDocumentsUnavailable\"),\n createProjectFailed:\n overrides?.createProjectFailed ??\n i18n.t(\"projectSelect.createProjectFailed\"),\n createProjectNameConflict:\n overrides?.createProjectNameConflict ??\n i18n.t(\"projectSelect.createProjectNameConflict\"),\n createProjectNameInvalid:\n overrides?.createProjectNameInvalid ??\n i18n.t(\"projectSelect.createProjectNameInvalid\"),\n createProjectNameLabel:\n overrides?.createProjectNameLabel ??\n i18n.t(\"projectSelect.createProjectNameLabel\"),\n createProjectNamePlaceholder:\n overrides?.createProjectNamePlaceholder ??\n i18n.t(\"projectSelect.createProjectNamePlaceholder\"),\n createProjectNameRequired:\n overrides?.createProjectNameRequired ??\n i18n.t(\"projectSelect.createProjectNameRequired\"),\n createProjectPermissionDenied:\n overrides?.createProjectPermissionDenied ??\n i18n.t(\"projectSelect.createProjectPermissionDenied\"),\n createProjectTitle:\n overrides?.createProjectTitle ??\n i18n.t(\"projectSelect.createProjectTitle\"),\n linkExistingProject:\n overrides?.linkExistingProject ??\n i18n.t(\"projectSelect.linkExistingProject\"),\n loadingProjects:\n overrides?.loadingProjects ?? i18n.t(\"projectSelect.loadingProjects\"),\n noProject: overrides?.noProject ?? i18n.t(\"projectSelect.noProject\"),\n projectLabel:\n overrides?.projectLabel ?? i18n.t(\"projectSelect.projectLabel\"),\n projectLocked:\n overrides?.projectLocked ?? i18n.t(\"projectSelect.projectLocked\"),\n projectMissingTitle:\n overrides?.projectMissingTitle ??\n i18n.t(\"projectSelect.projectMissingTitle\"),\n projectUnavailable:\n overrides?.projectUnavailable ??\n i18n.t(\"projectSelect.projectUnavailable\")\n };\n}\n\nfunction resolveProjectCreationErrorLabel(\n error: unknown,\n labels: WorkspaceUserProjectSelectLabels\n): string {\n switch (getWorkspaceUserProjectErrorCode(error)) {\n case \"EEXIST\":\n case \"project_directory_already_exists\":\n return labels.createProjectNameConflict;\n case \"project_name_invalid\":\n return labels.createProjectNameInvalid;\n case \"EACCES\":\n case \"EPERM\":\n case \"project_directory_permission_denied\":\n return labels.createProjectPermissionDenied;\n case \"ENOENT\":\n case \"project_documents_unavailable\":\n return labels.createProjectDocumentsUnavailable;\n default:\n return labels.createProjectFailed;\n }\n}\n"],"mappings":"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","names":[]}
|