Merge branch 'master' of github.com:Mintplex-Labs/anything-llm

This commit is contained in:
timothycarambat 2025-03-17 17:47:55 -07:00
commit 0d5e869f5c
5 changed files with 162 additions and 13 deletions

View File

@ -164,18 +164,28 @@ const PinItemToWorkspace = memo(({ workspace, docPath, item }) => {
<div
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
className="flex gap-x-2 items-center hover:bg-theme-file-picker-hover p-[2px] rounded ml-2"
onClick={updatePinStatus}
className="flex items-center ml-2 cursor-pointer"
data-tooltip-id="pin-document"
data-tooltip-content={
pinned ? "Un-pin from workspace" : "Pin to workspace"
}
>
<PushPin
data-tooltip-id="pin-document"
data-tooltip-content={
pinned ? "Un-Pin from workspace" : "Pin to workspace"
}
size={16}
onClick={updatePinStatus}
weight={hover || pinned ? "fill" : "regular"}
className="outline-none text-base font-bold flex-shrink-0 cursor-pointer"
/>
{pinned ? (
<div
className={`bg-theme-settings-input-active rounded-3xl whitespace-nowrap ${hover ? "bg-red-500/20" : ""}`}
>
<p className={`text-xs px-2 py-0.5 ${hover ? "text-red-500" : ""}`}>
{hover ? "Un-pin" : "Pinned"}
</p>
</div>
) : (
<PushPin
size={16}
weight="regular"
className="outline-none text-base font-bold flex-shrink-0"
/>
)}
</div>
);
});

View File

@ -162,7 +162,11 @@ function WorkspaceDirectory({
<div className="overflow-y-auto h-[calc(100%-40px)]">
{files.items.some((folder) => folder.items.length > 0) ||
movedItems.length > 0 ? (
<RenderFileRows files={files} movedItems={movedItems}>
<RenderFileRows
files={files}
movedItems={movedItems}
workspace={workspace}
>
{({ item, folder }) => (
<WorkspaceFileRow
key={item.id}
@ -384,12 +388,19 @@ const DocumentWatchAlert = memo(() => {
);
});
function RenderFileRows({ files, movedItems, children }) {
function RenderFileRows({ files, movedItems, children, workspace }) {
function sortMovedItemsAndFiles(a, b) {
const aIsMovedItem = movedItems.some((movedItem) => movedItem.id === a.id);
const bIsMovedItem = movedItems.some((movedItem) => movedItem.id === b.id);
if (aIsMovedItem && !bIsMovedItem) return -1;
if (!aIsMovedItem && bIsMovedItem) return 1;
// Sort pinned items to the top
const aIsPinned = a.pinnedWorkspaces?.includes(workspace.id);
const bIsPinned = b.pinnedWorkspaces?.includes(workspace.id);
if (aIsPinned && !bIsPinned) return -1;
if (!aIsPinned && bIsPinned) return 1;
return 0;
}

View File

@ -14,6 +14,7 @@ const { CollectorApi } = require("../../../utils/collectorApi");
const fs = require("fs");
const path = require("path");
const { Document } = require("../../../models/documents");
const { purgeFolder } = require("../../../utils/files/purgeDocument");
const documentsPath =
process.env.NODE_ENV === "development"
? path.resolve(__dirname, "../../../storage/documents")
@ -847,6 +848,65 @@ function apiDocumentEndpoints(app) {
}
);
app.delete(
"/v1/document/remove-folder",
[validApiKey],
async (request, response) => {
/*
#swagger.tags = ['Documents']
#swagger.description = 'Remove a folder and all its contents from the documents storage directory.'
#swagger.requestBody = {
description: 'Name of the folder to remove.',
required: true,
content: {
"application/json": {
schema: {
type: 'object',
properties: {
name: {
type: 'string',
example: "my-folder"
}
}
}
}
}
}
#swagger.responses[200] = {
content: {
"application/json": {
schema: {
type: 'object',
example: {
success: true,
message: "Folder removed successfully"
}
}
}
}
}
#swagger.responses[403] = {
schema: {
"$ref": "#/definitions/InvalidAPIKey"
}
}
*/
try {
const { name } = reqBody(request);
await purgeFolder(name);
response
.status(200)
.json({ success: true, message: "Folder removed successfully" });
} catch (e) {
console.error(e);
response.status(500).json({
success: false,
message: `Failed to remove folder: ${e.message}`,
});
}
}
);
app.post(
"/v1/document/move-files",
[validApiKey],

View File

@ -1532,6 +1532,66 @@
}
}
},
"/v1/document/remove-folder": {
"delete": {
"tags": [
"Documents"
],
"description": "Remove a folder and all its contents from the documents storage directory.",
"parameters": [],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"example": {
"success": true,
"message": "Folder removed successfully"
}
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InvalidAPIKey"
}
},
"application/xml": {
"schema": {
"$ref": "#/components/schemas/InvalidAPIKey"
}
}
}
},
"500": {
"description": "Internal Server Error"
}
},
"requestBody": {
"description": "Name of the folder to remove.",
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "my-folder"
}
}
}
}
}
}
}
},
"/v1/document/move-files": {
"post": {
"tags": [

View File

@ -22,6 +22,14 @@ async function purgeDocument(filename = null) {
return;
}
/**
* Purge a folder and all its contents. This will also remove all vector-cache files and workspace document associations
* for the documents within the folder.
* @notice This function is not recursive. It only purges the contents of the specified folder.
* @notice You cannot purge the `custom-documents` folder.
* @param {string} folderName - The name/path of the folder to purge.
* @returns {Promise<void>}
*/
async function purgeFolder(folderName = null) {
if (!folderName) return;
const subFolder = normalizePath(folderName);