This commit is contained in:
2025-11-12 17:02:27 +01:00
parent d2e27c12a2
commit b812d748ea
44 changed files with 221 additions and 356 deletions
+22 -28
View File
@@ -37,26 +37,24 @@ const LoginRoute = () => {
let combined = extract(location.search);
if (typeof window !== 'undefined') {
const hash = window.location.hash || '';
const queryIndex = hash.indexOf('?');
if (queryIndex !== -1) {
const hashQuery = hash.slice(queryIndex + 1);
const hashParams = extract(`?${hashQuery}`);
combined = {
token: combined.token || hashParams.token,
username: combined.username || hashParams.username,
preferredTenantId: combined.preferredTenantId || hashParams.preferredTenantId,
};
}
if (!combined.token) {
const searchParams = extract(window.location.search);
combined = {
token: combined.token || searchParams.token,
username: combined.username || searchParams.username,
preferredTenantId: combined.preferredTenantId || searchParams.preferredTenantId,
};
}
const hash = window.location.hash || '';
const queryIndex = hash.indexOf('?');
if (queryIndex !== -1) {
const hashQuery = hash.slice(queryIndex + 1);
const hashParams = extract(`?${hashQuery}`);
combined = {
token: combined.token || hashParams.token,
username: combined.username || hashParams.username,
preferredTenantId: combined.preferredTenantId || hashParams.preferredTenantId,
};
}
if (!combined.token) {
const searchParams = extract(window.location.search);
combined = {
token: combined.token || searchParams.token,
username: combined.username || searchParams.username,
preferredTenantId: combined.preferredTenantId || searchParams.preferredTenantId,
};
}
return combined;
@@ -96,10 +94,6 @@ const LoginRoute = () => {
);
const clearMagicParamsFromUrl = useCallback(() => {
if (typeof window === 'undefined') {
return;
}
const removableKeys = ['magic_token', 'username', 'preferred_tenant_id'];
const currentSearch = new URLSearchParams(window.location.search);
let searchChanged = false;
@@ -184,7 +178,7 @@ const LoginRoute = () => {
const handlePasskeyLogin = useCallback(
async (rawUsername) => {
const username = typeof rawUsername === 'string' ? rawUsername.trim() : '';
const username = rawUsername?.trim?.() || '';
if (!username) {
setStatusMessage('Enter your username before using a passkey.', 'error');
return;
@@ -381,7 +375,7 @@ const LoginRoute = () => {
const handleSignup = useCallback(
async (rawUsername) => {
const username = typeof rawUsername === 'string' ? rawUsername.trim() : '';
const username = rawUsername?.trim?.() || '';
if (!username) {
setStatusMessage('Choose a username to create your account.', 'error');
return;
@@ -459,8 +453,8 @@ const LoginRoute = () => {
);
const redirectTarget = useMemo(() => {
const target = location.state?.from;
if (typeof target === 'string' && target.startsWith('/')) {
const target = String(location.state?.from ?? '');
if (target.startsWith('/')) {
return target;
}
return '/documents';
+14 -4
View File
@@ -12,8 +12,16 @@ import { useSidebarContext } from '../sidebar/SidebarContext';
const PanelManagerContext = createContext(null);
const PANEL_LIMITS = {
sidebar: { minRatio: 1 / 6, maxRatio: 1 / 4 },
detail: { minRatio: 1 / 4, maxRatio: 3 / 4 },
sidebar: {
minRatio: 1 / 6,
maxRatio: 1 / 4,
minPx: 240,
},
detail: {
minRatio: 1 / 4,
maxRatio: 3 / 4,
minPx: 320,
},
};
const STORAGE_KEYS = {
@@ -30,8 +38,10 @@ const clampPanelWidth = (panel, value) => {
return numeric;
}
const viewport = window.innerWidth;
const minLimit = Math.max(0, Math.round(viewport * limits.minRatio));
const rawMax = Math.max(minLimit, Math.round(viewport * limits.maxRatio));
const ratioMin = Math.round(viewport * limits.minRatio);
const ratioMax = Math.round(viewport * limits.maxRatio);
const minLimit = Math.max(0, Math.max(ratioMin, limits.minPx));
const rawMax = Math.max(minLimit, ratioMax);
const maxAllowed = Math.min(rawMax, viewport - 160);
const targetMax = Math.max(minLimit, maxAllowed);
return Math.min(Math.max(numeric, minLimit), targetMax);
+4 -2
View File
@@ -16,10 +16,12 @@ export const resolveApiPath = (path = '') => path;
const makeRowKey = (type, id) =>
id ? `${type}${ROW_KEY_SEPARATOR}${id}` : `${type}${ROW_KEY_SEPARATOR}`;
const getRowType = (key) => (typeof key === 'string' ? key.split(ROW_KEY_SEPARATOR, 1)[0] : '');
const getRowType = (key) => (
typeof key?.split === 'function' ? key.split(ROW_KEY_SEPARATOR, 1)[0] : ''
);
export const getRowId = (key) => {
if (typeof key !== 'string') return '';
if (typeof key?.indexOf !== 'function' || typeof key?.slice !== 'function') return '';
const separatorIndex = key.indexOf(ROW_KEY_SEPARATOR);
if (separatorIndex === -1) return key;
return key.slice(separatorIndex + 1);
+1 -1
View File
@@ -1,7 +1,7 @@
import React, { useContext, useEffect, useMemo, useReducer } from 'react';
import api from '../lib/api';
const storage = typeof window !== 'undefined' ? window.sessionStorage : undefined;
const storage = window.sessionStorage;
const STORED_TOKEN = storage?.getItem('papercrate_token') ?? '';
let STORED_TENANT = null;
@@ -11,9 +11,6 @@ const SORT_DIRECTION_STORAGE_KEY = 'papercrate_sort_direction';
const INCLUDE_DESCENDANTS_STORAGE_KEY = 'papercrate_include_descendants';
const readSessionStorage = (key) => {
if (typeof window === 'undefined') {
return null;
}
try {
return window.sessionStorage.getItem(key);
} catch (error) {
@@ -23,9 +20,6 @@ const readSessionStorage = (key) => {
};
const writeSessionStorage = (key, value) => {
if (typeof window === 'undefined') {
return;
}
try {
window.sessionStorage.setItem(key, value);
} catch (error) {
+1 -1
View File
@@ -59,7 +59,7 @@ export const useWorkspaceSelection = ({
const selectEntry = useCallback(
(entry, event) => {
const rowKey = typeof entry === 'string' ? entry : entry?.rowKey;
const rowKey = entry?.rowKey ?? (typeof entry?.split === 'function' ? entry : null);
if (!rowKey) return;
handleEntrySelection(rowKey, event);
},