@nextclaw/ui 0.24.0-beta.0 → 0.24.0-beta.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/assets/api-BqVIq0lF.js +13 -0
  3. package/dist/assets/{appearance-settings-page-CPoFZLw8.js → appearance-settings-page-CTWn1eAT.js} +1 -1
  4. package/dist/assets/{book-open-jcUt0rr9.js → book-open-o2x7OLiO.js} +1 -1
  5. package/dist/assets/{channels-list-page-anMJAkfK.js → channels-list-page-Bzn-pzyJ.js} +1 -1
  6. package/dist/assets/{config-split-page-AcuFnbIC.js → config-split-page-CnRbXXlh.js} +1 -1
  7. package/dist/assets/{confirm-dialog-B-atCfC5.js → confirm-dialog-B_Hbcra2.js} +1 -1
  8. package/dist/assets/{createLucideIcon-Blz0FzrV.js → createLucideIcon-rwwpqyks.js} +1 -1
  9. package/dist/assets/{desktop-capabilities-page-8lKF_Ob-.js → desktop-capabilities-page-C2ayYQTr.js} +1 -1
  10. package/dist/assets/{desktop-update-config-DABXDpbj.js → desktop-update-config-C13czpyL.js} +1 -1
  11. package/dist/assets/{dist-eH-_j8yU.js → dist-BsF3hfOi.js} +1 -1
  12. package/dist/assets/{dist-D8kcEpTf.js → dist-aNN3iQxV.js} +1 -1
  13. package/dist/assets/{doc-browser-DzXRehlW.js → doc-browser-D8dIOo9E.js} +1 -1
  14. package/dist/assets/doc-browser-DcuOOtpP.js +1 -0
  15. package/dist/assets/{doc-browser-context-BlbUcg2J.js → doc-browser-context-Dhsit2Ma.js} +1 -1
  16. package/dist/assets/{extensions-mquwAJ2Z.js → extensions-CD6xvKF_.js} +1 -1
  17. package/dist/assets/{form-actions-CaZDGEmB.js → form-actions-CC4Wz_lL.js} +1 -1
  18. package/dist/assets/index-BTsbdtv6.js +109 -0
  19. package/dist/assets/index-Bcfy2kTh.css +1 -0
  20. package/dist/assets/loader-circle-B6aFbB-8.js +1 -0
  21. package/dist/assets/mcp-marketplace-page-BtUAypA7.js +1 -0
  22. package/dist/assets/{mcp-marketplace-page-gFtgyueL.js → mcp-marketplace-page-r2MmD9xO.js} +1 -1
  23. package/dist/assets/{model-config-page-hFBpeRAO.js → model-config-page-DboxoT-I.js} +1 -1
  24. package/dist/assets/{navigation-link-Hb5Z0UxZ.js → navigation-link-C_6oj3zz.js} +1 -1
  25. package/dist/assets/plus-DRsq9Kvs.js +1 -0
  26. package/dist/assets/{privacy-settings-page-C18zo3ox.js → privacy-settings-page-C2sDBqhb.js} +1 -1
  27. package/dist/assets/projects-BcPcx-uD.js +1 -0
  28. package/dist/assets/{providers-config-page-YU0-AOXJ.js → providers-config-page-CmUFl9RF.js} +1 -1
  29. package/dist/assets/react-BjO9I4WZ.js +8 -0
  30. package/dist/assets/{refresh-cw-ZHKfE3yx.js → refresh-cw-DsT2kvXi.js} +1 -1
  31. package/dist/assets/remote-Ci6x91ES.js +1 -0
  32. package/dist/assets/{rotate-cw-CLhOXGwE.js → rotate-cw-BCAs6c3R.js} +1 -1
  33. package/dist/assets/{runtime-config-page-Dmy1A_0Y.js → runtime-config-page-cQKNeAjL.js} +1 -1
  34. package/dist/assets/{save-CWuuZs77.js → save-CadRMTMQ.js} +1 -1
  35. package/dist/assets/{search-DcmsKAn2.js → search-B6tB4fzB.js} +1 -1
  36. package/dist/assets/{search-config-page-CxBacx6W.js → search-config-page-C8lOIkxn.js} +1 -1
  37. package/dist/assets/{secrets-config-page-B4py8-KR.js → secrets-config-page-8clzAag2.js} +1 -1
  38. package/dist/assets/security-config-DPbM6IVT.js +1 -0
  39. package/dist/assets/{select-BEr0Iy_f.js → select-CO9S_C2C.js} +1 -1
  40. package/dist/assets/skeleton-IHILNhIW.js +1 -0
  41. package/dist/assets/{tag-chip-ByqDkn6g.js → tag-chip-BZKk0UkK.js} +1 -1
  42. package/dist/assets/x-BuvHIb1d.js +1 -0
  43. package/dist/index.html +21 -21
  44. package/package.json +5 -5
  45. package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +362 -241
  46. package/src/features/apps/components/app-document-access-section.tsx +187 -0
  47. package/src/features/apps/components/app-package-card.tsx +150 -275
  48. package/src/features/apps/hooks/use-app-packages.ts +91 -35
  49. package/src/features/chat/index.ts +5 -1
  50. package/src/features/projects/AGENTS.md +3 -2
  51. package/src/features/projects/components/project-overview.tsx +70 -139
  52. package/src/features/projects/components/work/project-work-item-drawer.test.tsx +65 -0
  53. package/src/features/projects/components/work/project-work-item-drawer.tsx +367 -0
  54. package/src/features/projects/components/work/project-work-items.test.tsx +98 -0
  55. package/src/features/projects/components/work/project-work-items.tsx +199 -0
  56. package/src/features/projects/components/work/project-work-state-settings.tsx +285 -0
  57. package/src/features/projects/hooks/use-project-observation.ts +56 -26
  58. package/src/features/projects/hooks/use-project-work.test.tsx +58 -0
  59. package/src/features/projects/hooks/use-project-work.ts +215 -0
  60. package/src/features/projects/pages/project-home-page.tsx +119 -138
  61. package/src/features/projects/pages/projects-page.test.tsx +79 -308
  62. package/src/shared/lib/i18n/locales/en-US/doc-browser.json +16 -1
  63. package/src/shared/lib/i18n/locales/en-US/projects.json +60 -1
  64. package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +16 -1
  65. package/src/shared/lib/i18n/locales/zh-CN/projects.json +60 -1
  66. package/dist/assets/api-CoqPRKmF.js +0 -13
  67. package/dist/assets/doc-browser-DJEMr7Zk.js +0 -1
  68. package/dist/assets/index-DyR5iR0O.css +0 -1
  69. package/dist/assets/index-XxXj8WDS.js +0 -109
  70. package/dist/assets/loader-circle-0qPOOYQ5.js +0 -1
  71. package/dist/assets/mcp-marketplace-page-uanamJ6L.js +0 -1
  72. package/dist/assets/plus-CYOvNvcV.js +0 -1
  73. package/dist/assets/projects-C8Gm9RS8.js +0 -1
  74. package/dist/assets/react-DF-kP7iN.js +0 -8
  75. package/dist/assets/remote-B_utkBra.js +0 -1
  76. package/dist/assets/security-config-CTP4IQWw.js +0 -1
  77. package/dist/assets/skeleton-B2NHluWf.js +0 -1
  78. package/dist/assets/x-CENkFyK5.js +0 -1
  79. package/src/features/projects/components/project-work-items.test.tsx +0 -78
  80. package/src/features/projects/components/project-work-items.tsx +0 -272
@@ -0,0 +1,187 @@
1
+ import { useState } from "react";
2
+ import type { AppPackageView } from "@nextclaw/client-sdk";
3
+ import { FolderKey, ShieldCheck, Trash2 } from "lucide-react";
4
+ import { useAppDocumentAccessMutation } from "@/features/apps/hooks/use-app-packages";
5
+ import { ServerPathPickerDialog } from "@/shared/components/path-picker/server-path-picker-dialog";
6
+ import { Button } from "@/shared/components/ui/button";
7
+ import { t } from "@/shared/lib/i18n";
8
+
9
+ type DocumentScope = AppPackageView["documentAccess"][number];
10
+
11
+ export function AppDocumentAccessSection({
12
+ appId,
13
+ appName,
14
+ disabled,
15
+ scopes,
16
+ }: {
17
+ appId: string;
18
+ appName: string;
19
+ disabled: boolean;
20
+ scopes: DocumentScope[];
21
+ }) {
22
+ const mutation = useAppDocumentAccessMutation();
23
+ const [activeScopeId, setActiveScopeId] = useState<string | null>(null);
24
+ const [modes, setModes] = useState<Record<string, "read" | "read-write">>({});
25
+ const activeScope = scopes.find((scope) => scope.id === activeScopeId);
26
+ const effectiveMode = activeScope
27
+ ? (modes[activeScope.id] ?? activeScope.effectiveMode ?? "read")
28
+ : "read";
29
+
30
+ if (scopes.length === 0) return null;
31
+
32
+ const error = mutation.error instanceof Error ? mutation.error.message : null;
33
+
34
+ return (
35
+ <section className="border-t border-border/60 bg-muted/10 px-4 py-3">
36
+ <div className="mb-2 flex items-center gap-2">
37
+ <FolderKey className="h-3.5 w-3.5 text-muted-foreground" />
38
+ <h3 className="text-xs font-semibold text-foreground">
39
+ {t("appPackagesDocumentAccessTitle")}
40
+ </h3>
41
+ </div>
42
+ <div className="space-y-2">
43
+ {scopes.map((scope) => {
44
+ const selectedMode = modes[scope.id] ?? scope.effectiveMode ?? "read";
45
+ return (
46
+ <div
47
+ key={scope.id}
48
+ className="rounded-lg border border-border/60 bg-card px-3 py-2.5"
49
+ >
50
+ <div className="flex flex-wrap items-start justify-between gap-2">
51
+ <div className="min-w-0 flex-1">
52
+ <div className="flex items-center gap-1.5 text-xs font-medium text-foreground">
53
+ <ShieldCheck className="h-3.5 w-3.5 text-muted-foreground" />
54
+ <code>{scope.id}</code>
55
+ <span className="font-normal text-muted-foreground">
56
+ {scope.status === "ungranted"
57
+ ? t("appPackagesDocumentAccessUngranted")
58
+ : scope.status === "unavailable"
59
+ ? t("appPackagesDocumentAccessUnavailable")
60
+ : scope.effectiveMode === "read-write"
61
+ ? t("appPackagesDocumentAccessReadWrite")
62
+ : t("appPackagesDocumentAccessRead")}
63
+ </span>
64
+ </div>
65
+ {scope.description ? (
66
+ <p className="mt-1 text-[11px] leading-4 text-muted-foreground">
67
+ {scope.description}
68
+ </p>
69
+ ) : null}
70
+ {scope.grantedPath ? (
71
+ <code
72
+ className="mt-1 block truncate text-[10px] text-muted-foreground"
73
+ title={scope.grantedPath}
74
+ >
75
+ {scope.grantedPath}
76
+ </code>
77
+ ) : null}
78
+ </div>
79
+ <div className="flex shrink-0 items-center gap-1.5">
80
+ <label
81
+ className="sr-only"
82
+ htmlFor={`${appId}-${scope.id}-mode`}
83
+ >
84
+ {t("appPackagesDocumentAccessMode")}
85
+ </label>
86
+ <select
87
+ id={`${appId}-${scope.id}-mode`}
88
+ value={selectedMode}
89
+ disabled={disabled || mutation.isPending}
90
+ onChange={(event) =>
91
+ setModes((current) => ({
92
+ ...current,
93
+ [scope.id]: event.target.value as "read" | "read-write",
94
+ }))
95
+ }
96
+ className="h-8 rounded-md border border-input bg-background px-2 text-[11px] text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
97
+ >
98
+ <option value="read">
99
+ {t("appPackagesDocumentAccessRead")}
100
+ </option>
101
+ {scope.mode === "read-write" ? (
102
+ <option value="read-write">
103
+ {t("appPackagesDocumentAccessReadWrite")}
104
+ </option>
105
+ ) : null}
106
+ </select>
107
+ <Button
108
+ type="button"
109
+ size="sm"
110
+ variant="outline"
111
+ disabled={disabled || mutation.isPending}
112
+ onClick={() => {
113
+ mutation.reset();
114
+ setActiveScopeId(scope.id);
115
+ }}
116
+ >
117
+ {scope.granted
118
+ ? t("appPackagesDocumentAccessReplace")
119
+ : t("appPackagesDocumentAccessChoose")}
120
+ </Button>
121
+ {scope.granted ? (
122
+ <button
123
+ type="button"
124
+ aria-label={t("appPackagesDocumentAccessRevoke")}
125
+ title={t("appPackagesDocumentAccessRevoke")}
126
+ disabled={disabled || mutation.isPending}
127
+ onClick={() =>
128
+ mutation.mutate({
129
+ action: "revoke",
130
+ appId,
131
+ scopeId: scope.id,
132
+ })
133
+ }
134
+ className="rounded-md p-2 text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
135
+ >
136
+ <Trash2 className="h-3.5 w-3.5" />
137
+ </button>
138
+ ) : null}
139
+ </div>
140
+ </div>
141
+ </div>
142
+ );
143
+ })}
144
+ </div>
145
+ {error ? (
146
+ <p role="alert" className="mt-2 text-xs text-destructive">
147
+ {error}
148
+ </p>
149
+ ) : null}
150
+ <ServerPathPickerDialog
151
+ open={Boolean(activeScope)}
152
+ currentPath={activeScope?.grantedPath}
153
+ isSaving={mutation.isPending}
154
+ onOpenChange={(open) => {
155
+ if (!open) setActiveScopeId(null);
156
+ }}
157
+ onConfirm={async (directoryPath) => {
158
+ if (!activeScope) return;
159
+ await mutation.mutateAsync({
160
+ action: "grant",
161
+ appId,
162
+ scopeId: activeScope.id,
163
+ directoryPath,
164
+ mode: effectiveMode,
165
+ });
166
+ setActiveScopeId(null);
167
+ }}
168
+ title={`${t("appPackagesDocumentAccessChooseTitle")} · ${appName}`}
169
+ description={
170
+ activeScope?.description ??
171
+ t("appPackagesDocumentAccessChooseDescription")
172
+ }
173
+ pathLabel={t("appPackagesDocumentAccessPath")}
174
+ confirmLabel={
175
+ activeScope?.granted
176
+ ? t("appPackagesDocumentAccessReplace")
177
+ : t("appPackagesDocumentAccessGrant")
178
+ }
179
+ hint={
180
+ effectiveMode === "read-write"
181
+ ? t("appPackagesDocumentAccessWriteWarning")
182
+ : t("appPackagesDocumentAccessReadHint")
183
+ }
184
+ />
185
+ </section>
186
+ );
187
+ }