Skip to content

Commit

Permalink
[CoreNodes] Hide certain folders when empty (Shared with me, Orphaned…
Browse files Browse the repository at this point in the history
… Resources) (#10236)

* add a specific mime type for google's Shared with me folder

* add backfill script

* add a filter on catch all folders

* add the URL for the shared with me folder

* rename CATCH_ALL_FOLDERS_ into FOLDERS_TO_HIDE_IF_EMPTY_
  • Loading branch information
aubin-tchoi authored Jan 27, 2025
1 parent b8728a8 commit bae93cd
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 5 deletions.
42 changes: 42 additions & 0 deletions connectors/migrations/20250127_backfill_gdrive_shared_with_me.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { MIME_TYPES } from "@dust-tt/types";
import { makeScript } from "scripts/helpers";

import {
GOOGLE_DRIVE_SHARED_WITH_ME_VIRTUAL_ID,
GOOGLE_DRIVE_SHARED_WITH_ME_WEB_URL,
} from "@connectors/connectors/google_drive/lib/consts";
import { getInternalId } from "@connectors/connectors/google_drive/temporal/utils";
import { dataSourceConfigFromConnector } from "@connectors/lib/api/data_source_config";
import { concurrentExecutor } from "@connectors/lib/async_utils";
import { upsertDataSourceFolder } from "@connectors/lib/data_sources";
import { ConnectorResource } from "@connectors/resources/connector_resource";

makeScript({}, async ({ execute }, logger) => {
const connectors = await ConnectorResource.listByType("google_drive", {});

await concurrentExecutor(
connectors,
async (connector) => {
const folderId = getInternalId(GOOGLE_DRIVE_SHARED_WITH_ME_VIRTUAL_ID);
if (execute) {
await upsertDataSourceFolder({
dataSourceConfig: dataSourceConfigFromConnector(connector),
folderId,
parents: [folderId],
parentId: null,
title: "Shared with me",
mimeType: MIME_TYPES.GOOGLE_DRIVE.SHARED_WITH_ME,
sourceUrl: GOOGLE_DRIVE_SHARED_WITH_ME_WEB_URL,
});
logger.info(
`Upserted folder ${folderId} for connector ${connector.id}`
);
} else {
logger.info(
`Would upsert folder ${folderId} for connector ${connector.id}`
);
}
},
{ concurrency: 10 }
);
});
7 changes: 5 additions & 2 deletions connectors/src/connectors/google_drive/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import {
getLocalParents,
isDriveObjectExpandable,
} from "@connectors/connectors/google_drive/lib";
import { GOOGLE_DRIVE_SHARED_WITH_ME_VIRTUAL_ID } from "@connectors/connectors/google_drive/lib/consts";
import {
GOOGLE_DRIVE_SHARED_WITH_ME_VIRTUAL_ID,
GOOGLE_DRIVE_SHARED_WITH_ME_WEB_URL,
} from "@connectors/connectors/google_drive/lib/consts";
import { getGoogleDriveObject } from "@connectors/connectors/google_drive/lib/google_drive_api";
import { getPermissionViewType } from "@connectors/connectors/google_drive/lib/permissions";
import {
Expand Down Expand Up @@ -416,7 +419,7 @@ export class GoogleDriveConnectorManager extends BaseConnectorManager<null> {
type: "folder" as const,
preventSelection: true,
title: "Shared with me",
sourceUrl: null,
sourceUrl: GOOGLE_DRIVE_SHARED_WITH_ME_WEB_URL,
lastUpdatedAt: null,
expandable: true,
permission: "none",
Expand Down
4 changes: 4 additions & 0 deletions connectors/src/connectors/google_drive/lib/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ export const GOOGLE_DRIVE_USER_SPACE_VIRTUAL_DRIVE_ID = "userspace";
// and a "sharedWithMe=true" property.
// On our side, we want to group them into one virtual folder in our UI. This is the ID of that virtual folder.
export const GOOGLE_DRIVE_SHARED_WITH_ME_VIRTUAL_ID = "sharedWithMe";

// URL to the "Shared with me" section of Google Drive.
export const GOOGLE_DRIVE_SHARED_WITH_ME_WEB_URL =
"https://drive.google.com/drive/shared-with-me";
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Op } from "sequelize";
import { getSourceUrlForGoogleDriveFiles } from "@connectors/connectors/google_drive";
import {
GOOGLE_DRIVE_SHARED_WITH_ME_VIRTUAL_ID,
GOOGLE_DRIVE_SHARED_WITH_ME_WEB_URL,
GOOGLE_DRIVE_USER_SPACE_VIRTUAL_DRIVE_ID,
} from "@connectors/connectors/google_drive/lib/consts";
import { getGoogleDriveObject } from "@connectors/connectors/google_drive/lib/google_drive_api";
Expand Down Expand Up @@ -75,7 +76,8 @@ export async function upsertSharedWithMeFolder(connectorId: ModelId) {
parents: [folderId],
parentId: null,
title: "Shared with me",
mimeType: MIME_TYPES.GOOGLE_DRIVE.FOLDER,
mimeType: MIME_TYPES.GOOGLE_DRIVE.SHARED_WITH_ME,
sourceUrl: GOOGLE_DRIVE_SHARED_WITH_ME_WEB_URL,
});
}

Expand Down
5 changes: 5 additions & 0 deletions front/lib/api/content_nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export const NON_EXPANDABLE_NODES_MIME_TYPES = [
MIME_TYPES.GITHUB.ISSUES,
] as readonly string[];

export const FOLDERS_TO_HIDE_IF_EMPTY_MIME_TYPES = [
MIME_TYPES.NOTION.UNKNOWN_FOLDER,
MIME_TYPES.GOOGLE_DRIVE.SHARED_WITH_ME,
] as readonly string[];

export function getContentNodeInternalIdFromTableId(
dataSourceView: DataSourceViewResource | DataSourceViewType,
tableId: string
Expand Down
15 changes: 14 additions & 1 deletion front/lib/api/data_source_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import assert from "assert";
import config from "@app/lib/api/config";
import {
computeNodesDiff,
FOLDERS_TO_HIDE_IF_EMPTY_MIME_TYPES,
getContentNodeInternalIdFromTableId,
getContentNodeMetadata,
NON_EXPANDABLE_NODES_MIME_TYPES,
Expand Down Expand Up @@ -181,6 +182,16 @@ function filterNodesByViewType(
}
}

function removeCatchAllFoldersIfEmpty(
nodes: CoreAPIContentNode[]
): CoreAPIContentNode[] {
return nodes.filter(
(node) =>
!FOLDERS_TO_HIDE_IF_EMPTY_MIME_TYPES.includes(node.mime_type) ||
node.has_children
);
}

function makeCoreDataSourceViewFilter(
dataSourceView: DataSourceViewResource | DataSourceViewType
): CoreAPIDatasourceViewFilter {
Expand Down Expand Up @@ -237,7 +248,9 @@ async function getContentNodesForDataSourceViewFromCore(
return new Err(new Error(coreRes.error.message));
}

const filteredNodes = filterNodesByViewType(coreRes.value.nodes, viewType);
const filteredNodes = removeCatchAllFoldersIfEmpty(
filterNodesByViewType(coreRes.value.nodes, viewType)
);

return new Ok({
nodes: filteredNodes.map((node) => {
Expand Down
2 changes: 1 addition & 1 deletion types/src/shared/internal_mime_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const MIME_TYPES = {
provider: "google_drive",
// Spreadsheets are handled as data_source_folders for sheets
// For other files and sheets, we keep Google's mime types
resourceTypes: ["FOLDER", "SPREADSHEET"],
resourceTypes: ["SHARED_WITH_ME", "FOLDER", "SPREADSHEET"],
}),
INTERCOM: getMimeTypes({
provider: "intercom",
Expand Down

0 comments on commit bae93cd

Please sign in to comment.