Make logging in work on frontend

This commit is contained in:
2024-11-04 21:51:38 +01:00
parent 9cdbf9fec8
commit 69afef15ec
16 changed files with 165 additions and 98 deletions

View File

@@ -28,6 +28,7 @@
"rehype-mathjax": "^6.0.0",
"rehype-prism": "^2.3.3",
"rehype-react": "^8.0.0",
"remark": "^15.0.1",
"remark-math": "^6.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.1",
@@ -4975,6 +4976,22 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark": {
"version": "15.0.1",
"resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz",
"integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"remark-parse": "^11.0.0",
"remark-stringify": "^11.0.0",
"unified": "^11.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark-math": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz",
@@ -5024,6 +5041,21 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/remark-stringify": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
"integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"mdast-util-to-markdown": "^2.0.0",
"unified": "^11.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",

View File

@@ -42,6 +42,7 @@
"rehype-mathjax": "^6.0.0",
"rehype-prism": "^2.3.3",
"rehype-react": "^8.0.0",
"remark": "^15.0.1",
"remark-math": "^6.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.1",

View File

@@ -21,15 +21,10 @@ const MarkdownPreview = ({ content, handleFileSelect }) => {
if (href.startsWith(`${baseUrl}/internal/`)) {
// For existing files, extract the path and directly select it
const [filePath, heading] = decodeURIComponent(
const [filePath] = decodeURIComponent(
href.replace(`${baseUrl}/internal/`, '')
).split('#');
handleFileSelect(filePath);
// TODO: Handle heading navigation if needed
if (heading) {
console.debug('Heading navigation not implemented:', heading);
}
} else if (href.startsWith(`${baseUrl}/notfound/`)) {
// For non-existent files, show a notification
const fileName = decodeURIComponent(
@@ -47,7 +42,7 @@ const MarkdownPreview = ({ content, handleFileSelect }) => {
() =>
unified()
.use(remarkParse)
.use(remarkWikiLinks, currentWorkspace?.id)
.use(remarkWikiLinks, currentWorkspace?.name)
.use(remarkMath)
.use(remarkRehype)
.use(rehypeMathjax)
@@ -90,7 +85,7 @@ const MarkdownPreview = ({ content, handleFileSelect }) => {
},
},
}),
[baseUrl, handleFileSelect, currentWorkspace?.id]
[baseUrl, handleFileSelect, currentWorkspace?.name]
);
useEffect(() => {

View File

@@ -47,7 +47,7 @@ const WorkspaceSwitcher = () => {
const handleWorkspaceCreated = async (newWorkspace) => {
await loadWorkspaces();
switchWorkspace(newWorkspace.id);
switchWorkspace(newWorkspace.name);
};
return (
@@ -102,10 +102,10 @@ const WorkspaceSwitcher = () => {
</Center>
) : (
workspaces.map((workspace) => {
const isSelected = workspace.id === currentWorkspace?.id;
const isSelected = workspace.name === currentWorkspace?.name;
return (
<Paper
key={workspace.id}
key={workspace.name}
p="xs"
withBorder
style={{
@@ -125,7 +125,7 @@ const WorkspaceSwitcher = () => {
<UnstyledButton
style={{ flex: 1 }}
onClick={() => {
switchWorkspace(workspace.id);
switchWorkspace(workspace.name);
setPopoverOpened(false);
}}
>

View File

@@ -8,10 +8,10 @@ import React, {
import { useMantineColorScheme } from '@mantine/core';
import { notifications } from '@mantine/notifications';
import {
fetchLastWorkspaceId,
fetchLastWorkspaceName,
getWorkspace,
updateWorkspace,
updateLastWorkspace,
updateLastWorkspaceName,
deleteWorkspace,
listWorkspaces,
} from '../services/api';
@@ -41,9 +41,9 @@ export const WorkspaceProvider = ({ children }) => {
}
}, []);
const loadWorkspaceData = useCallback(async (workspaceId) => {
const loadWorkspaceData = useCallback(async (workspaceName) => {
try {
const workspace = await getWorkspace(workspaceId);
const workspace = await getWorkspace(workspaceName);
setCurrentWorkspace(workspace);
setColorScheme(workspace.theme);
} catch (error) {
@@ -61,8 +61,8 @@ export const WorkspaceProvider = ({ children }) => {
const allWorkspaces = await listWorkspaces();
if (allWorkspaces.length > 0) {
const firstWorkspace = allWorkspaces[0];
await updateLastWorkspace(firstWorkspace.id);
await loadWorkspaceData(firstWorkspace.id);
await updateLastWorkspaceName(firstWorkspace.name);
await loadWorkspaceData(firstWorkspace.name);
}
} catch (error) {
console.error('Failed to load first available workspace:', error);
@@ -77,9 +77,9 @@ export const WorkspaceProvider = ({ children }) => {
useEffect(() => {
const initializeWorkspace = async () => {
try {
const { lastWorkspaceId } = await fetchLastWorkspaceId();
if (lastWorkspaceId) {
await loadWorkspaceData(lastWorkspaceId);
const { lastWorkspaceName } = await fetchLastWorkspaceName();
if (lastWorkspaceName) {
await loadWorkspaceData(lastWorkspaceName);
} else {
await loadFirstAvailableWorkspace();
}
@@ -95,11 +95,11 @@ export const WorkspaceProvider = ({ children }) => {
initializeWorkspace();
}, []);
const switchWorkspace = useCallback(async (workspaceId) => {
const switchWorkspace = useCallback(async (workspaceName) => {
try {
setLoading(true);
await updateLastWorkspace(workspaceId);
await loadWorkspaceData(workspaceId);
await updateLastWorkspaceName(workspaceName);
await loadWorkspaceData(workspaceName);
await loadWorkspaces();
} catch (error) {
console.error('Failed to switch workspace:', error);
@@ -129,10 +129,10 @@ export const WorkspaceProvider = ({ children }) => {
}
// Delete workspace and get the next workspace ID
const response = await deleteWorkspace(currentWorkspace.id);
const response = await deleteWorkspace(currentWorkspace.name);
// Load the new workspace data
await loadWorkspaceData(response.nextWorkspaceId);
await loadWorkspaceData(response.nextWorkspaceName);
notifications.show({
title: 'Success',
@@ -162,7 +162,7 @@ export const WorkspaceProvider = ({ children }) => {
};
const response = await updateWorkspace(
currentWorkspace.id,
currentWorkspace.name,
updatedWorkspace
);
setCurrentWorkspace(response);

View File

@@ -19,7 +19,7 @@ export const useFileContent = (selectedFile) => {
if (filePath === DEFAULT_FILE.path) {
newContent = DEFAULT_FILE.content;
} else if (!isImageFile(filePath)) {
newContent = await fetchFileContent(currentWorkspace.id, filePath);
newContent = await fetchFileContent(currentWorkspace.name, filePath);
} else {
newContent = ''; // Set empty content for image files
}

View File

@@ -10,7 +10,7 @@ export const useFileList = () => {
if (!currentWorkspace || workspaceLoading) return;
try {
const fileList = await fetchFileList(currentWorkspace.id);
const fileList = await fetchFileList(currentWorkspace.name);
if (Array.isArray(fileList)) {
setFiles(fileList);
} else {

View File

@@ -29,7 +29,7 @@ export const useFileOperations = () => {
if (!currentWorkspace) return false;
try {
await saveFileContent(currentWorkspace.id, filePath, content);
await saveFileContent(currentWorkspace.name, filePath, content);
notifications.show({
title: 'Success',
message: 'File saved successfully',
@@ -55,7 +55,7 @@ export const useFileOperations = () => {
if (!currentWorkspace) return false;
try {
await deleteFile(currentWorkspace.id, filePath);
await deleteFile(currentWorkspace.name, filePath);
notifications.show({
title: 'Success',
message: 'File deleted successfully',
@@ -81,7 +81,7 @@ export const useFileOperations = () => {
if (!currentWorkspace) return false;
try {
await saveFileContent(currentWorkspace.id, fileName, initialContent);
await saveFileContent(currentWorkspace.name, fileName, initialContent);
notifications.show({
title: 'Success',
message: 'File created successfully',

View File

@@ -10,7 +10,7 @@ export const useGitOperations = () => {
if (!currentWorkspace || !settings.gitEnabled) return false;
try {
await pullChanges(currentWorkspace.id);
await pullChanges(currentWorkspace.name);
notifications.show({
title: 'Success',
message: 'Successfully pulled latest changes',
@@ -33,7 +33,7 @@ export const useGitOperations = () => {
if (!currentWorkspace || !settings.gitEnabled) return false;
try {
await commitAndPush(currentWorkspace.id, message);
await commitAndPush(currentWorkspace.name, message);
notifications.show({
title: 'Success',
message: 'Successfully committed and pushed changes',

View File

@@ -9,7 +9,7 @@ export const useLastOpenedFile = () => {
if (!currentWorkspace) return null;
try {
const response = await getLastOpenedFile(currentWorkspace.id);
const response = await getLastOpenedFile(currentWorkspace.name);
return response.lastOpenedFilePath || null;
} catch (error) {
console.error('Failed to load last opened file:', error);
@@ -22,7 +22,7 @@ export const useLastOpenedFile = () => {
if (!currentWorkspace) return;
try {
await updateLastOpenedFile(currentWorkspace.id, filePath);
await updateLastOpenedFile(currentWorkspace.name, filePath);
} catch (error) {
console.error('Failed to save last opened file:', error);
}

View File

@@ -1,28 +1,28 @@
import { API_BASE_URL } from '../utils/constants';
import { apiCall } from './authApi';
export const fetchLastWorkspaceId = async () => {
export const fetchLastWorkspaceName = async () => {
const response = await apiCall(`${API_BASE_URL}/workspaces/last`);
return response.json();
};
export const fetchFileList = async (workspaceId) => {
export const fetchFileList = async (workspaceName) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/files`
`${API_BASE_URL}/workspaces/${workspaceName}/files`
);
return response.json();
};
export const fetchFileContent = async (workspaceId, filePath) => {
export const fetchFileContent = async (workspaceName, filePath) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/files/${filePath}`
`${API_BASE_URL}/workspaces/${workspaceName}/files/${filePath}`
);
return response.text();
};
export const saveFileContent = async (workspaceId, filePath, content) => {
export const saveFileContent = async (workspaceName, filePath, content) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/files/${filePath}`,
`${API_BASE_URL}/workspaces/${workspaceName}/files/${filePath}`,
{
method: 'POST',
headers: {
@@ -34,9 +34,9 @@ export const saveFileContent = async (workspaceId, filePath, content) => {
return response.text();
};
export const deleteFile = async (workspaceId, filePath) => {
export const deleteFile = async (workspaceName, filePath) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/files/${filePath}`,
`${API_BASE_URL}/workspaces/${workspaceName}/files/${filePath}`,
{
method: 'DELETE',
}
@@ -44,26 +44,29 @@ export const deleteFile = async (workspaceId, filePath) => {
return response.text();
};
export const getWorkspace = async (workspaceId) => {
const response = await apiCall(`${API_BASE_URL}/workspaces/${workspaceId}`);
export const getWorkspace = async (workspaceName) => {
const response = await apiCall(`${API_BASE_URL}/workspaces/${workspaceName}`);
return response.json();
};
// Combined function to update workspace data including settings
export const updateWorkspace = async (workspaceId, workspaceData) => {
const response = await apiCall(`${API_BASE_URL}/workspaces/${workspaceId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(workspaceData),
});
export const updateWorkspace = async (workspaceName, workspaceData) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceName}`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(workspaceData),
}
);
return response.json();
};
export const pullChanges = async (workspaceId) => {
export const pullChanges = async (workspaceName) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/git/pull`,
`${API_BASE_URL}/workspaces/${workspaceName}/git/pull`,
{
method: 'POST',
}
@@ -71,9 +74,9 @@ export const pullChanges = async (workspaceId) => {
return response.json();
};
export const commitAndPush = async (workspaceId, message) => {
export const commitAndPush = async (workspaceName, message) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/git/commit`,
`${API_BASE_URL}/workspaces/${workspaceName}/git/commit`,
{
method: 'POST',
headers: {
@@ -85,13 +88,13 @@ export const commitAndPush = async (workspaceId, message) => {
return response.json();
};
export const getFileUrl = (workspaceId, filePath) => {
return `${API_BASE_URL}/workspaces/${workspaceId}/files/${filePath}`;
export const getFileUrl = (workspaceName, filePath) => {
return `${API_BASE_URL}/workspaces/${workspaceName}/files/${filePath}`;
};
export const lookupFileByName = async (workspaceId, filename) => {
export const lookupFileByName = async (workspaceName, filename) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/files/lookup?filename=${encodeURIComponent(
`${API_BASE_URL}/workspaces/${workspaceName}/files/lookup?filename=${encodeURIComponent(
filename
)}`
);
@@ -99,9 +102,9 @@ export const lookupFileByName = async (workspaceId, filename) => {
return data.paths;
};
export const updateLastOpenedFile = async (workspaceId, filePath) => {
export const updateLastOpenedFile = async (workspaceName, filePath) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/files/last`,
`${API_BASE_URL}/workspaces/${workspaceName}/files/last`,
{
method: 'PUT',
headers: {
@@ -113,9 +116,9 @@ export const updateLastOpenedFile = async (workspaceId, filePath) => {
return response.json();
};
export const getLastOpenedFile = async (workspaceId) => {
export const getLastOpenedFile = async (workspaceName) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceId}/files/last`
`${API_BASE_URL}/workspaces/${workspaceName}/files/last`
);
return response.json();
};
@@ -136,20 +139,23 @@ export const createWorkspace = async (name) => {
return response.json();
};
export const deleteWorkspace = async (workspaceId) => {
const response = await apiCall(`${API_BASE_URL}/workspaces/${workspaceId}`, {
method: 'DELETE',
});
export const deleteWorkspace = async (workspaceName) => {
const response = await apiCall(
`${API_BASE_URL}/workspaces/${workspaceName}`,
{
method: 'DELETE',
}
);
return response.json();
};
export const updateLastWorkspace = async (workspaceId) => {
export const updateLastWorkspaceName = async (workspaceName) => {
const response = await apiCall(`${API_BASE_URL}/workspaces/last`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ workspaceId }),
body: JSON.stringify({ workspaceName }),
});
return response.json();
};

View File

@@ -27,10 +27,10 @@ function createFileLink(filePath, displayText, heading, baseUrl) {
};
}
function createImageNode(workspaceId, filePath, displayText) {
function createImageNode(workspaceName, filePath, displayText) {
return {
type: 'image',
url: getFileUrl(workspaceId, filePath),
url: getFileUrl(workspaceName, filePath),
alt: displayText,
title: displayText,
};
@@ -43,9 +43,9 @@ function addMarkdownExtension(fileName) {
return `${fileName}.md`;
}
export function remarkWikiLinks(workspaceId) {
export function remarkWikiLinks(workspaceName) {
return async function transformer(tree) {
if (!workspaceId) {
if (!workspaceName) {
console.warn('No workspace ID provided to remarkWikiLinks plugin');
return;
}
@@ -113,13 +113,13 @@ export function remarkWikiLinks(workspaceId) {
? match.fileName
: addMarkdownExtension(match.fileName);
const paths = await lookupFileByName(workspaceId, lookupFileName);
const paths = await lookupFileByName(workspaceName, lookupFileName);
if (paths && paths.length > 0) {
const filePath = paths[0];
if (match.isImage) {
newNodes.push(
createImageNode(workspaceId, filePath, match.displayText)
createImageNode(workspaceName, filePath, match.displayText)
);
} else {
newNodes.push(

View File

@@ -52,11 +52,16 @@ export default defineConfig(({ mode }) => ({
// Markdown processing
markdown: [
'react-markdown',
'react-syntax-highlighter',
'rehype-katex',
'rehype-mathjax',
'rehype-prism',
'rehype-react',
'remark',
'remark-math',
'katex',
'remark-parse',
'remark-rehype',
'unified',
'unist-util-visit',
],
// Icons and utilities