Skip to content

Commit a0c3d55

Browse files
committed
Merge upstream/main and resolve MFA conflicts
2 parents 1463c4a + 6683c51 commit a0c3d55

117 files changed

Lines changed: 2929 additions & 999 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "client",
33
"private": true,
4-
"version": "0.70.1",
4+
"version": "0.70.3",
55
"scripts": {
66
"dev": "vite",
77
"build": "tsc && vite build",

apps/client/public/locales/en-US/translation.json

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,11 @@
289289
"Save & Exit": "Save & Exit",
290290
"Double-click to edit Excalidraw diagram": "Double-click to edit Excalidraw diagram",
291291
"Paste link": "Paste link",
292+
"Paste link or search pages": "Paste link or search pages",
293+
"Link to web page": "Link to web page",
294+
"Recents": "Recents",
295+
"Page or URL": "Page or URL",
296+
"Link title": "Link title",
292297
"Edit link": "Edit link",
293298
"Remove link": "Remove link",
294299
"Add link": "Add link",
@@ -439,7 +444,6 @@
439444
"Toggle space public sharing": "Toggle space public sharing",
440445
"Public sharing is disabled at the workspace level": "Public sharing is disabled at the workspace level",
441446
"Prevent pages in this space from being shared publicly.": "Prevent pages in this space from being shared publicly.",
442-
"Requires an enterprise license": "Requires an enterprise license",
443447
"Page permissions": "Page permissions",
444448
"Control who can view and edit individual pages. Available with an enterprise license.": "Control who can view and edit individual pages. Available with an enterprise license.",
445449
"Enable public sharing": "Enable public sharing",
@@ -621,25 +625,25 @@
621625
"Generative AI (Ask AI)": "Generative AI (Ask AI)",
622626
"Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.": "Enable AI-powered content generation in the editor. Allows users to generate, improve, translate and transform text.",
623627
"Toggle generative AI": "Toggle generative AI",
624-
"Enterprise feature": "Enterprise feature",
628+
"Upgrade your plan": "Upgrade your plan",
629+
"Available with a paid license": "Available with a paid license",
630+
"Upgrade your license tier.": "Upgrade your license tier.",
625631
"AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.",
626632
"AI & MCP": "AI & MCP",
627633
"AI": "AI",
628634
"MCP": "MCP",
629635
"Model Context Protocol (MCP)": "Model Context Protocol (MCP)",
630636
"Enable the MCP server to allow AI assistants and tools to interact with your workspace content.": "Enable the MCP server to allow AI assistants and tools to interact with your workspace content.",
631637
"MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "MCP is only available in the Docmost enterprise edition. Contact sales@docmost.com.",
632-
"MCP documentation": "MCP documentation",
633638
"MCP Server URL": "MCP Server URL",
634639
"Use your API key for authentication. You can manage API keys in your account settings.": "Use your API key for authentication. You can manage API keys in your account settings.",
635640
"Supported tools": "Supported tools",
636641
"Your workspace has MCP enabled. Use your API key to connect AI assistants.": "Your workspace has MCP enabled. Use your API key to connect AI assistants.",
637642
"MCP server URL:": "MCP server URL:",
638643
"Learn more": "Learn more",
639-
"View the": "View the",
640-
"for usage details.": "for usage details.",
641-
"for setup instructions.": "for setup instructions.",
642-
"API documentation": "API documentation",
644+
"Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.": "Manage API keys for all users in the workspace. View the <anchor>API documentation</anchor> for usage details.",
645+
"View the <anchor>API documentation</anchor> for usage details.": "View the <anchor>API documentation</anchor> for usage details.",
646+
"View the <anchor>MCP documentation</anchor>.": "View the <anchor>MCP documentation</anchor>.",
643647
"Sources": "Sources",
644648
"AI Answers not available for attachments": "AI Answers not available for attachments",
645649
"No answer available": "No answer available",
@@ -654,12 +658,12 @@
654658
"Mark all as read": "Mark all as read",
655659
"Mark as read": "Mark as read",
656660
"More options": "More options",
657-
"mentioned you in a comment": "mentioned you in a comment",
658-
"commented on a page": "commented on a page",
659-
"resolved a comment": "resolved a comment",
660-
"mentioned you on a page": "mentioned you on a page",
661-
"gave you edit access to a page": "gave you edit access to a page",
662-
"gave you view access to a page": "gave you view access to a page",
661+
"<bold>{{name}}</bold> mentioned you in a comment": "<bold>{{name}}</bold> mentioned you in a comment",
662+
"<bold>{{name}}</bold> commented on a page": "<bold>{{name}}</bold> commented on a page",
663+
"<bold>{{name}}</bold> resolved a comment": "<bold>{{name}}</bold> resolved a comment",
664+
"<bold>{{name}}</bold> mentioned you on a page": "<bold>{{name}}</bold> mentioned you on a page",
665+
"<bold>{{name}}</bold> gave you edit access to a page": "<bold>{{name}}</bold> gave you edit access to a page",
666+
"<bold>{{name}}</bold> gave you view access to a page": "<bold>{{name}}</bold> gave you view access to a page",
663667
"Today": "Today",
664668
"Yesterday": "Yesterday",
665669
"This week": "This week",
@@ -693,5 +697,16 @@
693697
"Failed to update trash retention": "Failed to update trash retention",
694698
"Removed page restriction": "Removed page restriction",
695699
"Added page permission": "Added page permission",
696-
"Removed page permission": "Removed page permission"
700+
"Removed page permission": "Removed page permission",
701+
"Verifying your email": "Verifying your email",
702+
"Please wait...": "Please wait...",
703+
"Verification failed. The link may have expired.": "Verification failed. The link may have expired.",
704+
"Check your email": "Check your email",
705+
"We sent a verification link to {{email}}.": "We sent a verification link to {{email}}.",
706+
"We sent a verification link to your email.": "We sent a verification link to your email.",
707+
"Click the link to verify your email and access your workspace.": "Click the link to verify your email and access your workspace.",
708+
"Resend verification email": "Resend verification email",
709+
"Verification email sent. Please check your inbox.": "Verification email sent. Please check your inbox.",
710+
"Failed to resend verification email. Please try again.": "Failed to resend verification email. Please try again.",
711+
"We've sent you an email with your associated workspaces.": "We've sent you an email with your associated workspaces."
697712
}

apps/client/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import UserApiKeys from "@/ee/api-key/pages/user-api-keys";
3838
import WorkspaceApiKeys from "@/ee/api-key/pages/workspace-api-keys";
3939
import AiSettings from "@/ee/ai/pages/ai-settings.tsx";
4040
import AuditLogs from "@/ee/audit/pages/audit-logs.tsx";
41+
import VerifyEmail from "@/ee/pages/verify-email.tsx";
4142

4243
export default function App() {
4344
const { t } = useTranslation();
@@ -63,6 +64,7 @@ export default function App() {
6364
<>
6465
<Route path={"/create"} element={<CreateWorkspace />} />
6566
<Route path={"/select"} element={<CloudLogin />} />
67+
<Route path={"/verify-email"} element={<VerifyEmail />} />
6668
</>
6769
)}
6870

apps/client/src/components/settings/settings-sidebar.tsx

Lines changed: 35 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import { useTranslation } from "react-i18next";
2121
import { isCloud } from "@/lib/config.ts";
2222
import useUserRole from "@/hooks/use-user-role.tsx";
2323
import { useAtom } from "jotai";
24-
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
24+
import { entitlementAtom } from "@/ee/entitlement/entitlement-atom";
25+
import { Feature } from "@/ee/features";
26+
import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label";
2527
import {
2628
prefetchApiKeyManagement,
2729
prefetchApiKeys,
@@ -39,22 +41,19 @@ import { mobileSidebarAtom } from "@/components/layouts/global/hooks/atoms/sideb
3941
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
4042
import { useSettingsNavigation } from "@/hooks/use-settings-navigation";
4143

42-
interface DataItem {
44+
type DataItem = {
4345
label: string;
4446
icon: React.ElementType;
4547
path: string;
46-
isCloud?: boolean;
47-
isEnterprise?: boolean;
48-
isAdmin?: boolean;
49-
isOwner?: boolean;
50-
isSelfhosted?: boolean;
51-
showDisabledInNonEE?: boolean;
52-
}
48+
feature?: string;
49+
role?: "admin" | "owner";
50+
env?: "cloud" | "selfhosted";
51+
};
5352

54-
interface DataGroup {
53+
type DataGroup = {
5554
heading: string;
5655
items: DataItem[];
57-
}
56+
};
5857

5958
const groupedData: DataGroup[] = [
6059
{
@@ -70,36 +69,28 @@ const groupedData: DataGroup[] = [
7069
label: "API keys",
7170
icon: IconKey,
7271
path: "/settings/account/api-keys",
73-
isCloud: true,
74-
isEnterprise: true,
75-
showDisabledInNonEE: true,
72+
feature: Feature.API_KEYS,
7673
},
7774
],
7875
},
7976
{
8077
heading: "Workspace",
8178
items: [
8279
{ label: "General", icon: IconSettings, path: "/settings/workspace" },
83-
{
84-
label: "Members",
85-
icon: IconUsers,
86-
path: "/settings/members",
87-
},
80+
{ label: "Members", icon: IconUsers, path: "/settings/members" },
8881
{
8982
label: "Billing",
9083
icon: IconCoin,
9184
path: "/settings/billing",
92-
isCloud: true,
93-
isAdmin: true,
85+
role: "admin",
86+
env: "cloud",
9487
},
9588
{
9689
label: "Security & SSO",
9790
icon: IconLock,
9891
path: "/settings/security",
99-
isCloud: true,
100-
isEnterprise: true,
101-
isAdmin: true,
102-
showDisabledInNonEE: true,
92+
feature: Feature.SECURITY_SETTINGS,
93+
role: "admin",
10394
},
10495
{ label: "Groups", icon: IconUsersGroup, path: "/settings/groups" },
10596
{ label: "Spaces", icon: IconSpaces, path: "/settings/spaces" },
@@ -108,25 +99,22 @@ const groupedData: DataGroup[] = [
10899
label: "API management",
109100
icon: IconKey,
110101
path: "/settings/api-keys",
111-
isCloud: true,
112-
isEnterprise: true,
113-
isAdmin: true,
114-
showDisabledInNonEE: true,
102+
feature: Feature.API_KEYS,
103+
role: "admin",
115104
},
116105
{
117106
label: "AI settings",
118107
icon: IconSparkles,
119108
path: "/settings/ai",
120-
isAdmin: true,
109+
role: "admin",
121110
},
122111
{
123112
label: "Audit log",
124113
icon: IconHistory,
125114
path: "/settings/audit",
126-
isEnterprise: true,
127-
isOwner: true,
128-
isSelfhosted: true,
129-
showDisabledInNonEE: true,
115+
feature: Feature.AUDIT_LOGS,
116+
role: "owner",
117+
env: "selfhosted",
130118
},
131119
],
132120
},
@@ -148,51 +136,29 @@ export default function SettingsSidebar() {
148136
const [active, setActive] = useState(location.pathname);
149137
const { goBack } = useSettingsNavigation();
150138
const { isAdmin, isOwner } = useUserRole();
151-
const [workspace] = useAtom(workspaceAtom);
139+
const [entitlements] = useAtom(entitlementAtom);
140+
const upgradeLabel = useUpgradeLabel();
152141
const [mobileSidebarOpened] = useAtom(mobileSidebarAtom);
153142
const toggleMobileSidebar = useToggleSidebar(mobileSidebarAtom);
154143

155144
useEffect(() => {
156145
setActive(location.pathname);
157146
}, [location.pathname]);
158147

159-
const hasRoleAccess = (item: DataItem) => {
160-
if (item.isOwner) return isOwner;
161-
if (item.isAdmin) return isAdmin;
162-
return true;
163-
};
148+
const hasFeature = (f: string) =>
149+
entitlements?.features?.includes(f) ?? false;
164150

165151
const canShowItem = (item: DataItem) => {
166-
if (item.showDisabledInNonEE && item.isEnterprise) {
167-
if (item.isSelfhosted && isCloud()) return false;
168-
return hasRoleAccess(item);
169-
}
170-
171-
if (item.isCloud && item.isEnterprise) {
172-
if (!(isCloud() || workspace?.hasLicenseKey)) return false;
173-
return hasRoleAccess(item);
174-
}
175-
176-
if (item.isCloud) {
177-
return isCloud() ? hasRoleAccess(item) : false;
178-
}
179-
180-
if (item.isSelfhosted) {
181-
return !isCloud() ? hasRoleAccess(item) : false;
182-
}
183-
184-
if (item.isEnterprise) {
185-
return workspace?.hasLicenseKey ? hasRoleAccess(item) : false;
186-
}
187-
188-
return hasRoleAccess(item);
152+
if (item.env === "cloud" && !isCloud()) return false;
153+
if (item.env === "selfhosted" && isCloud()) return false;
154+
if (item.role === "admin" && !isAdmin) return false;
155+
if (item.role === "owner" && !isOwner) return false;
156+
return true;
189157
};
190158

191159
const isItemDisabled = (item: DataItem) => {
192-
if (item.showDisabledInNonEE && item.isEnterprise) {
193-
return !(isCloud() || workspace?.hasLicenseKey);
194-
}
195-
return false;
160+
if (!item.feature) return false;
161+
return !hasFeature(item.feature);
196162
};
197163

198164
const menuItems = groupedData.map((group) => {
@@ -225,7 +191,7 @@ export default function SettingsSidebar() {
225191
prefetchHandler = prefetchBilling;
226192
break;
227193
case "License & Edition":
228-
if (workspace?.hasLicenseKey) {
194+
if (entitlements?.tier !== "free") {
229195
prefetchHandler = prefetchLicense;
230196
}
231197
break;
@@ -280,7 +246,7 @@ export default function SettingsSidebar() {
280246
return (
281247
<Tooltip
282248
key={item.label}
283-
label={t("Available in enterprise edition")}
249+
label={upgradeLabel}
284250
position="right"
285251
withArrow
286252
>

apps/client/src/components/ui/auto-tooltip-text.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function AutoTooltipText({
3434
disabled={!isTruncated || !label}
3535
multiline
3636
withArrow
37+
withinPortal={false}
3738
{...tooltipProps}
3839
>
3940
<Text

apps/client/src/ee/ai/components/enable-ai-search.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { Group, Text, Switch, MantineSize, Title } from "@mantine/core";
1+
import { Group, Text, Switch, MantineSize, Tooltip } from "@mantine/core";
22
import { useAtom } from "jotai";
33
import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts";
44
import React, { useState } from "react";
55
import { useTranslation } from "react-i18next";
66
import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts";
77
import { notifications } from "@mantine/notifications";
8-
import { isCloud } from "@/lib/config.ts";
9-
import useLicense from "@/ee/hooks/use-license.tsx";
8+
import { useHasFeature } from "@/ee/hooks/use-feature";
9+
import { Feature } from "@/ee/features";
10+
import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label";
1011

1112
export default function EnableAiSearch() {
1213
const { t } = useTranslation();
@@ -37,9 +38,8 @@ export function AiSearchToggle({ size, label }: AiSearchToggleProps) {
3738
const { t } = useTranslation();
3839
const [workspace, setWorkspace] = useAtom(workspaceAtom);
3940
const [checked, setChecked] = useState(workspace?.settings?.ai?.search);
40-
const { hasLicenseKey } = useLicense();
41-
42-
const hasAccess = isCloud() || (!isCloud() && hasLicenseKey);
41+
const hasAccess = useHasFeature(Feature.AI);
42+
const upgradeLabel = useUpgradeLabel();
4343

4444
const handleChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
4545
const value = event.currentTarget.checked;
@@ -56,14 +56,16 @@ export function AiSearchToggle({ size, label }: AiSearchToggleProps) {
5656
};
5757

5858
return (
59-
<Switch
60-
size={size}
61-
label={label}
62-
labelPosition="left"
63-
defaultChecked={checked}
64-
onChange={handleChange}
65-
disabled={!hasAccess}
66-
aria-label={t("Toggle AI search")}
67-
/>
59+
<Tooltip label={upgradeLabel} disabled={hasAccess} refProp="rootRef">
60+
<Switch
61+
size={size}
62+
label={label}
63+
labelPosition="left"
64+
defaultChecked={checked}
65+
onChange={handleChange}
66+
disabled={!hasAccess}
67+
aria-label={t("Toggle AI search")}
68+
/>
69+
</Tooltip>
6870
);
6971
}

0 commit comments

Comments
 (0)