@agent-native/dispatch 0.40.2 → 0.40.4-nightly-20260930124743
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/CHANGELOG.md +19 -7
- package/dist/actions/provider-api-register.d.ts +7 -7
- package/dist/routes/pages/settings-page.d.ts +10 -0
- package/dist/routes/pages/settings-page.d.ts.map +1 -0
- package/dist/routes/pages/settings-page.js +104 -0
- package/dist/routes/pages/settings-page.js.map +1 -0
- package/dist/routes/pages/settings.d.ts +4 -12
- package/dist/routes/pages/settings.d.ts.map +1 -1
- package/dist/routes/pages/settings.js +4 -106
- package/dist/routes/pages/settings.js.map +1 -1
- package/package.json +4 -4
- package/src/components/layout/Layout.spec.tsx +62 -10
- package/src/components/workspace-app-chat-rail.spec.tsx +1 -1
- package/src/routes/pages/browser-chat.spec.tsx +1 -1
- package/src/routes/pages/settings-page.tsx +250 -0
- package/src/routes/pages/settings.tsx +4 -252
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @agent-native/dispatch
|
|
2
2
|
|
|
3
|
+
## 0.40.4-nightly-20260930124743
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [ce1245c]
|
|
8
|
+
- Updated dependencies [e90dedc]
|
|
9
|
+
- @agent-native/core@0.198.3-nightly-20260930124743
|
|
10
|
+
- @agent-native/toolkit@0.198.3-nightly-20260930124743
|
|
11
|
+
|
|
12
|
+
## 0.40.3
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 181ca1d: Keep the package changelog in Dispatch's route wrapper so generated workspaces can render the shared Settings page during SSR.
|
|
17
|
+
- Release all public npm packages with a patch version bump.
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- Updated dependencies [63c4c02]
|
|
20
|
+
- @agent-native/toolkit@0.198.2
|
|
21
|
+
|
|
3
22
|
## 0.40.2
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -1078,11 +1097,4 @@
|
|
|
1078
1097
|
- Updated dependencies [89f194f]
|
|
1079
1098
|
- @agent-native/toolkit@0.14.3
|
|
1080
1099
|
|
|
1081
|
-
## 0.24.6
|
|
1082
|
-
|
|
1083
|
-
### Patch Changes
|
|
1084
|
-
|
|
1085
|
-
- Updated dependencies [2db503b]
|
|
1086
|
-
- @agent-native/toolkit@0.14.2
|
|
1087
|
-
|
|
1088
1100
|
For the full list of releases, see the [changelog archive](./changelog/archive/CHANGELOG.md).
|
|
@@ -47,9 +47,9 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
47
47
|
notes?: string | undefined;
|
|
48
48
|
scope?: "org" | "user" | undefined;
|
|
49
49
|
}, {
|
|
50
|
-
message?: undefined;
|
|
51
50
|
id?: undefined;
|
|
52
51
|
deleted?: undefined;
|
|
52
|
+
found?: undefined;
|
|
53
53
|
providers: {
|
|
54
54
|
id: string;
|
|
55
55
|
label: string;
|
|
@@ -61,11 +61,10 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
61
61
|
}[];
|
|
62
62
|
count: number;
|
|
63
63
|
provider?: undefined;
|
|
64
|
-
found?: undefined;
|
|
65
64
|
registered?: undefined;
|
|
66
65
|
label?: undefined;
|
|
67
|
-
} | {
|
|
68
66
|
message?: undefined;
|
|
67
|
+
} | {
|
|
69
68
|
id?: undefined;
|
|
70
69
|
deleted?: undefined;
|
|
71
70
|
count?: undefined;
|
|
@@ -74,8 +73,8 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
74
73
|
provider: import("node_modules/@agent-native/core/dist/provider-api").CustomProviderConfig;
|
|
75
74
|
registered?: undefined;
|
|
76
75
|
label?: undefined;
|
|
77
|
-
} | {
|
|
78
76
|
message?: undefined;
|
|
77
|
+
} | {
|
|
79
78
|
deleted?: undefined;
|
|
80
79
|
count?: undefined;
|
|
81
80
|
providers?: undefined;
|
|
@@ -84,22 +83,23 @@ declare const _default: import("node_modules/@agent-native/core/dist").ActionDef
|
|
|
84
83
|
id: string;
|
|
85
84
|
registered?: undefined;
|
|
86
85
|
label?: undefined;
|
|
87
|
-
} | {
|
|
88
86
|
message?: undefined;
|
|
87
|
+
} | {
|
|
88
|
+
found?: undefined;
|
|
89
89
|
count?: undefined;
|
|
90
90
|
providers?: undefined;
|
|
91
91
|
provider?: undefined;
|
|
92
|
-
found?: undefined;
|
|
93
92
|
deleted: boolean;
|
|
94
93
|
id: string;
|
|
95
94
|
registered?: undefined;
|
|
96
95
|
label?: undefined;
|
|
96
|
+
message?: undefined;
|
|
97
97
|
} | {
|
|
98
98
|
deleted?: undefined;
|
|
99
|
+
found?: undefined;
|
|
99
100
|
count?: undefined;
|
|
100
101
|
providers?: undefined;
|
|
101
102
|
provider?: undefined;
|
|
102
|
-
found?: undefined;
|
|
103
103
|
registered: boolean;
|
|
104
104
|
id: string;
|
|
105
105
|
label: string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function meta(): {
|
|
2
|
+
title: string;
|
|
3
|
+
}[];
|
|
4
|
+
export interface DispatchSettingsPageProps {
|
|
5
|
+
/** Raw CHANGELOG.md behind What's new. */
|
|
6
|
+
changelog: string;
|
|
7
|
+
}
|
|
8
|
+
/** The template route supplies the app's own changelog. */
|
|
9
|
+
export declare function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps): import("node_modules/@types/react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=settings-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-page.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/settings-page.tsx"],"names":[],"mappings":"AAkDA,wBAAgB,IAAI;;IAEnB;AAED,MAAM,WAAW,yBAAyB;IACxC,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,EAAE,yBAAyB,mDA6L5E"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CHAT_FIRST_MODE_CHANGED_EVENT, readChatFirstModeState, writeChatFirstMode, } from "@agent-native/core/client/agent-chat";
|
|
3
|
+
import { useFeatureFlag, useFeatureFlagState, } from "@agent-native/core/client/feature-flags";
|
|
4
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
5
|
+
import { SETTINGS_REDESIGN_FLAG } from "@agent-native/core/feature-flags/registry";
|
|
6
|
+
import { ChangelogSettingsCard } from "@agent-native/toolkit/app/changelog";
|
|
7
|
+
import { OrgMembersPage, TeamPage } from "@agent-native/toolkit/app/org";
|
|
8
|
+
import { AccountSettingsCard, CORE_SETTINGS_PAGES, registerSettingsPages, SettingsGroup, SettingsRow, SettingsTabsPage, useAgentSettingsTabs, } from "@agent-native/toolkit/app/settings";
|
|
9
|
+
import { LanguagePicker } from "@agent-native/toolkit/app/shared";
|
|
10
|
+
import { IconShield } from "@tabler/icons-react";
|
|
11
|
+
import { useMemo, useState } from "react";
|
|
12
|
+
import { Link } from "react-router";
|
|
13
|
+
import { Button } from "../../components/ui/button.js";
|
|
14
|
+
import { Switch } from "../../components/ui/switch.js";
|
|
15
|
+
import { dispatchAccessDescriptor } from "../../shared/app-roles.js";
|
|
16
|
+
import { DISPATCH_CONNECT_APPS_FLAG } from "../../shared/feature-flags.js";
|
|
17
|
+
const coreMembersPage = CORE_SETTINGS_PAGES.find((page) => page.id === "members");
|
|
18
|
+
if (!coreMembersPage) {
|
|
19
|
+
throw new Error("Core Settings has no members page for Dispatch app roles");
|
|
20
|
+
}
|
|
21
|
+
function DispatchMembersSettingsPage() {
|
|
22
|
+
return _jsx(OrgMembersPage, { appRoles: dispatchAccessDescriptor });
|
|
23
|
+
}
|
|
24
|
+
// The redesigned Settings shows Members from core; Dispatch's replaces it so
|
|
25
|
+
// the app-role column stays.
|
|
26
|
+
registerSettingsPages([
|
|
27
|
+
{ ...coreMembersPage, component: DispatchMembersSettingsPage },
|
|
28
|
+
]);
|
|
29
|
+
export function meta() {
|
|
30
|
+
return [{ title: "Settings - Dispatch" }];
|
|
31
|
+
}
|
|
32
|
+
/** The template route supplies the app's own changelog. */
|
|
33
|
+
export function DispatchSettingsPage({ changelog }) {
|
|
34
|
+
const t = useT();
|
|
35
|
+
const connectAppsEnabled = useFeatureFlag(DISPATCH_CONNECT_APPS_FLAG.key);
|
|
36
|
+
// Core Preferences owns the interface language in the redesigned Settings,
|
|
37
|
+
// whose Dispatch General page shows `generalGroups` instead of `general`.
|
|
38
|
+
const redesign = useFeatureFlagState(SETTINGS_REDESIGN_FLAG.key).enabled;
|
|
39
|
+
const agentSettingsTabs = useAgentSettingsTabs({
|
|
40
|
+
usageAppId: "dispatch",
|
|
41
|
+
usageViewAllHref: "/admin/metrics",
|
|
42
|
+
organizationContent: (_jsx("div", { className: "mx-auto w-full max-w-3xl", children: _jsx(TeamPage, { showTitle: false, appRoles: dispatchAccessDescriptor, createOrgDescription: "Set up a team to share dispatch destinations and approvals with your colleagues." }) })),
|
|
43
|
+
});
|
|
44
|
+
const settingsTabs = [
|
|
45
|
+
...agentSettingsTabs,
|
|
46
|
+
{
|
|
47
|
+
id: "admin",
|
|
48
|
+
label: t("dispatch.nav.admin", { defaultValue: "Admin" }),
|
|
49
|
+
icon: IconShield,
|
|
50
|
+
group: "Admin",
|
|
51
|
+
href: "/admin",
|
|
52
|
+
content: null,
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
const [chatFirstModeState] = useState(() => readChatFirstModeState());
|
|
56
|
+
const [chatFirstMode, setChatFirstMode] = useState(() => chatFirstModeState.enabled);
|
|
57
|
+
const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState(chatFirstModeState.availability === "unavailable"
|
|
58
|
+
? t("settings.chatFirstStorageUnavailable")
|
|
59
|
+
: null);
|
|
60
|
+
function updateChatFirstMode(enabled) {
|
|
61
|
+
const result = writeChatFirstMode(enabled);
|
|
62
|
+
if (!result.ok) {
|
|
63
|
+
setChatFirstStorageNotice(t("settings.chatFirstStorageBlocked"));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
setChatFirstStorageNotice(null);
|
|
67
|
+
setChatFirstMode(enabled);
|
|
68
|
+
window.dispatchEvent(new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {
|
|
69
|
+
detail: { enabled },
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
const generalSearchEntries = useMemo(() => [
|
|
73
|
+
...(redesign
|
|
74
|
+
? []
|
|
75
|
+
: [
|
|
76
|
+
{
|
|
77
|
+
id: "dispatch-language",
|
|
78
|
+
label: t("settings.languageTitle"),
|
|
79
|
+
keywords: "language locale translation i18n",
|
|
80
|
+
hash: "language",
|
|
81
|
+
},
|
|
82
|
+
]),
|
|
83
|
+
{
|
|
84
|
+
id: "dispatch-workspace",
|
|
85
|
+
label: redesign
|
|
86
|
+
? t("settings.resourcesTitle")
|
|
87
|
+
: t("settings.workspaceTitle"),
|
|
88
|
+
keywords: "workspace resources integrations vault destinations",
|
|
89
|
+
hash: "workspace-resources",
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "dispatch-chat-first",
|
|
93
|
+
label: t("settings.chatFirstTitle"),
|
|
94
|
+
keywords: "chat first codex t3 apps pane navigation",
|
|
95
|
+
hash: "chat-first",
|
|
96
|
+
},
|
|
97
|
+
], [redesign, t]);
|
|
98
|
+
const chatFirstSwitch = (_jsx(Switch, { "aria-label": t("settings.chatFirstAriaLabel"), checked: chatFirstMode, onCheckedChange: updateChatFirstMode }));
|
|
99
|
+
const chatFirstStorageAlert = chatFirstStorageNotice ? (_jsx("p", { className: "text-sm text-destructive", role: "alert", children: chatFirstStorageNotice })) : null;
|
|
100
|
+
const connectAppsRow = connectAppsEnabled ? (_jsx(SettingsRow, { id: "connect-apps", label: t("settings.connectApps"), description: t("settings.connectAppsDescription"), control: _jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/connect", children: t("settings.openConnectApps") }) }) })) : null;
|
|
101
|
+
const resourceSettingsButton = (_jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/workspace", children: t("settings.openResourceSettings") }) }));
|
|
102
|
+
return (_jsx(SettingsTabsPage, { account: _jsx(AccountSettingsCard, {}), extraTabs: settingsTabs, generalSearchEntries: generalSearchEntries, general: _jsxs("div", { className: "mx-auto w-full max-w-2xl space-y-6", children: [_jsx("p", { className: "text-sm leading-6 text-muted-foreground", children: t("settings.description") }), _jsxs(SettingsGroup, { children: [_jsx(SettingsRow, { id: "language", label: t("settings.languageTitle"), description: t("settings.languageDescription"), control: _jsx("div", { className: "w-56", children: _jsx(LanguagePicker, { label: t("settings.languageLabel") }) }) }), _jsx(SettingsRow, { id: "workspace-resources", label: t("settings.workspaceTitle"), description: t("settings.workspaceDescription"), control: resourceSettingsButton }), connectAppsRow] }), _jsx(SettingsGroup, { id: "chat-first", children: _jsxs(SettingsRow, { label: t("settings.chatFirstTitle"), description: t("settings.chatFirstDescription"), control: chatFirstSwitch, children: [_jsx("p", { className: "text-sm leading-6 text-muted-foreground", children: t("settings.chatFirstSessionWatchDescription") }), chatFirstStorageAlert] }) })] }), generalGroups: _jsxs(SettingsGroup, { id: "workspace", title: t("settings.workspaceTitle"), children: [_jsx(SettingsRow, { id: "chat-first", label: t("settings.chatFirstTitle"), description: t("settings.chatFirstDescription"), control: chatFirstSwitch, children: chatFirstStorageAlert }), _jsx(SettingsRow, { id: "workspace-resources", label: t("settings.resourcesTitle"), description: t("settings.workspaceDescription"), control: resourceSettingsButton }), connectAppsRow] }), whatsNew: _jsx("div", { className: "mx-auto w-full max-w-2xl", children: _jsx(ChangelogSettingsCard, { markdown: changelog }) }), whatsNewMarkdown: changelog }));
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=settings-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-page.js","sourceRoot":"","sources":["../../../src/routes/pages/settings-page.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,cAAc,EACd,mBAAmB,GACpB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE3E,MAAM,eAAe,GAAG,mBAAmB,CAAC,IAAI,CAC9C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,SAAS,CAChC,CAAC;AACF,IAAI,CAAC,eAAe,EAAE,CAAC;IACrB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO,KAAC,cAAc,IAAC,QAAQ,EAAE,wBAAwB,GAAI,CAAC;AAChE,CAAC;AAED,6EAA6E;AAC7E,6BAA6B;AAC7B,qBAAqB,CAAC;IACpB,EAAE,GAAG,eAAe,EAAE,SAAS,EAAE,2BAA2B,EAAE;CAC/D,CAAC,CAAC;AAEH,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,CAAC;AAC5C,CAAC;AAOD,2DAA2D;AAC3D,MAAM,UAAU,oBAAoB,CAAC,EAAE,SAAS,EAA6B;IAC3E,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IACjB,MAAM,kBAAkB,GAAG,cAAc,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;IAC1E,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IACzE,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;QAC7C,UAAU,EAAE,UAAU;QACtB,gBAAgB,EAAE,gBAAgB;QAClC,mBAAmB,EAAE,CACnB,cAAK,SAAS,EAAC,0BAA0B,YACvC,KAAC,QAAQ,IACP,SAAS,EAAE,KAAK,EAChB,QAAQ,EAAE,wBAAwB,EAClC,oBAAoB,EAAC,kFAAkF,GACvG,GACE,CACP;KACF,CAAC,CAAC;IACH,MAAM,YAAY,GAAG;QACnB,GAAG,iBAAiB;QACpB;YACE,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,CAAC,CAAC,oBAAoB,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;YACzD,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,IAAI;SACd;KACF,CAAC;IACF,MAAM,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACtE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAChD,GAAG,EAAE,CAAC,kBAAkB,CAAC,OAAO,CACjC,CAAC;IACF,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,GAAG,QAAQ,CAGlE,kBAAkB,CAAC,YAAY,KAAK,aAAa;QAC/C,CAAC,CAAC,CAAC,CAAC,sCAAsC,CAAC;QAC3C,CAAC,CAAC,IAAI,CACT,CAAC;IAEF,SAAS,mBAAmB,CAAC,OAAgB;QAC3C,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,yBAAyB,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QACD,yBAAyB,CAAC,IAAI,CAAC,CAAC;QAChC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC1B,MAAM,CAAC,aAAa,CAClB,IAAI,WAAW,CAAC,6BAA6B,EAAE;YAC7C,MAAM,EAAE,EAAE,OAAO,EAAE;SACpB,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,oBAAoB,GAAG,OAAO,CAClC,GAAG,EAAE,CAAC;QACJ,GAAG,CAAC,QAAQ;YACV,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE;oBACE,EAAE,EAAE,mBAAmB;oBACvB,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC;oBAClC,QAAQ,EAAE,kCAAkC;oBAC5C,IAAI,EAAE,UAAU;iBACjB;aACF,CAAC;QACN;YACE,EAAE,EAAE,oBAAoB;YACxB,KAAK,EAAE,QAAQ;gBACb,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC;gBAC9B,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC;YAChC,QAAQ,EAAE,qDAAqD;YAC/D,IAAI,EAAE,qBAAqB;SAC5B;QACD;YACE,EAAE,EAAE,qBAAqB;YACzB,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC;YACnC,QAAQ,EAAE,0CAA0C;YACpD,IAAI,EAAE,YAAY;SACnB;KACF,EACD,CAAC,QAAQ,EAAE,CAAC,CAAC,CACd,CAAC;IAEF,MAAM,eAAe,GAAG,CACtB,KAAC,MAAM,kBACO,CAAC,CAAC,6BAA6B,CAAC,EAC5C,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,mBAAmB,GACpC,CACH,CAAC;IACF,MAAM,qBAAqB,GAAG,sBAAsB,CAAC,CAAC,CAAC,CACrD,YAAG,SAAS,EAAC,0BAA0B,EAAC,IAAI,EAAC,OAAO,YACjD,sBAAsB,GACrB,CACL,CAAC,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,cAAc,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAC1C,KAAC,WAAW,IACV,EAAE,EAAC,cAAc,EACjB,KAAK,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAChC,WAAW,EAAE,CAAC,CAAC,iCAAiC,CAAC,EACjD,OAAO,EACL,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,OAAO,kBAC/B,KAAC,IAAI,IAAC,EAAE,EAAC,UAAU,YAAE,CAAC,CAAC,0BAA0B,CAAC,GAAQ,GACnD,GAEX,CACH,CAAC,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,sBAAsB,GAAG,CAC7B,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,OAAO,kBAC/B,KAAC,IAAI,IAAC,EAAE,EAAC,YAAY,YAAE,CAAC,CAAC,+BAA+B,CAAC,GAAQ,GAC1D,CACV,CAAC;IAEF,OAAO,CACL,KAAC,gBAAgB,IACf,OAAO,EAAE,KAAC,mBAAmB,KAAG,EAChC,SAAS,EAAE,YAAY,EACvB,oBAAoB,EAAE,oBAAoB,EAC1C,OAAO,EACL,eAAK,SAAS,EAAC,oCAAoC,aACjD,YAAG,SAAS,EAAC,yCAAyC,YACnD,CAAC,CAAC,sBAAsB,CAAC,GACxB,EAEJ,MAAC,aAAa,eACZ,KAAC,WAAW,IACV,EAAE,EAAC,UAAU,EACb,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC,EAClC,WAAW,EAAE,CAAC,CAAC,8BAA8B,CAAC,EAC9C,OAAO,EACL,cAAK,SAAS,EAAC,MAAM,YACnB,KAAC,cAAc,IAAC,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC,GAAI,GAClD,GAER,EACF,KAAC,WAAW,IACV,EAAE,EAAC,qBAAqB,EACxB,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,EACnC,WAAW,EAAE,CAAC,CAAC,+BAA+B,CAAC,EAC/C,OAAO,EAAE,sBAAsB,GAC/B,EACD,cAAc,IACD,EAEhB,KAAC,aAAa,IAAC,EAAE,EAAC,YAAY,YAC5B,MAAC,WAAW,IACV,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,EACnC,WAAW,EAAE,CAAC,CAAC,+BAA+B,CAAC,EAC/C,OAAO,EAAE,eAAe,aAExB,YAAG,SAAS,EAAC,yCAAyC,YACnD,CAAC,CAAC,2CAA2C,CAAC,GAC7C,EACH,qBAAqB,IACV,GACA,IACZ,EAER,aAAa,EACX,MAAC,aAAa,IAAC,EAAE,EAAC,WAAW,EAAC,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,aAC/D,KAAC,WAAW,IACV,EAAE,EAAC,YAAY,EACf,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,EACnC,WAAW,EAAE,CAAC,CAAC,+BAA+B,CAAC,EAC/C,OAAO,EAAE,eAAe,YAEvB,qBAAqB,GACV,EACd,KAAC,WAAW,IACV,EAAE,EAAC,qBAAqB,EACxB,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,EACnC,WAAW,EAAE,CAAC,CAAC,+BAA+B,CAAC,EAC/C,OAAO,EAAE,sBAAsB,GAC/B,EACD,cAAc,IACD,EAElB,QAAQ,EACN,cAAK,SAAS,EAAC,0BAA0B,YACvC,KAAC,qBAAqB,IAAC,QAAQ,EAAE,SAAS,GAAI,GAC1C,EAER,gBAAgB,EAAE,SAAS,GAC3B,CACH,CAAC;AACJ,CAAC","sourcesContent":["import {\n CHAT_FIRST_MODE_CHANGED_EVENT,\n readChatFirstModeState,\n writeChatFirstMode,\n} from \"@agent-native/core/client/agent-chat\";\nimport {\n useFeatureFlag,\n useFeatureFlagState,\n} from \"@agent-native/core/client/feature-flags\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { SETTINGS_REDESIGN_FLAG } from \"@agent-native/core/feature-flags/registry\";\nimport { ChangelogSettingsCard } from \"@agent-native/toolkit/app/changelog\";\nimport { OrgMembersPage, TeamPage } from \"@agent-native/toolkit/app/org\";\nimport {\n AccountSettingsCard,\n CORE_SETTINGS_PAGES,\n registerSettingsPages,\n SettingsGroup,\n SettingsRow,\n SettingsTabsPage,\n useAgentSettingsTabs,\n type SettingsSearchEntry,\n} from \"@agent-native/toolkit/app/settings\";\nimport { LanguagePicker } from \"@agent-native/toolkit/app/shared\";\nimport { IconShield } from \"@tabler/icons-react\";\nimport { useMemo, useState } from \"react\";\nimport { Link } from \"react-router\";\n\nimport { Button } from \"../../components/ui/button\";\nimport { Switch } from \"../../components/ui/switch\";\nimport { dispatchAccessDescriptor } from \"../../shared/app-roles.js\";\nimport { DISPATCH_CONNECT_APPS_FLAG } from \"../../shared/feature-flags.js\";\n\nconst coreMembersPage = CORE_SETTINGS_PAGES.find(\n (page) => page.id === \"members\",\n);\nif (!coreMembersPage) {\n throw new Error(\"Core Settings has no members page for Dispatch app roles\");\n}\n\nfunction DispatchMembersSettingsPage() {\n return <OrgMembersPage appRoles={dispatchAccessDescriptor} />;\n}\n\n// The redesigned Settings shows Members from core; Dispatch's replaces it so\n// the app-role column stays.\nregisterSettingsPages([\n { ...coreMembersPage, component: DispatchMembersSettingsPage },\n]);\n\nexport function meta() {\n return [{ title: \"Settings - Dispatch\" }];\n}\n\nexport interface DispatchSettingsPageProps {\n /** Raw CHANGELOG.md behind What's new. */\n changelog: string;\n}\n\n/** The template route supplies the app's own changelog. */\nexport function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {\n const t = useT();\n const connectAppsEnabled = useFeatureFlag(DISPATCH_CONNECT_APPS_FLAG.key);\n // Core Preferences owns the interface language in the redesigned Settings,\n // whose Dispatch General page shows `generalGroups` instead of `general`.\n const redesign = useFeatureFlagState(SETTINGS_REDESIGN_FLAG.key).enabled;\n const agentSettingsTabs = useAgentSettingsTabs({\n usageAppId: \"dispatch\",\n usageViewAllHref: \"/admin/metrics\",\n organizationContent: (\n <div className=\"mx-auto w-full max-w-3xl\">\n <TeamPage\n showTitle={false}\n appRoles={dispatchAccessDescriptor}\n createOrgDescription=\"Set up a team to share dispatch destinations and approvals with your colleagues.\"\n />\n </div>\n ),\n });\n const settingsTabs = [\n ...agentSettingsTabs,\n {\n id: \"admin\",\n label: t(\"dispatch.nav.admin\", { defaultValue: \"Admin\" }),\n icon: IconShield,\n group: \"Admin\",\n href: \"/admin\",\n content: null,\n },\n ];\n const [chatFirstModeState] = useState(() => readChatFirstModeState());\n const [chatFirstMode, setChatFirstMode] = useState(\n () => chatFirstModeState.enabled,\n );\n const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState<\n string | null\n >(\n chatFirstModeState.availability === \"unavailable\"\n ? t(\"settings.chatFirstStorageUnavailable\")\n : null,\n );\n\n function updateChatFirstMode(enabled: boolean) {\n const result = writeChatFirstMode(enabled);\n if (!result.ok) {\n setChatFirstStorageNotice(t(\"settings.chatFirstStorageBlocked\"));\n return;\n }\n setChatFirstStorageNotice(null);\n setChatFirstMode(enabled);\n window.dispatchEvent(\n new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {\n detail: { enabled },\n }),\n );\n }\n\n const generalSearchEntries = useMemo<SettingsSearchEntry[]>(\n () => [\n ...(redesign\n ? []\n : [\n {\n id: \"dispatch-language\",\n label: t(\"settings.languageTitle\"),\n keywords: \"language locale translation i18n\",\n hash: \"language\",\n },\n ]),\n {\n id: \"dispatch-workspace\",\n label: redesign\n ? t(\"settings.resourcesTitle\")\n : t(\"settings.workspaceTitle\"),\n keywords: \"workspace resources integrations vault destinations\",\n hash: \"workspace-resources\",\n },\n {\n id: \"dispatch-chat-first\",\n label: t(\"settings.chatFirstTitle\"),\n keywords: \"chat first codex t3 apps pane navigation\",\n hash: \"chat-first\",\n },\n ],\n [redesign, t],\n );\n\n const chatFirstSwitch = (\n <Switch\n aria-label={t(\"settings.chatFirstAriaLabel\")}\n checked={chatFirstMode}\n onCheckedChange={updateChatFirstMode}\n />\n );\n const chatFirstStorageAlert = chatFirstStorageNotice ? (\n <p className=\"text-sm text-destructive\" role=\"alert\">\n {chatFirstStorageNotice}\n </p>\n ) : null;\n const connectAppsRow = connectAppsEnabled ? (\n <SettingsRow\n id=\"connect-apps\"\n label={t(\"settings.connectApps\")}\n description={t(\"settings.connectAppsDescription\")}\n control={\n <Button variant=\"outline\" asChild>\n <Link to=\"/connect\">{t(\"settings.openConnectApps\")}</Link>\n </Button>\n }\n />\n ) : null;\n const resourceSettingsButton = (\n <Button variant=\"outline\" asChild>\n <Link to=\"/workspace\">{t(\"settings.openResourceSettings\")}</Link>\n </Button>\n );\n\n return (\n <SettingsTabsPage\n account={<AccountSettingsCard />}\n extraTabs={settingsTabs}\n generalSearchEntries={generalSearchEntries}\n general={\n <div className=\"mx-auto w-full max-w-2xl space-y-6\">\n <p className=\"text-sm leading-6 text-muted-foreground\">\n {t(\"settings.description\")}\n </p>\n\n <SettingsGroup>\n <SettingsRow\n id=\"language\"\n label={t(\"settings.languageTitle\")}\n description={t(\"settings.languageDescription\")}\n control={\n <div className=\"w-56\">\n <LanguagePicker label={t(\"settings.languageLabel\")} />\n </div>\n }\n />\n <SettingsRow\n id=\"workspace-resources\"\n label={t(\"settings.workspaceTitle\")}\n description={t(\"settings.workspaceDescription\")}\n control={resourceSettingsButton}\n />\n {connectAppsRow}\n </SettingsGroup>\n\n <SettingsGroup id=\"chat-first\">\n <SettingsRow\n label={t(\"settings.chatFirstTitle\")}\n description={t(\"settings.chatFirstDescription\")}\n control={chatFirstSwitch}\n >\n <p className=\"text-sm leading-6 text-muted-foreground\">\n {t(\"settings.chatFirstSessionWatchDescription\")}\n </p>\n {chatFirstStorageAlert}\n </SettingsRow>\n </SettingsGroup>\n </div>\n }\n generalGroups={\n <SettingsGroup id=\"workspace\" title={t(\"settings.workspaceTitle\")}>\n <SettingsRow\n id=\"chat-first\"\n label={t(\"settings.chatFirstTitle\")}\n description={t(\"settings.chatFirstDescription\")}\n control={chatFirstSwitch}\n >\n {chatFirstStorageAlert}\n </SettingsRow>\n <SettingsRow\n id=\"workspace-resources\"\n label={t(\"settings.resourcesTitle\")}\n description={t(\"settings.workspaceDescription\")}\n control={resourceSettingsButton}\n />\n {connectAppsRow}\n </SettingsGroup>\n }\n whatsNew={\n <div className=\"mx-auto w-full max-w-2xl\">\n <ChangelogSettingsCard markdown={changelog} />\n </div>\n }\n whatsNewMarkdown={changelog}\n />\n );\n}\n"]}
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
export
|
|
5
|
-
/** Raw CHANGELOG.md behind What's new. */
|
|
6
|
-
changelog: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Dispatch's Settings. The template route renders it with the app's own
|
|
10
|
-
* changelog; `dispatchRoutes` consumers get the default export.
|
|
11
|
-
*/
|
|
12
|
-
export declare function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps): import("node_modules/@types/react").JSX.Element;
|
|
1
|
+
import { DispatchSettingsPage } from "./settings-page.js";
|
|
2
|
+
export { DispatchSettingsPage };
|
|
3
|
+
export type { DispatchSettingsPageProps } from "./settings-page.js";
|
|
4
|
+
export { meta } from "./settings-page.js";
|
|
13
5
|
export default function SettingsRoute(): import("node_modules/@types/react").JSX.Element;
|
|
14
6
|
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,YAAY,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,MAAM,CAAC,OAAO,UAAU,aAAa,oDAEpC"}
|
|
@@ -1,110 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import { CHAT_FIRST_MODE_CHANGED_EVENT, readChatFirstModeState, writeChatFirstMode, } from "@agent-native/core/client/agent-chat";
|
|
3
|
-
import { useFeatureFlag, useFeatureFlagState, } from "@agent-native/core/client/feature-flags";
|
|
4
|
-
import { useT } from "@agent-native/core/client/i18n";
|
|
5
|
-
import { SETTINGS_REDESIGN_FLAG } from "@agent-native/core/feature-flags/registry";
|
|
6
|
-
import { ChangelogSettingsCard } from "@agent-native/toolkit/app/changelog";
|
|
7
|
-
import { OrgMembersPage, TeamPage } from "@agent-native/toolkit/app/org";
|
|
8
|
-
import { AccountSettingsCard, CORE_SETTINGS_PAGES, registerSettingsPages, SettingsGroup, SettingsRow, SettingsTabsPage, useAgentSettingsTabs, } from "@agent-native/toolkit/app/settings";
|
|
9
|
-
import { LanguagePicker } from "@agent-native/toolkit/app/shared";
|
|
10
|
-
import { IconShield } from "@tabler/icons-react";
|
|
11
|
-
import { useMemo, useState } from "react";
|
|
12
|
-
import { Link } from "react-router";
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
2
|
import packageChangelog from "../../../CHANGELOG.md?raw";
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import { DISPATCH_CONNECT_APPS_FLAG } from "../../shared/feature-flags.js";
|
|
18
|
-
const coreMembersPage = CORE_SETTINGS_PAGES.find((page) => page.id === "members");
|
|
19
|
-
if (!coreMembersPage) {
|
|
20
|
-
throw new Error("Core Settings has no members page for Dispatch app roles");
|
|
21
|
-
}
|
|
22
|
-
function DispatchMembersSettingsPage() {
|
|
23
|
-
return _jsx(OrgMembersPage, { appRoles: dispatchAccessDescriptor });
|
|
24
|
-
}
|
|
25
|
-
// The redesigned Settings shows Members from core; Dispatch's replaces it so
|
|
26
|
-
// the app-role column stays.
|
|
27
|
-
registerSettingsPages([
|
|
28
|
-
{ ...coreMembersPage, component: DispatchMembersSettingsPage },
|
|
29
|
-
]);
|
|
30
|
-
export function meta() {
|
|
31
|
-
return [{ title: "Settings - Dispatch" }];
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Dispatch's Settings. The template route renders it with the app's own
|
|
35
|
-
* changelog; `dispatchRoutes` consumers get the default export.
|
|
36
|
-
*/
|
|
37
|
-
export function DispatchSettingsPage({ changelog }) {
|
|
38
|
-
const t = useT();
|
|
39
|
-
const connectAppsEnabled = useFeatureFlag(DISPATCH_CONNECT_APPS_FLAG.key);
|
|
40
|
-
// Core Preferences owns the interface language in the redesigned Settings,
|
|
41
|
-
// whose Dispatch General page shows `generalGroups` instead of `general`.
|
|
42
|
-
const redesign = useFeatureFlagState(SETTINGS_REDESIGN_FLAG.key).enabled;
|
|
43
|
-
const agentSettingsTabs = useAgentSettingsTabs({
|
|
44
|
-
usageAppId: "dispatch",
|
|
45
|
-
usageViewAllHref: "/admin/metrics",
|
|
46
|
-
organizationContent: (_jsx("div", { className: "mx-auto w-full max-w-3xl", children: _jsx(TeamPage, { showTitle: false, appRoles: dispatchAccessDescriptor, createOrgDescription: "Set up a team to share dispatch destinations and approvals with your colleagues." }) })),
|
|
47
|
-
});
|
|
48
|
-
const settingsTabs = [
|
|
49
|
-
...agentSettingsTabs,
|
|
50
|
-
{
|
|
51
|
-
id: "admin",
|
|
52
|
-
label: t("dispatch.nav.admin", { defaultValue: "Admin" }),
|
|
53
|
-
icon: IconShield,
|
|
54
|
-
group: "Admin",
|
|
55
|
-
href: "/admin",
|
|
56
|
-
content: null,
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
const [chatFirstModeState] = useState(() => readChatFirstModeState());
|
|
60
|
-
const [chatFirstMode, setChatFirstMode] = useState(() => chatFirstModeState.enabled);
|
|
61
|
-
const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState(chatFirstModeState.availability === "unavailable"
|
|
62
|
-
? t("settings.chatFirstStorageUnavailable")
|
|
63
|
-
: null);
|
|
64
|
-
function updateChatFirstMode(enabled) {
|
|
65
|
-
const result = writeChatFirstMode(enabled);
|
|
66
|
-
if (!result.ok) {
|
|
67
|
-
setChatFirstStorageNotice(t("settings.chatFirstStorageBlocked"));
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
setChatFirstStorageNotice(null);
|
|
71
|
-
setChatFirstMode(enabled);
|
|
72
|
-
window.dispatchEvent(new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {
|
|
73
|
-
detail: { enabled },
|
|
74
|
-
}));
|
|
75
|
-
}
|
|
76
|
-
const generalSearchEntries = useMemo(() => [
|
|
77
|
-
...(redesign
|
|
78
|
-
? []
|
|
79
|
-
: [
|
|
80
|
-
{
|
|
81
|
-
id: "dispatch-language",
|
|
82
|
-
label: t("settings.languageTitle"),
|
|
83
|
-
keywords: "language locale translation i18n",
|
|
84
|
-
hash: "language",
|
|
85
|
-
},
|
|
86
|
-
]),
|
|
87
|
-
{
|
|
88
|
-
id: "dispatch-workspace",
|
|
89
|
-
label: redesign
|
|
90
|
-
? t("settings.resourcesTitle")
|
|
91
|
-
: t("settings.workspaceTitle"),
|
|
92
|
-
keywords: "workspace resources integrations vault destinations",
|
|
93
|
-
hash: "workspace-resources",
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
id: "dispatch-chat-first",
|
|
97
|
-
label: t("settings.chatFirstTitle"),
|
|
98
|
-
keywords: "chat first codex t3 apps pane navigation",
|
|
99
|
-
hash: "chat-first",
|
|
100
|
-
},
|
|
101
|
-
], [redesign, t]);
|
|
102
|
-
const chatFirstSwitch = (_jsx(Switch, { "aria-label": t("settings.chatFirstAriaLabel"), checked: chatFirstMode, onCheckedChange: updateChatFirstMode }));
|
|
103
|
-
const chatFirstStorageAlert = chatFirstStorageNotice ? (_jsx("p", { className: "text-sm text-destructive", role: "alert", children: chatFirstStorageNotice })) : null;
|
|
104
|
-
const connectAppsRow = connectAppsEnabled ? (_jsx(SettingsRow, { id: "connect-apps", label: t("settings.connectApps"), description: t("settings.connectAppsDescription"), control: _jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/connect", children: t("settings.openConnectApps") }) }) })) : null;
|
|
105
|
-
const resourceSettingsButton = (_jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/workspace", children: t("settings.openResourceSettings") }) }));
|
|
106
|
-
return (_jsx(SettingsTabsPage, { account: _jsx(AccountSettingsCard, {}), extraTabs: settingsTabs, generalSearchEntries: generalSearchEntries, general: _jsxs("div", { className: "mx-auto w-full max-w-2xl space-y-6", children: [_jsx("p", { className: "text-sm leading-6 text-muted-foreground", children: t("settings.description") }), _jsxs(SettingsGroup, { children: [_jsx(SettingsRow, { id: "language", label: t("settings.languageTitle"), description: t("settings.languageDescription"), control: _jsx("div", { className: "w-56", children: _jsx(LanguagePicker, { label: t("settings.languageLabel") }) }) }), _jsx(SettingsRow, { id: "workspace-resources", label: t("settings.workspaceTitle"), description: t("settings.workspaceDescription"), control: resourceSettingsButton }), connectAppsRow] }), _jsx(SettingsGroup, { id: "chat-first", children: _jsxs(SettingsRow, { label: t("settings.chatFirstTitle"), description: t("settings.chatFirstDescription"), control: chatFirstSwitch, children: [_jsx("p", { className: "text-sm leading-6 text-muted-foreground", children: t("settings.chatFirstSessionWatchDescription") }), chatFirstStorageAlert] }) })] }), generalGroups: _jsxs(SettingsGroup, { id: "workspace", title: t("settings.workspaceTitle"), children: [_jsx(SettingsRow, { id: "chat-first", label: t("settings.chatFirstTitle"), description: t("settings.chatFirstDescription"), control: chatFirstSwitch, children: chatFirstStorageAlert }), _jsx(SettingsRow, { id: "workspace-resources", label: t("settings.resourcesTitle"), description: t("settings.workspaceDescription"), control: resourceSettingsButton }), connectAppsRow] }), whatsNew: _jsx("div", { className: "mx-auto w-full max-w-2xl", children: _jsx(ChangelogSettingsCard, { markdown: changelog }) }), whatsNewMarkdown: changelog }));
|
|
107
|
-
}
|
|
3
|
+
import { DispatchSettingsPage } from "./settings-page.js";
|
|
4
|
+
export { DispatchSettingsPage };
|
|
5
|
+
export { meta } from "./settings-page.js";
|
|
108
6
|
export default function SettingsRoute() {
|
|
109
7
|
return _jsx(DispatchSettingsPage, { changelog: packageChangelog });
|
|
110
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n CHAT_FIRST_MODE_CHANGED_EVENT,\n readChatFirstModeState,\n writeChatFirstMode,\n} from \"@agent-native/core/client/agent-chat\";\nimport {\n useFeatureFlag,\n useFeatureFlagState,\n} from \"@agent-native/core/client/feature-flags\";\nimport { useT } from \"@agent-native/core/client/i18n\";\nimport { SETTINGS_REDESIGN_FLAG } from \"@agent-native/core/feature-flags/registry\";\nimport { ChangelogSettingsCard } from \"@agent-native/toolkit/app/changelog\";\nimport { OrgMembersPage, TeamPage } from \"@agent-native/toolkit/app/org\";\nimport {\n AccountSettingsCard,\n CORE_SETTINGS_PAGES,\n registerSettingsPages,\n SettingsGroup,\n SettingsRow,\n SettingsTabsPage,\n useAgentSettingsTabs,\n type SettingsSearchEntry,\n} from \"@agent-native/toolkit/app/settings\";\nimport { LanguagePicker } from \"@agent-native/toolkit/app/shared\";\nimport { IconShield } from \"@tabler/icons-react\";\nimport { useMemo, useState } from \"react\";\nimport { Link } from \"react-router\";\n\nimport packageChangelog from \"../../../CHANGELOG.md?raw\";\nimport { Button } from \"../../components/ui/button\";\nimport { Switch } from \"../../components/ui/switch\";\nimport { dispatchAccessDescriptor } from \"../../shared/app-roles.js\";\nimport { DISPATCH_CONNECT_APPS_FLAG } from \"../../shared/feature-flags.js\";\n\nconst coreMembersPage = CORE_SETTINGS_PAGES.find(\n (page) => page.id === \"members\",\n);\nif (!coreMembersPage) {\n throw new Error(\"Core Settings has no members page for Dispatch app roles\");\n}\n\nfunction DispatchMembersSettingsPage() {\n return <OrgMembersPage appRoles={dispatchAccessDescriptor} />;\n}\n\n// The redesigned Settings shows Members from core; Dispatch's replaces it so\n// the app-role column stays.\nregisterSettingsPages([\n { ...coreMembersPage, component: DispatchMembersSettingsPage },\n]);\n\nexport function meta() {\n return [{ title: \"Settings - Dispatch\" }];\n}\n\nexport interface DispatchSettingsPageProps {\n /** Raw CHANGELOG.md behind What's new. */\n changelog: string;\n}\n\n/**\n * Dispatch's Settings. The template route renders it with the app's own\n * changelog; `dispatchRoutes` consumers get the default export.\n */\nexport function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {\n const t = useT();\n const connectAppsEnabled = useFeatureFlag(DISPATCH_CONNECT_APPS_FLAG.key);\n // Core Preferences owns the interface language in the redesigned Settings,\n // whose Dispatch General page shows `generalGroups` instead of `general`.\n const redesign = useFeatureFlagState(SETTINGS_REDESIGN_FLAG.key).enabled;\n const agentSettingsTabs = useAgentSettingsTabs({\n usageAppId: \"dispatch\",\n usageViewAllHref: \"/admin/metrics\",\n organizationContent: (\n <div className=\"mx-auto w-full max-w-3xl\">\n <TeamPage\n showTitle={false}\n appRoles={dispatchAccessDescriptor}\n createOrgDescription=\"Set up a team to share dispatch destinations and approvals with your colleagues.\"\n />\n </div>\n ),\n });\n const settingsTabs = [\n ...agentSettingsTabs,\n {\n id: \"admin\",\n label: t(\"dispatch.nav.admin\", { defaultValue: \"Admin\" }),\n icon: IconShield,\n group: \"Admin\",\n href: \"/admin\",\n content: null,\n },\n ];\n const [chatFirstModeState] = useState(() => readChatFirstModeState());\n const [chatFirstMode, setChatFirstMode] = useState(\n () => chatFirstModeState.enabled,\n );\n const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState<\n string | null\n >(\n chatFirstModeState.availability === \"unavailable\"\n ? t(\"settings.chatFirstStorageUnavailable\")\n : null,\n );\n\n function updateChatFirstMode(enabled: boolean) {\n const result = writeChatFirstMode(enabled);\n if (!result.ok) {\n setChatFirstStorageNotice(t(\"settings.chatFirstStorageBlocked\"));\n return;\n }\n setChatFirstStorageNotice(null);\n setChatFirstMode(enabled);\n window.dispatchEvent(\n new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {\n detail: { enabled },\n }),\n );\n }\n\n const generalSearchEntries = useMemo<SettingsSearchEntry[]>(\n () => [\n ...(redesign\n ? []\n : [\n {\n id: \"dispatch-language\",\n label: t(\"settings.languageTitle\"),\n keywords: \"language locale translation i18n\",\n hash: \"language\",\n },\n ]),\n {\n id: \"dispatch-workspace\",\n label: redesign\n ? t(\"settings.resourcesTitle\")\n : t(\"settings.workspaceTitle\"),\n keywords: \"workspace resources integrations vault destinations\",\n hash: \"workspace-resources\",\n },\n {\n id: \"dispatch-chat-first\",\n label: t(\"settings.chatFirstTitle\"),\n keywords: \"chat first codex t3 apps pane navigation\",\n hash: \"chat-first\",\n },\n ],\n [redesign, t],\n );\n\n const chatFirstSwitch = (\n <Switch\n aria-label={t(\"settings.chatFirstAriaLabel\")}\n checked={chatFirstMode}\n onCheckedChange={updateChatFirstMode}\n />\n );\n const chatFirstStorageAlert = chatFirstStorageNotice ? (\n <p className=\"text-sm text-destructive\" role=\"alert\">\n {chatFirstStorageNotice}\n </p>\n ) : null;\n const connectAppsRow = connectAppsEnabled ? (\n <SettingsRow\n id=\"connect-apps\"\n label={t(\"settings.connectApps\")}\n description={t(\"settings.connectAppsDescription\")}\n control={\n <Button variant=\"outline\" asChild>\n <Link to=\"/connect\">{t(\"settings.openConnectApps\")}</Link>\n </Button>\n }\n />\n ) : null;\n const resourceSettingsButton = (\n <Button variant=\"outline\" asChild>\n <Link to=\"/workspace\">{t(\"settings.openResourceSettings\")}</Link>\n </Button>\n );\n\n return (\n <SettingsTabsPage\n account={<AccountSettingsCard />}\n extraTabs={settingsTabs}\n generalSearchEntries={generalSearchEntries}\n general={\n <div className=\"mx-auto w-full max-w-2xl space-y-6\">\n <p className=\"text-sm leading-6 text-muted-foreground\">\n {t(\"settings.description\")}\n </p>\n\n <SettingsGroup>\n <SettingsRow\n id=\"language\"\n label={t(\"settings.languageTitle\")}\n description={t(\"settings.languageDescription\")}\n control={\n <div className=\"w-56\">\n <LanguagePicker label={t(\"settings.languageLabel\")} />\n </div>\n }\n />\n <SettingsRow\n id=\"workspace-resources\"\n label={t(\"settings.workspaceTitle\")}\n description={t(\"settings.workspaceDescription\")}\n control={resourceSettingsButton}\n />\n {connectAppsRow}\n </SettingsGroup>\n\n <SettingsGroup id=\"chat-first\">\n <SettingsRow\n label={t(\"settings.chatFirstTitle\")}\n description={t(\"settings.chatFirstDescription\")}\n control={chatFirstSwitch}\n >\n <p className=\"text-sm leading-6 text-muted-foreground\">\n {t(\"settings.chatFirstSessionWatchDescription\")}\n </p>\n {chatFirstStorageAlert}\n </SettingsRow>\n </SettingsGroup>\n </div>\n }\n generalGroups={\n <SettingsGroup id=\"workspace\" title={t(\"settings.workspaceTitle\")}>\n <SettingsRow\n id=\"chat-first\"\n label={t(\"settings.chatFirstTitle\")}\n description={t(\"settings.chatFirstDescription\")}\n control={chatFirstSwitch}\n >\n {chatFirstStorageAlert}\n </SettingsRow>\n <SettingsRow\n id=\"workspace-resources\"\n label={t(\"settings.resourcesTitle\")}\n description={t(\"settings.workspaceDescription\")}\n control={resourceSettingsButton}\n />\n {connectAppsRow}\n </SettingsGroup>\n }\n whatsNew={\n <div className=\"mx-auto w-full max-w-2xl\">\n <ChangelogSettingsCard markdown={changelog} />\n </div>\n }\n whatsNewMarkdown={changelog}\n />\n );\n}\n\nexport default function SettingsRoute() {\n return <DispatchSettingsPage changelog={packageChangelog} />;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/routes/pages/settings.tsx"],"names":[],"mappings":";AAAA,OAAO,gBAAgB,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,MAAM,CAAC,OAAO,UAAU,aAAa;IACnC,OAAO,KAAC,oBAAoB,IAAC,SAAS,EAAE,gBAAgB,GAAI,CAAC;AAC/D,CAAC","sourcesContent":["import packageChangelog from \"../../../CHANGELOG.md?raw\";\nimport { DispatchSettingsPage } from \"./settings-page.js\";\n\nexport { DispatchSettingsPage };\nexport type { DispatchSettingsPageProps } from \"./settings-page.js\";\nexport { meta } from \"./settings-page.js\";\n\nexport default function SettingsRoute() {\n return <DispatchSettingsPage changelog={packageChangelog} />;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.4-nightly-20260930124743",
|
|
4
4
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"tailwind-merge": "^3.5.0",
|
|
90
90
|
"vaul": "^1.1.2",
|
|
91
91
|
"zod": "^4.3.6",
|
|
92
|
-
"@agent-native/toolkit": "0.198.
|
|
92
|
+
"@agent-native/toolkit": "0.198.3-nightly-20260930124743"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@react-router/dev": "^8.1.0",
|
|
@@ -103,10 +103,10 @@
|
|
|
103
103
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
104
104
|
"vite": "8.1.0",
|
|
105
105
|
"vitest": "^4.1.5",
|
|
106
|
-
"@agent-native/core": "0.198.
|
|
106
|
+
"@agent-native/core": "0.198.3-nightly-20260930124743"
|
|
107
107
|
},
|
|
108
108
|
"peerDependencies": {
|
|
109
|
-
"@agent-native/core": "
|
|
109
|
+
"@agent-native/core": "0.198.3-nightly-20260930124743",
|
|
110
110
|
"react": ">=19.2.7",
|
|
111
111
|
"react-dom": ">=19.2.7",
|
|
112
112
|
"react-router": ">=8"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSettingsPathname } from "@agent-native/toolkit/app/settings";
|
|
1
2
|
// @vitest-environment happy-dom
|
|
2
3
|
import React, { act } from "react";
|
|
3
4
|
import { createRoot, type Root } from "react-dom/client";
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
dispatchNavLinkTarget,
|
|
13
14
|
formatThreadAge,
|
|
14
15
|
isElectronEmbeddedSearch,
|
|
15
|
-
|
|
16
|
+
isRedesignedSettingsPath,
|
|
16
17
|
NavContent,
|
|
17
18
|
renderChatFirstAppSurfaceTab,
|
|
18
19
|
shouldAutoCollapseDispatchSidebar,
|
|
@@ -30,13 +31,27 @@ const clientState = vi.hoisted(() => ({
|
|
|
30
31
|
.mockResolvedValue({ startUrl: "about:blank" }),
|
|
31
32
|
}));
|
|
32
33
|
|
|
33
|
-
vi.mock("@agent-native/core/client/agent-chat", () => ({
|
|
34
|
+
vi.mock("@agent-native/core/client/agent-chat", async (importOriginal) => ({
|
|
35
|
+
...(await importOriginal<
|
|
36
|
+
typeof import("@agent-native/core/client/agent-chat")
|
|
37
|
+
>()),
|
|
34
38
|
navigateWithAgentChatViewTransition: (
|
|
35
39
|
navigate: (path: string) => void,
|
|
36
40
|
path: string,
|
|
37
41
|
) => navigate(path),
|
|
38
42
|
useAgentChatHomeHandoff: () => false,
|
|
39
43
|
useAgentChatHomeHandoffLinks: vi.fn(),
|
|
44
|
+
useChatModels: () => ({
|
|
45
|
+
availableModels: [],
|
|
46
|
+
defaultModel: "auto",
|
|
47
|
+
selectedModel: "auto",
|
|
48
|
+
selectedEngine: "",
|
|
49
|
+
selectedEffort: "medium" as const,
|
|
50
|
+
isLoading: false,
|
|
51
|
+
onModelChange: vi.fn(),
|
|
52
|
+
onEffortChange: vi.fn(),
|
|
53
|
+
refreshEngines: vi.fn(),
|
|
54
|
+
}),
|
|
40
55
|
useChatThreads: () => ({
|
|
41
56
|
threads: clientState.threads,
|
|
42
57
|
activeThreadId: "active-thread",
|
|
@@ -46,10 +61,20 @@ vi.mock("@agent-native/core/client/agent-chat", () => ({
|
|
|
46
61
|
renameThread: vi.fn(),
|
|
47
62
|
refreshThreads: vi.fn(),
|
|
48
63
|
}),
|
|
64
|
+
useChatModels: () => ({
|
|
65
|
+
availableModels: [],
|
|
66
|
+
defaultModel: "auto",
|
|
67
|
+
selectedModel: "auto",
|
|
68
|
+
selectedEngine: "auto",
|
|
69
|
+
selectedEffort: "medium",
|
|
70
|
+
setSelectedModel: vi.fn(),
|
|
71
|
+
}),
|
|
49
72
|
}));
|
|
50
73
|
|
|
51
74
|
vi.mock("@agent-native/toolkit/app/chat", async (importOriginal) => ({
|
|
52
75
|
...(await importOriginal<typeof import("@agent-native/toolkit/app/chat")>()),
|
|
76
|
+
AgentChatSurface: () => null,
|
|
77
|
+
AgentToggleButton: () => null,
|
|
53
78
|
AgentSidebar: ({ children }: { children: React.ReactNode }) => (
|
|
54
79
|
<div data-agent-sidebar>{children}</div>
|
|
55
80
|
),
|
|
@@ -65,9 +90,11 @@ vi.mock("@agent-native/core/client/api-path", () => ({
|
|
|
65
90
|
clientState.basePath && path.startsWith("/")
|
|
66
91
|
? `${clientState.basePath}${path}`
|
|
67
92
|
: path,
|
|
93
|
+
frameworkRoutePrefix: () => "",
|
|
68
94
|
}));
|
|
69
95
|
|
|
70
|
-
vi.mock("@agent-native/core/client/hooks", () => ({
|
|
96
|
+
vi.mock("@agent-native/core/client/hooks", async (importOriginal) => ({
|
|
97
|
+
...(await importOriginal<typeof import("@agent-native/core/client/hooks")>()),
|
|
71
98
|
useActionQuery: (action: string) => ({
|
|
72
99
|
data:
|
|
73
100
|
action === "list-workspace-apps" ? clientState.workspaceApps : undefined,
|
|
@@ -87,6 +114,7 @@ vi.mock("next-themes", () => ({
|
|
|
87
114
|
}));
|
|
88
115
|
|
|
89
116
|
vi.mock("@agent-native/core/client/i18n", () => ({
|
|
117
|
+
useFormatters: () => ({ formatNumber: (value: number) => String(value) }),
|
|
90
118
|
useT: () => (key: string, values?: Record<string, unknown>) => {
|
|
91
119
|
const messages: Record<string, string> = {
|
|
92
120
|
"dispatch.nav.chat": "Chat",
|
|
@@ -115,6 +143,10 @@ vi.mock("@agent-native/toolkit/app/shared", async (importOriginal) => ({
|
|
|
115
143
|
openCommandMenu: vi.fn(),
|
|
116
144
|
}));
|
|
117
145
|
|
|
146
|
+
vi.mock("../create-app-popover", () => ({
|
|
147
|
+
CreateAppPopover: () => null,
|
|
148
|
+
}));
|
|
149
|
+
|
|
118
150
|
vi.mock("@agent-native/toolkit/app/feedback", () => ({
|
|
119
151
|
FeedbackButton: () => <div>Feedback</div>,
|
|
120
152
|
}));
|
|
@@ -204,14 +236,34 @@ describe("Dispatch workspace app sidebar", () => {
|
|
|
204
236
|
|
|
205
237
|
describe("Dispatch Settings frame", () => {
|
|
206
238
|
it("drops the Dispatch chrome on Settings", () => {
|
|
207
|
-
|
|
208
|
-
expect(
|
|
209
|
-
expect(
|
|
239
|
+
const settingsEnabled = { enabled: true, status: "ready" } as const;
|
|
240
|
+
expect(isRedesignedSettingsPath("/settings", settingsEnabled)).toBe(true);
|
|
241
|
+
expect(isRedesignedSettingsPath("/settings/members", settingsEnabled)).toBe(
|
|
242
|
+
true,
|
|
243
|
+
);
|
|
244
|
+
expect(isRedesignedSettingsPath("/settings/app", settingsEnabled)).toBe(
|
|
245
|
+
true,
|
|
246
|
+
);
|
|
247
|
+
expect(
|
|
248
|
+
isRedesignedSettingsPath("/settings", {
|
|
249
|
+
enabled: false,
|
|
250
|
+
status: "loading",
|
|
251
|
+
}),
|
|
252
|
+
).toBe(true);
|
|
210
253
|
});
|
|
211
254
|
|
|
212
255
|
it("keeps the Dispatch chrome off Settings", () => {
|
|
213
|
-
|
|
214
|
-
expect(
|
|
256
|
+
const settingsEnabled = { enabled: true, status: "ready" } as const;
|
|
257
|
+
expect(isRedesignedSettingsPath("/admin", settingsEnabled)).toBe(false);
|
|
258
|
+
expect(
|
|
259
|
+
isRedesignedSettingsPath("/apps/mail/settings", settingsEnabled),
|
|
260
|
+
).toBe(false);
|
|
261
|
+
expect(
|
|
262
|
+
isRedesignedSettingsPath("/settings", {
|
|
263
|
+
enabled: false,
|
|
264
|
+
status: "unavailable",
|
|
265
|
+
}),
|
|
266
|
+
).toBe(false);
|
|
215
267
|
});
|
|
216
268
|
});
|
|
217
269
|
|
|
@@ -748,8 +800,8 @@ describe("chat-first surface panel toggle stacking", () => {
|
|
|
748
800
|
it("keeps the toggle above the mobile full-screen surface panel overlay", async () => {
|
|
749
801
|
const { ChatFirstSurfacePanelToggle: RealChatFirstSurfacePanelToggle } =
|
|
750
802
|
await vi.importActual<
|
|
751
|
-
typeof import("@agent-native/
|
|
752
|
-
>("@agent-native/
|
|
803
|
+
typeof import("@agent-native/toolkit/app/chat/chat-first")
|
|
804
|
+
>("@agent-native/toolkit/app/chat/chat-first");
|
|
753
805
|
const { ChatFirstSurfacePanel } =
|
|
754
806
|
await import("@agent-native/toolkit/app/chat/chat-first");
|
|
755
807
|
|
|
@@ -10,7 +10,7 @@ const railState = vi.hoisted(() => ({
|
|
|
10
10
|
mutateAsync: vi.fn().mockResolvedValue({ startUrl: "about:blank" }),
|
|
11
11
|
}));
|
|
12
12
|
|
|
13
|
-
vi.mock("@agent-native/
|
|
13
|
+
vi.mock("@agent-native/toolkit/app/chat", () => ({
|
|
14
14
|
AgentSidebar: (props: Record<string, unknown>) => {
|
|
15
15
|
railState.sidebarProps.push(props);
|
|
16
16
|
return (
|
|
@@ -12,7 +12,7 @@ const browserChat = vi.hoisted(() => ({
|
|
|
12
12
|
surfaceProps: null as Record<string, unknown> | null,
|
|
13
13
|
}));
|
|
14
14
|
|
|
15
|
-
vi.mock("@agent-native/
|
|
15
|
+
vi.mock("@agent-native/toolkit/app/chat", () => ({
|
|
16
16
|
AgentChatSurface: (props: Record<string, unknown>) => {
|
|
17
17
|
browserChat.surfaceProps = props;
|
|
18
18
|
return <div data-testid="browser-agent-chat" />;
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CHAT_FIRST_MODE_CHANGED_EVENT,
|
|
3
|
+
readChatFirstModeState,
|
|
4
|
+
writeChatFirstMode,
|
|
5
|
+
} from "@agent-native/core/client/agent-chat";
|
|
6
|
+
import {
|
|
7
|
+
useFeatureFlag,
|
|
8
|
+
useFeatureFlagState,
|
|
9
|
+
} from "@agent-native/core/client/feature-flags";
|
|
10
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
11
|
+
import { SETTINGS_REDESIGN_FLAG } from "@agent-native/core/feature-flags/registry";
|
|
12
|
+
import { ChangelogSettingsCard } from "@agent-native/toolkit/app/changelog";
|
|
13
|
+
import { OrgMembersPage, TeamPage } from "@agent-native/toolkit/app/org";
|
|
14
|
+
import {
|
|
15
|
+
AccountSettingsCard,
|
|
16
|
+
CORE_SETTINGS_PAGES,
|
|
17
|
+
registerSettingsPages,
|
|
18
|
+
SettingsGroup,
|
|
19
|
+
SettingsRow,
|
|
20
|
+
SettingsTabsPage,
|
|
21
|
+
useAgentSettingsTabs,
|
|
22
|
+
type SettingsSearchEntry,
|
|
23
|
+
} from "@agent-native/toolkit/app/settings";
|
|
24
|
+
import { LanguagePicker } from "@agent-native/toolkit/app/shared";
|
|
25
|
+
import { IconShield } from "@tabler/icons-react";
|
|
26
|
+
import { useMemo, useState } from "react";
|
|
27
|
+
import { Link } from "react-router";
|
|
28
|
+
|
|
29
|
+
import { Button } from "../../components/ui/button";
|
|
30
|
+
import { Switch } from "../../components/ui/switch";
|
|
31
|
+
import { dispatchAccessDescriptor } from "../../shared/app-roles.js";
|
|
32
|
+
import { DISPATCH_CONNECT_APPS_FLAG } from "../../shared/feature-flags.js";
|
|
33
|
+
|
|
34
|
+
const coreMembersPage = CORE_SETTINGS_PAGES.find(
|
|
35
|
+
(page) => page.id === "members",
|
|
36
|
+
);
|
|
37
|
+
if (!coreMembersPage) {
|
|
38
|
+
throw new Error("Core Settings has no members page for Dispatch app roles");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function DispatchMembersSettingsPage() {
|
|
42
|
+
return <OrgMembersPage appRoles={dispatchAccessDescriptor} />;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The redesigned Settings shows Members from core; Dispatch's replaces it so
|
|
46
|
+
// the app-role column stays.
|
|
47
|
+
registerSettingsPages([
|
|
48
|
+
{ ...coreMembersPage, component: DispatchMembersSettingsPage },
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
export function meta() {
|
|
52
|
+
return [{ title: "Settings - Dispatch" }];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface DispatchSettingsPageProps {
|
|
56
|
+
/** Raw CHANGELOG.md behind What's new. */
|
|
57
|
+
changelog: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** The template route supplies the app's own changelog. */
|
|
61
|
+
export function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {
|
|
62
|
+
const t = useT();
|
|
63
|
+
const connectAppsEnabled = useFeatureFlag(DISPATCH_CONNECT_APPS_FLAG.key);
|
|
64
|
+
// Core Preferences owns the interface language in the redesigned Settings,
|
|
65
|
+
// whose Dispatch General page shows `generalGroups` instead of `general`.
|
|
66
|
+
const redesign = useFeatureFlagState(SETTINGS_REDESIGN_FLAG.key).enabled;
|
|
67
|
+
const agentSettingsTabs = useAgentSettingsTabs({
|
|
68
|
+
usageAppId: "dispatch",
|
|
69
|
+
usageViewAllHref: "/admin/metrics",
|
|
70
|
+
organizationContent: (
|
|
71
|
+
<div className="mx-auto w-full max-w-3xl">
|
|
72
|
+
<TeamPage
|
|
73
|
+
showTitle={false}
|
|
74
|
+
appRoles={dispatchAccessDescriptor}
|
|
75
|
+
createOrgDescription="Set up a team to share dispatch destinations and approvals with your colleagues."
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
),
|
|
79
|
+
});
|
|
80
|
+
const settingsTabs = [
|
|
81
|
+
...agentSettingsTabs,
|
|
82
|
+
{
|
|
83
|
+
id: "admin",
|
|
84
|
+
label: t("dispatch.nav.admin", { defaultValue: "Admin" }),
|
|
85
|
+
icon: IconShield,
|
|
86
|
+
group: "Admin",
|
|
87
|
+
href: "/admin",
|
|
88
|
+
content: null,
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
const [chatFirstModeState] = useState(() => readChatFirstModeState());
|
|
92
|
+
const [chatFirstMode, setChatFirstMode] = useState(
|
|
93
|
+
() => chatFirstModeState.enabled,
|
|
94
|
+
);
|
|
95
|
+
const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState<
|
|
96
|
+
string | null
|
|
97
|
+
>(
|
|
98
|
+
chatFirstModeState.availability === "unavailable"
|
|
99
|
+
? t("settings.chatFirstStorageUnavailable")
|
|
100
|
+
: null,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
function updateChatFirstMode(enabled: boolean) {
|
|
104
|
+
const result = writeChatFirstMode(enabled);
|
|
105
|
+
if (!result.ok) {
|
|
106
|
+
setChatFirstStorageNotice(t("settings.chatFirstStorageBlocked"));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
setChatFirstStorageNotice(null);
|
|
110
|
+
setChatFirstMode(enabled);
|
|
111
|
+
window.dispatchEvent(
|
|
112
|
+
new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {
|
|
113
|
+
detail: { enabled },
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
|
|
119
|
+
() => [
|
|
120
|
+
...(redesign
|
|
121
|
+
? []
|
|
122
|
+
: [
|
|
123
|
+
{
|
|
124
|
+
id: "dispatch-language",
|
|
125
|
+
label: t("settings.languageTitle"),
|
|
126
|
+
keywords: "language locale translation i18n",
|
|
127
|
+
hash: "language",
|
|
128
|
+
},
|
|
129
|
+
]),
|
|
130
|
+
{
|
|
131
|
+
id: "dispatch-workspace",
|
|
132
|
+
label: redesign
|
|
133
|
+
? t("settings.resourcesTitle")
|
|
134
|
+
: t("settings.workspaceTitle"),
|
|
135
|
+
keywords: "workspace resources integrations vault destinations",
|
|
136
|
+
hash: "workspace-resources",
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: "dispatch-chat-first",
|
|
140
|
+
label: t("settings.chatFirstTitle"),
|
|
141
|
+
keywords: "chat first codex t3 apps pane navigation",
|
|
142
|
+
hash: "chat-first",
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
[redesign, t],
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
const chatFirstSwitch = (
|
|
149
|
+
<Switch
|
|
150
|
+
aria-label={t("settings.chatFirstAriaLabel")}
|
|
151
|
+
checked={chatFirstMode}
|
|
152
|
+
onCheckedChange={updateChatFirstMode}
|
|
153
|
+
/>
|
|
154
|
+
);
|
|
155
|
+
const chatFirstStorageAlert = chatFirstStorageNotice ? (
|
|
156
|
+
<p className="text-sm text-destructive" role="alert">
|
|
157
|
+
{chatFirstStorageNotice}
|
|
158
|
+
</p>
|
|
159
|
+
) : null;
|
|
160
|
+
const connectAppsRow = connectAppsEnabled ? (
|
|
161
|
+
<SettingsRow
|
|
162
|
+
id="connect-apps"
|
|
163
|
+
label={t("settings.connectApps")}
|
|
164
|
+
description={t("settings.connectAppsDescription")}
|
|
165
|
+
control={
|
|
166
|
+
<Button variant="outline" asChild>
|
|
167
|
+
<Link to="/connect">{t("settings.openConnectApps")}</Link>
|
|
168
|
+
</Button>
|
|
169
|
+
}
|
|
170
|
+
/>
|
|
171
|
+
) : null;
|
|
172
|
+
const resourceSettingsButton = (
|
|
173
|
+
<Button variant="outline" asChild>
|
|
174
|
+
<Link to="/workspace">{t("settings.openResourceSettings")}</Link>
|
|
175
|
+
</Button>
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<SettingsTabsPage
|
|
180
|
+
account={<AccountSettingsCard />}
|
|
181
|
+
extraTabs={settingsTabs}
|
|
182
|
+
generalSearchEntries={generalSearchEntries}
|
|
183
|
+
general={
|
|
184
|
+
<div className="mx-auto w-full max-w-2xl space-y-6">
|
|
185
|
+
<p className="text-sm leading-6 text-muted-foreground">
|
|
186
|
+
{t("settings.description")}
|
|
187
|
+
</p>
|
|
188
|
+
|
|
189
|
+
<SettingsGroup>
|
|
190
|
+
<SettingsRow
|
|
191
|
+
id="language"
|
|
192
|
+
label={t("settings.languageTitle")}
|
|
193
|
+
description={t("settings.languageDescription")}
|
|
194
|
+
control={
|
|
195
|
+
<div className="w-56">
|
|
196
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
197
|
+
</div>
|
|
198
|
+
}
|
|
199
|
+
/>
|
|
200
|
+
<SettingsRow
|
|
201
|
+
id="workspace-resources"
|
|
202
|
+
label={t("settings.workspaceTitle")}
|
|
203
|
+
description={t("settings.workspaceDescription")}
|
|
204
|
+
control={resourceSettingsButton}
|
|
205
|
+
/>
|
|
206
|
+
{connectAppsRow}
|
|
207
|
+
</SettingsGroup>
|
|
208
|
+
|
|
209
|
+
<SettingsGroup id="chat-first">
|
|
210
|
+
<SettingsRow
|
|
211
|
+
label={t("settings.chatFirstTitle")}
|
|
212
|
+
description={t("settings.chatFirstDescription")}
|
|
213
|
+
control={chatFirstSwitch}
|
|
214
|
+
>
|
|
215
|
+
<p className="text-sm leading-6 text-muted-foreground">
|
|
216
|
+
{t("settings.chatFirstSessionWatchDescription")}
|
|
217
|
+
</p>
|
|
218
|
+
{chatFirstStorageAlert}
|
|
219
|
+
</SettingsRow>
|
|
220
|
+
</SettingsGroup>
|
|
221
|
+
</div>
|
|
222
|
+
}
|
|
223
|
+
generalGroups={
|
|
224
|
+
<SettingsGroup id="workspace" title={t("settings.workspaceTitle")}>
|
|
225
|
+
<SettingsRow
|
|
226
|
+
id="chat-first"
|
|
227
|
+
label={t("settings.chatFirstTitle")}
|
|
228
|
+
description={t("settings.chatFirstDescription")}
|
|
229
|
+
control={chatFirstSwitch}
|
|
230
|
+
>
|
|
231
|
+
{chatFirstStorageAlert}
|
|
232
|
+
</SettingsRow>
|
|
233
|
+
<SettingsRow
|
|
234
|
+
id="workspace-resources"
|
|
235
|
+
label={t("settings.resourcesTitle")}
|
|
236
|
+
description={t("settings.workspaceDescription")}
|
|
237
|
+
control={resourceSettingsButton}
|
|
238
|
+
/>
|
|
239
|
+
{connectAppsRow}
|
|
240
|
+
</SettingsGroup>
|
|
241
|
+
}
|
|
242
|
+
whatsNew={
|
|
243
|
+
<div className="mx-auto w-full max-w-2xl">
|
|
244
|
+
<ChangelogSettingsCard markdown={changelog} />
|
|
245
|
+
</div>
|
|
246
|
+
}
|
|
247
|
+
whatsNewMarkdown={changelog}
|
|
248
|
+
/>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
@@ -1,257 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CHAT_FIRST_MODE_CHANGED_EVENT,
|
|
3
|
-
readChatFirstModeState,
|
|
4
|
-
writeChatFirstMode,
|
|
5
|
-
} from "@agent-native/core/client/agent-chat";
|
|
6
|
-
import {
|
|
7
|
-
useFeatureFlag,
|
|
8
|
-
useFeatureFlagState,
|
|
9
|
-
} from "@agent-native/core/client/feature-flags";
|
|
10
|
-
import { useT } from "@agent-native/core/client/i18n";
|
|
11
|
-
import { SETTINGS_REDESIGN_FLAG } from "@agent-native/core/feature-flags/registry";
|
|
12
|
-
import { ChangelogSettingsCard } from "@agent-native/toolkit/app/changelog";
|
|
13
|
-
import { OrgMembersPage, TeamPage } from "@agent-native/toolkit/app/org";
|
|
14
|
-
import {
|
|
15
|
-
AccountSettingsCard,
|
|
16
|
-
CORE_SETTINGS_PAGES,
|
|
17
|
-
registerSettingsPages,
|
|
18
|
-
SettingsGroup,
|
|
19
|
-
SettingsRow,
|
|
20
|
-
SettingsTabsPage,
|
|
21
|
-
useAgentSettingsTabs,
|
|
22
|
-
type SettingsSearchEntry,
|
|
23
|
-
} from "@agent-native/toolkit/app/settings";
|
|
24
|
-
import { LanguagePicker } from "@agent-native/toolkit/app/shared";
|
|
25
|
-
import { IconShield } from "@tabler/icons-react";
|
|
26
|
-
import { useMemo, useState } from "react";
|
|
27
|
-
import { Link } from "react-router";
|
|
28
|
-
|
|
29
1
|
import packageChangelog from "../../../CHANGELOG.md?raw";
|
|
30
|
-
import {
|
|
31
|
-
import { Switch } from "../../components/ui/switch";
|
|
32
|
-
import { dispatchAccessDescriptor } from "../../shared/app-roles.js";
|
|
33
|
-
import { DISPATCH_CONNECT_APPS_FLAG } from "../../shared/feature-flags.js";
|
|
34
|
-
|
|
35
|
-
const coreMembersPage = CORE_SETTINGS_PAGES.find(
|
|
36
|
-
(page) => page.id === "members",
|
|
37
|
-
);
|
|
38
|
-
if (!coreMembersPage) {
|
|
39
|
-
throw new Error("Core Settings has no members page for Dispatch app roles");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function DispatchMembersSettingsPage() {
|
|
43
|
-
return <OrgMembersPage appRoles={dispatchAccessDescriptor} />;
|
|
44
|
-
}
|
|
2
|
+
import { DispatchSettingsPage } from "./settings-page.js";
|
|
45
3
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
{ ...coreMembersPage, component: DispatchMembersSettingsPage },
|
|
50
|
-
]);
|
|
51
|
-
|
|
52
|
-
export function meta() {
|
|
53
|
-
return [{ title: "Settings - Dispatch" }];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface DispatchSettingsPageProps {
|
|
57
|
-
/** Raw CHANGELOG.md behind What's new. */
|
|
58
|
-
changelog: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Dispatch's Settings. The template route renders it with the app's own
|
|
63
|
-
* changelog; `dispatchRoutes` consumers get the default export.
|
|
64
|
-
*/
|
|
65
|
-
export function DispatchSettingsPage({ changelog }: DispatchSettingsPageProps) {
|
|
66
|
-
const t = useT();
|
|
67
|
-
const connectAppsEnabled = useFeatureFlag(DISPATCH_CONNECT_APPS_FLAG.key);
|
|
68
|
-
// Core Preferences owns the interface language in the redesigned Settings,
|
|
69
|
-
// whose Dispatch General page shows `generalGroups` instead of `general`.
|
|
70
|
-
const redesign = useFeatureFlagState(SETTINGS_REDESIGN_FLAG.key).enabled;
|
|
71
|
-
const agentSettingsTabs = useAgentSettingsTabs({
|
|
72
|
-
usageAppId: "dispatch",
|
|
73
|
-
usageViewAllHref: "/admin/metrics",
|
|
74
|
-
organizationContent: (
|
|
75
|
-
<div className="mx-auto w-full max-w-3xl">
|
|
76
|
-
<TeamPage
|
|
77
|
-
showTitle={false}
|
|
78
|
-
appRoles={dispatchAccessDescriptor}
|
|
79
|
-
createOrgDescription="Set up a team to share dispatch destinations and approvals with your colleagues."
|
|
80
|
-
/>
|
|
81
|
-
</div>
|
|
82
|
-
),
|
|
83
|
-
});
|
|
84
|
-
const settingsTabs = [
|
|
85
|
-
...agentSettingsTabs,
|
|
86
|
-
{
|
|
87
|
-
id: "admin",
|
|
88
|
-
label: t("dispatch.nav.admin", { defaultValue: "Admin" }),
|
|
89
|
-
icon: IconShield,
|
|
90
|
-
group: "Admin",
|
|
91
|
-
href: "/admin",
|
|
92
|
-
content: null,
|
|
93
|
-
},
|
|
94
|
-
];
|
|
95
|
-
const [chatFirstModeState] = useState(() => readChatFirstModeState());
|
|
96
|
-
const [chatFirstMode, setChatFirstMode] = useState(
|
|
97
|
-
() => chatFirstModeState.enabled,
|
|
98
|
-
);
|
|
99
|
-
const [chatFirstStorageNotice, setChatFirstStorageNotice] = useState<
|
|
100
|
-
string | null
|
|
101
|
-
>(
|
|
102
|
-
chatFirstModeState.availability === "unavailable"
|
|
103
|
-
? t("settings.chatFirstStorageUnavailable")
|
|
104
|
-
: null,
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
function updateChatFirstMode(enabled: boolean) {
|
|
108
|
-
const result = writeChatFirstMode(enabled);
|
|
109
|
-
if (!result.ok) {
|
|
110
|
-
setChatFirstStorageNotice(t("settings.chatFirstStorageBlocked"));
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
setChatFirstStorageNotice(null);
|
|
114
|
-
setChatFirstMode(enabled);
|
|
115
|
-
window.dispatchEvent(
|
|
116
|
-
new CustomEvent(CHAT_FIRST_MODE_CHANGED_EVENT, {
|
|
117
|
-
detail: { enabled },
|
|
118
|
-
}),
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
|
|
123
|
-
() => [
|
|
124
|
-
...(redesign
|
|
125
|
-
? []
|
|
126
|
-
: [
|
|
127
|
-
{
|
|
128
|
-
id: "dispatch-language",
|
|
129
|
-
label: t("settings.languageTitle"),
|
|
130
|
-
keywords: "language locale translation i18n",
|
|
131
|
-
hash: "language",
|
|
132
|
-
},
|
|
133
|
-
]),
|
|
134
|
-
{
|
|
135
|
-
id: "dispatch-workspace",
|
|
136
|
-
label: redesign
|
|
137
|
-
? t("settings.resourcesTitle")
|
|
138
|
-
: t("settings.workspaceTitle"),
|
|
139
|
-
keywords: "workspace resources integrations vault destinations",
|
|
140
|
-
hash: "workspace-resources",
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
id: "dispatch-chat-first",
|
|
144
|
-
label: t("settings.chatFirstTitle"),
|
|
145
|
-
keywords: "chat first codex t3 apps pane navigation",
|
|
146
|
-
hash: "chat-first",
|
|
147
|
-
},
|
|
148
|
-
],
|
|
149
|
-
[redesign, t],
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
const chatFirstSwitch = (
|
|
153
|
-
<Switch
|
|
154
|
-
aria-label={t("settings.chatFirstAriaLabel")}
|
|
155
|
-
checked={chatFirstMode}
|
|
156
|
-
onCheckedChange={updateChatFirstMode}
|
|
157
|
-
/>
|
|
158
|
-
);
|
|
159
|
-
const chatFirstStorageAlert = chatFirstStorageNotice ? (
|
|
160
|
-
<p className="text-sm text-destructive" role="alert">
|
|
161
|
-
{chatFirstStorageNotice}
|
|
162
|
-
</p>
|
|
163
|
-
) : null;
|
|
164
|
-
const connectAppsRow = connectAppsEnabled ? (
|
|
165
|
-
<SettingsRow
|
|
166
|
-
id="connect-apps"
|
|
167
|
-
label={t("settings.connectApps")}
|
|
168
|
-
description={t("settings.connectAppsDescription")}
|
|
169
|
-
control={
|
|
170
|
-
<Button variant="outline" asChild>
|
|
171
|
-
<Link to="/connect">{t("settings.openConnectApps")}</Link>
|
|
172
|
-
</Button>
|
|
173
|
-
}
|
|
174
|
-
/>
|
|
175
|
-
) : null;
|
|
176
|
-
const resourceSettingsButton = (
|
|
177
|
-
<Button variant="outline" asChild>
|
|
178
|
-
<Link to="/workspace">{t("settings.openResourceSettings")}</Link>
|
|
179
|
-
</Button>
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
return (
|
|
183
|
-
<SettingsTabsPage
|
|
184
|
-
account={<AccountSettingsCard />}
|
|
185
|
-
extraTabs={settingsTabs}
|
|
186
|
-
generalSearchEntries={generalSearchEntries}
|
|
187
|
-
general={
|
|
188
|
-
<div className="mx-auto w-full max-w-2xl space-y-6">
|
|
189
|
-
<p className="text-sm leading-6 text-muted-foreground">
|
|
190
|
-
{t("settings.description")}
|
|
191
|
-
</p>
|
|
192
|
-
|
|
193
|
-
<SettingsGroup>
|
|
194
|
-
<SettingsRow
|
|
195
|
-
id="language"
|
|
196
|
-
label={t("settings.languageTitle")}
|
|
197
|
-
description={t("settings.languageDescription")}
|
|
198
|
-
control={
|
|
199
|
-
<div className="w-56">
|
|
200
|
-
<LanguagePicker label={t("settings.languageLabel")} />
|
|
201
|
-
</div>
|
|
202
|
-
}
|
|
203
|
-
/>
|
|
204
|
-
<SettingsRow
|
|
205
|
-
id="workspace-resources"
|
|
206
|
-
label={t("settings.workspaceTitle")}
|
|
207
|
-
description={t("settings.workspaceDescription")}
|
|
208
|
-
control={resourceSettingsButton}
|
|
209
|
-
/>
|
|
210
|
-
{connectAppsRow}
|
|
211
|
-
</SettingsGroup>
|
|
212
|
-
|
|
213
|
-
<SettingsGroup id="chat-first">
|
|
214
|
-
<SettingsRow
|
|
215
|
-
label={t("settings.chatFirstTitle")}
|
|
216
|
-
description={t("settings.chatFirstDescription")}
|
|
217
|
-
control={chatFirstSwitch}
|
|
218
|
-
>
|
|
219
|
-
<p className="text-sm leading-6 text-muted-foreground">
|
|
220
|
-
{t("settings.chatFirstSessionWatchDescription")}
|
|
221
|
-
</p>
|
|
222
|
-
{chatFirstStorageAlert}
|
|
223
|
-
</SettingsRow>
|
|
224
|
-
</SettingsGroup>
|
|
225
|
-
</div>
|
|
226
|
-
}
|
|
227
|
-
generalGroups={
|
|
228
|
-
<SettingsGroup id="workspace" title={t("settings.workspaceTitle")}>
|
|
229
|
-
<SettingsRow
|
|
230
|
-
id="chat-first"
|
|
231
|
-
label={t("settings.chatFirstTitle")}
|
|
232
|
-
description={t("settings.chatFirstDescription")}
|
|
233
|
-
control={chatFirstSwitch}
|
|
234
|
-
>
|
|
235
|
-
{chatFirstStorageAlert}
|
|
236
|
-
</SettingsRow>
|
|
237
|
-
<SettingsRow
|
|
238
|
-
id="workspace-resources"
|
|
239
|
-
label={t("settings.resourcesTitle")}
|
|
240
|
-
description={t("settings.workspaceDescription")}
|
|
241
|
-
control={resourceSettingsButton}
|
|
242
|
-
/>
|
|
243
|
-
{connectAppsRow}
|
|
244
|
-
</SettingsGroup>
|
|
245
|
-
}
|
|
246
|
-
whatsNew={
|
|
247
|
-
<div className="mx-auto w-full max-w-2xl">
|
|
248
|
-
<ChangelogSettingsCard markdown={changelog} />
|
|
249
|
-
</div>
|
|
250
|
-
}
|
|
251
|
-
whatsNewMarkdown={changelog}
|
|
252
|
-
/>
|
|
253
|
-
);
|
|
254
|
-
}
|
|
4
|
+
export { DispatchSettingsPage };
|
|
5
|
+
export type { DispatchSettingsPageProps } from "./settings-page.js";
|
|
6
|
+
export { meta } from "./settings-page.js";
|
|
255
7
|
|
|
256
8
|
export default function SettingsRoute() {
|
|
257
9
|
return <DispatchSettingsPage changelog={packageChangelog} />;
|