diff --git a/apps/client/package.json b/apps/client/package.json index 6b8a8b60d..f85c008e1 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -1,7 +1,7 @@ { "name": "client", "private": true, - "version": "0.80.0", + "version": "0.80.1", "scripts": { "dev": "vite", "build": "tsc && vite build", @@ -25,14 +25,14 @@ "@tabler/icons-react": "^3.40.0", "@tanstack/react-query": "5.90.17", "alfaaz": "^1.1.0", - "axios": "1.15.0", + "axios": "1.16.0", "blueimp-load-image": "^5.16.0", "clsx": "^2.1.1", "emoji-mart": "^5.6.0", "file-saver": "^2.0.5", "highlightjs-sap-abap": "^0.3.0", - "i18next": "^25.10.1", - "i18next-http-backend": "^3.0.2", + "i18next": "25.10.1", + "i18next-http-backend": "3.0.6", "jotai": "^2.18.1", "jotai-optics": "^0.4.0", "js-cookie": "^3.0.5", @@ -42,7 +42,7 @@ "mantine-form-zod-resolver": "^1.3.0", "mermaid": "^11.13.0", "mitt": "^3.0.1", - "posthog-js": "1.363.1", + "posthog-js": "1.372.2", "react": "^18.3.1", "react-arborist": "3.4.0", "react-clear-modal": "^2.0.18", @@ -50,11 +50,10 @@ "react-drawio": "^1.0.7", "react-error-boundary": "^6.1.1", "react-helmet-async": "^3.0.0", - "react-i18next": "^16.5.8", + "react-i18next": "16.5.8", "react-router-dom": "^7.13.1", "semver": "^7.7.4", "socket.io-client": "^4.8.3", - "tiptap-extension-global-drag-handle": "^0.1.18", "zod": "^4.3.6" }, "devDependencies": { @@ -74,7 +73,7 @@ "eslint-plugin-react-refresh": "^0.5.2", "globals": "^15.13.0", "optics-ts": "^2.4.1", - "postcss": "^8.5.8", + "postcss": "^8.5.12", "postcss-preset-mantine": "^1.18.0", "postcss-simple-vars": "^7.0.1", "prettier": "^3.8.1", diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index f831289bc..0d686cc2a 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -971,4 +971,17 @@ "Strikethrough": "Strikethrough", "Undo": "Undo", "Redo": "Redo" + "Backlinks": "Backlinks", + "Last updated by": "Last updated by", + "Last updated": "Last updated", + "Stats": "Stats", + "Word count": "Word count", + "Characters": "Characters", + "Incoming links": "Incoming links", + "Outgoing links": "Outgoing links", + "Incoming links ({{count}})": "Incoming links ({{count}})", + "Outgoing links ({{count}})": "Outgoing links ({{count}})", + "No pages link here yet.": "No pages link here yet.", + "This page doesn't link to other pages yet.": "This page doesn't link to other pages yet.", + "Verified until {{date}}": "Verified until {{date}}" } diff --git a/apps/client/src/components/common/avatar-uploader.tsx b/apps/client/src/components/common/avatar-uploader.tsx index 8d9552f64..750e4ba68 100644 --- a/apps/client/src/components/common/avatar-uploader.tsx +++ b/apps/client/src/components/common/avatar-uploader.tsx @@ -80,6 +80,12 @@ export default function AvatarUploader({ } }; + const ariaLabel = { + [AvatarIconType.AVATAR]: t("Change avatar"), + [AvatarIconType.SPACE_ICON]: t("Change space icon"), + [AvatarIconType.WORKSPACE_ICON]: t("Change workspace icon"), + }[type]; + const handleRemove = async () => { if (disabled) return; @@ -104,6 +110,8 @@ export default function AvatarUploader({ ref={fileInputRef} onChange={handleFileInputChange} accept="image/png,image/jpeg,image/jpg" + aria-label={ariaLabel} + tabIndex={-1} style={{ display: "none" }} /> @@ -115,6 +123,8 @@ export default function AvatarUploader({ size={size} avatarUrl={currentImageUrl} name={fallbackName} + aria-label={ariaLabel} + aria-haspopup="menu" style={{ cursor: disabled || isLoading ? "default" : "pointer", opacity: isLoading ? 0.6 : 1, diff --git a/apps/client/src/components/common/copy.tsx b/apps/client/src/components/common/copy.tsx index 745fc4ba6..2144417b9 100644 --- a/apps/client/src/components/common/copy.tsx +++ b/apps/client/src/components/common/copy.tsx @@ -25,6 +25,7 @@ export default function CopyTextButton({ text, size }: CopyProps) { variant="subtle" onClick={copy} size={size} + aria-label={copied ? t("Copied") : t("Copy")} > {copied ? : } diff --git a/apps/client/src/components/common/recent-changes.tsx b/apps/client/src/components/common/recent-changes.tsx index 277ceb811..8e0e56f29 100644 --- a/apps/client/src/components/common/recent-changes.tsx +++ b/apps/client/src/components/common/recent-changes.tsx @@ -4,7 +4,7 @@ import { UnstyledButton, Badge, Table, - ActionIcon, + ThemeIcon, Button, } from "@mantine/core"; import { Link } from "react-router-dom"; @@ -49,9 +49,9 @@ export default function RecentChanges({ spaceId }: Props) { > {page.icon || ( - + - + )} diff --git a/apps/client/src/components/common/search-input.tsx b/apps/client/src/components/common/search-input.tsx index 08cbbee06..27e50fd4e 100644 --- a/apps/client/src/components/common/search-input.tsx +++ b/apps/client/src/components/common/search-input.tsx @@ -6,12 +6,14 @@ import { useTranslation } from "react-i18next"; export interface SearchInputProps { placeholder?: string; + ariaLabel?: string; debounceDelay?: number; onSearch: (value: string) => void; } export function SearchInput({ placeholder, + ariaLabel, debounceDelay = 500, onSearch, }: SearchInputProps) { @@ -28,6 +30,7 @@ export function SearchInput({ } value={value} onChange={(e) => setValue(e.currentTarget.value)} diff --git a/apps/client/src/components/icons/icon-people-circle.tsx b/apps/client/src/components/icons/icon-people-circle.tsx index 996958965..1a2daf73d 100644 --- a/apps/client/src/components/icons/icon-people-circle.tsx +++ b/apps/client/src/components/icons/icon-people-circle.tsx @@ -1,11 +1,11 @@ -import { ActionIcon, rem } from "@mantine/core"; +import { ThemeIcon } from "@mantine/core"; import React from "react"; import { IconUsersGroup } from "@tabler/icons-react"; export function IconGroupCircle() { return ( - + - + ); } diff --git a/apps/client/src/components/layouts/global/app-shell.module.css b/apps/client/src/components/layouts/global/app-shell.module.css index ed369612c..dd3b72e45 100644 --- a/apps/client/src/components/layouts/global/app-shell.module.css +++ b/apps/client/src/components/layouts/global/app-shell.module.css @@ -27,5 +27,3 @@ background: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-5)) } } - - diff --git a/apps/client/src/components/layouts/global/aside.tsx b/apps/client/src/components/layouts/global/aside.tsx index 4f2cf5927..73e6a381d 100644 --- a/apps/client/src/components/layouts/global/aside.tsx +++ b/apps/client/src/components/layouts/global/aside.tsx @@ -8,6 +8,7 @@ import { TableOfContents } from "@/features/editor/components/table-of-contents/ import { useAtomValue } from "jotai"; import { pageEditorAtom } from "@/features/editor/atoms/editor-atoms.ts"; import AsideChatPanel from "@/ee/ai-chat/components/aside-chat-panel"; +import { PageDetailsAside } from "@/features/page-details/components/page-details-aside.tsx"; export default function Aside() { const [{ tab }] = useAtom(asideStateAtom); @@ -30,6 +31,10 @@ export default function Aside() { component = ; title = "AI Chat"; break; + case "details": + component = ; + title = "Details"; + break; default: component = null; title = null; diff --git a/apps/client/src/components/layouts/global/global-app-shell.tsx b/apps/client/src/components/layouts/global/global-app-shell.tsx index 64bd3dde7..4c56fe076 100644 --- a/apps/client/src/components/layouts/global/global-app-shell.tsx +++ b/apps/client/src/components/layouts/global/global-app-shell.tsx @@ -1,6 +1,7 @@ import { AppShell, Container } from "@mantine/core"; import React, { useEffect, useRef, useState } from "react"; import { useLocation } from "react-router-dom"; +import { useTranslation } from "react-i18next"; import SettingsSidebar from "@/components/settings/settings-sidebar.tsx"; import { useAtom } from "jotai"; import { @@ -23,11 +24,12 @@ export default function GlobalAppShell({ }: { children: React.ReactNode; }) { + const { t } = useTranslation(); useTrialEndAction(); const [mobileOpened] = useAtom(mobileSidebarAtom); const toggleMobile = useToggleSidebar(mobileSidebarAtom); const [desktopOpened] = useAtom(desktopSidebarAtom); - const [{ isAsideOpen }] = useAtom(asideStateAtom); + const [{ isAsideOpen, tab: asideTab }] = useAtom(asideStateAtom); const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom); const [isResizing, setIsResizing] = useState(false); const sidebarRef = useRef(null); @@ -105,6 +107,15 @@ export default function GlobalAppShell({ className={classes.navbar} withBorder={false} ref={sidebarRef} + aria-label={ + isSpaceRoute + ? t("Space navigation") + : isSettingsRoute + ? t("Settings navigation") + : isAiRoute + ? t("AI navigation") + : t("Main navigation") + } > {isSpaceRoute && (
@@ -114,16 +125,33 @@ export default function GlobalAppShell({ {isAiRoute && } {showGlobalSidebar && } - + {isSettingsRoute ? ( - {children} + + {children} + ) : ( children )} {isPageRoute && ( - +