mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-06 07:54:22 +00:00
Make logging in work on frontend
This commit is contained in:
@@ -45,8 +45,8 @@ func SetupRoutes(r chi.Router, db *db.DB, fs *filesystem.FileSystem, authMiddlew
|
||||
r.Route("/workspaces", func(r chi.Router) {
|
||||
r.Get("/", handler.ListWorkspaces())
|
||||
r.Post("/", handler.CreateWorkspace())
|
||||
r.Get("/last", handler.GetLastWorkspace())
|
||||
r.Put("/last", handler.UpdateLastWorkspace())
|
||||
r.Get("/last", handler.GetLastWorkspaceName())
|
||||
r.Put("/last", handler.UpdateLastWorkspaceName())
|
||||
|
||||
// Single workspace routes
|
||||
r.Route("/{workspaceName}", func(r chi.Router) {
|
||||
|
||||
@@ -120,9 +120,26 @@ func (db *DB) UpdateUser(user *models.User) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) UpdateLastWorkspace(userID, workspaceID int) error {
|
||||
_, err := db.Exec("UPDATE users SET last_workspace_id = ? WHERE id = ?", workspaceID, userID)
|
||||
return err
|
||||
func (db *DB) UpdateLastWorkspace(userID int, workspaceName string) error {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var workspaceID int
|
||||
|
||||
err = tx.QueryRow("SELECT id FROM workspaces WHERE user_id = ? AND name = ?", userID, workspaceName).Scan(&workspaceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("UPDATE users SET last_workspace_id = ? WHERE id = ?", workspaceID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (db *DB) DeleteUser(id int) error {
|
||||
@@ -147,8 +164,14 @@ func (db *DB) DeleteUser(id int) error {
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (db *DB) GetLastWorkspaceID(userID int) (int, error) {
|
||||
var workspaceID int
|
||||
err := db.QueryRow("SELECT last_workspace_id FROM users WHERE id = ?", userID).Scan(&workspaceID)
|
||||
return workspaceID, err
|
||||
func (db *DB) GetLastWorkspaceName(userID int) (string, error) {
|
||||
var workspaceName string
|
||||
err := db.QueryRow(`
|
||||
SELECT
|
||||
w.name
|
||||
FROM workspaces w
|
||||
JOIN users u ON u.last_workspace_id = w.id
|
||||
WHERE u.id = ?`, userID).
|
||||
Scan(&workspaceName)
|
||||
return workspaceName, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"novamd/internal/httpcontext"
|
||||
@@ -151,10 +152,12 @@ func (h *Handler) DeleteWorkspace() http.HandlerFunc {
|
||||
}
|
||||
|
||||
// Find another workspace to set as last
|
||||
var nextWorkspaceName string
|
||||
var nextWorkspaceID int
|
||||
for _, ws := range workspaces {
|
||||
if ws.ID != ctx.Workspace.ID {
|
||||
nextWorkspaceID = ws.ID
|
||||
nextWorkspaceName = ws.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -188,28 +191,28 @@ func (h *Handler) DeleteWorkspace() http.HandlerFunc {
|
||||
}
|
||||
|
||||
// Return the next workspace ID in the response so frontend knows where to redirect
|
||||
respondJSON(w, map[string]int{"nextWorkspaceId": nextWorkspaceID})
|
||||
respondJSON(w, map[string]string{"nextWorkspaceName": nextWorkspaceName})
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) GetLastWorkspace() http.HandlerFunc {
|
||||
func (h *Handler) GetLastWorkspaceName() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, ok := httpcontext.GetRequestContext(w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
workspaceID, err := h.DB.GetLastWorkspaceID(ctx.UserID)
|
||||
workspaceName, err := h.DB.GetLastWorkspaceName(ctx.UserID)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to get last workspace", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
respondJSON(w, map[string]int{"lastWorkspaceId": workspaceID})
|
||||
respondJSON(w, map[string]string{"lastWorkspaceName": workspaceName})
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateLastWorkspace() http.HandlerFunc {
|
||||
func (h *Handler) UpdateLastWorkspaceName() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, ok := httpcontext.GetRequestContext(w, r)
|
||||
if !ok {
|
||||
@@ -217,15 +220,17 @@ func (h *Handler) UpdateLastWorkspace() http.HandlerFunc {
|
||||
}
|
||||
|
||||
var requestBody struct {
|
||||
WorkspaceID int `json:"workspaceId"`
|
||||
WorkspaceName string `json:"workspaceName"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
|
||||
fmt.Println(err)
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.DB.UpdateLastWorkspace(ctx.UserID, requestBody.WorkspaceID); err != nil {
|
||||
if err := h.DB.UpdateLastWorkspace(ctx.UserID, requestBody.WorkspaceName); err != nil {
|
||||
fmt.Println(err)
|
||||
http.Error(w, "Failed to update last workspace", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
32
frontend/package-lock.json
generated
32
frontend/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user