From bdf65674185522fd6202840513574d8e216e6fc5 Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Tue, 2 May 2023 22:11:29 -0400 Subject: [PATCH] 20469: Provide select parameter to contents to avoid loading mounts Arvados-DCO-1.1-Signed-off-by: Peter Amstutz --- src/models/container-request.ts | 62 ++++----- src/models/group.ts | 19 ++- src/services/groups-service/groups-service.ts | 125 +++++++++--------- .../project-panel-middleware-service.ts | 10 +- 4 files changed, 121 insertions(+), 95 deletions(-) diff --git a/src/models/container-request.ts b/src/models/container-request.ts index aa5e0f79..02a8ea70 100644 --- a/src/models/container-request.ts +++ b/src/models/container-request.ts @@ -8,41 +8,41 @@ import { RuntimeConstraints } from './runtime-constraints'; import { SchedulingParameters } from './scheduling-parameters'; export enum ContainerRequestState { - UNCOMMITTED = 'Uncommitted', - COMMITTED = 'Committed', - FINAL = 'Final', + UNCOMMITTED = 'Uncommitted', + COMMITTED = 'Committed', + FINAL = 'Final', } export interface ContainerRequestResource - extends Resource, + extends Resource, ResourceWithProperties { - command: string[]; - containerCountMax: number; - containerCount: number; - containerImage: string; - containerUuid: string | null; - cumulativeCost: number; - cwd: string; - description: string; - environment: any; - expiresAt: string; - filters: string; - kind: ResourceKind.CONTAINER_REQUEST; - logUuid: string | null; - mounts: { [path: string]: MountType }; - name: string; - outputName: string; - outputPath: string; - outputProperties: any; - outputStorageClasses: string[]; - outputTtl: number; - outputUuid: string | null; - priority: number | null; - requestingContainerUuid: string | null; - runtimeConstraints: RuntimeConstraints; - schedulingParameters: SchedulingParameters; - state: ContainerRequestState; - useExisting: boolean; + command: string[]; + containerCountMax: number; + containerCount: number; + containerImage: string; + containerUuid: string | null; + cumulativeCost: number; + cwd: string; + description: string; + environment: any; + expiresAt: string; + filters: string; + kind: ResourceKind.CONTAINER_REQUEST; + logUuid: string | null; + mounts: { [path: string]: MountType }; + name: string; + outputName: string; + outputPath: string; + outputProperties: any; + outputStorageClasses: string[]; + outputTtl: number; + outputUuid: string | null; + priority: number | null; + requestingContainerUuid: string | null; + runtimeConstraints: RuntimeConstraints; + schedulingParameters: SchedulingParameters; + state: ContainerRequestState; + useExisting: boolean; } // Until the api supports unselecting fields, we need a list of all other fields to omit mounts diff --git a/src/models/group.ts b/src/models/group.ts index f6a72c53..109f3857 100644 --- a/src/models/group.ts +++ b/src/models/group.ts @@ -21,8 +21,8 @@ export interface GroupResource extends TrashableResource, ResourceWithProperties export enum GroupClass { PROJECT = 'project', - FILTER = 'filter', - ROLE = 'role', + FILTER = 'filter', + ROLE = 'role', } export enum BuiltinGroups { @@ -40,3 +40,18 @@ export const isBuiltinGroup = (uuid: string) => { const parts = match ? match[0].split('-') : []; return parts.length === 3 && parts[1] === ResourceObjectType.GROUP && Object.values(BuiltinGroups).includes(parts[2]); }; + +export const selectedFieldsOfGroup = [ + "uuid", + "name", + "group_class", + "description", + "properties", + "writable_by", + "can_write", + "can_manage", + "trash_at", + "delete_at", + "is_trashed", + "frozen_by_uuid" +]; diff --git a/src/services/groups-service/groups-service.ts b/src/services/groups-service/groups-service.ts index a36ddba8..cdbe8bab 100644 --- a/src/services/groups-service/groups-service.ts +++ b/src/services/groups-service/groups-service.ts @@ -6,8 +6,8 @@ import { CancelToken } from 'axios'; import { snakeCase, camelCase } from "lodash"; import { CommonResourceService } from 'services/common-service/common-resource-service'; import { - ListResults, - ListArguments, + ListResults, + ListArguments, } from 'services/common-service/common-service'; import { AxiosInstance, AxiosRequestConfig } from 'axios'; import { CollectionResource } from 'models/collection'; @@ -20,78 +20,85 @@ import { GroupResource } from 'models/group'; import { Session } from 'models/session'; export interface ContentsArguments { - limit?: number; - offset?: number; - order?: string; - filters?: string; - recursive?: boolean; - includeTrash?: boolean; - excludeHomeProject?: boolean; + limit?: number; + offset?: number; + order?: string; + filters?: string; + recursive?: boolean; + includeTrash?: boolean; + excludeHomeProject?: boolean; + select?: string[]; } export interface SharedArguments extends ListArguments { - include?: string; + include?: string; } export type GroupContentsResource = - | CollectionResource - | ProjectResource - | ProcessResource - | WorkflowResource; + | CollectionResource + | ProjectResource + | ProcessResource + | WorkflowResource; export class GroupsService< - T extends GroupResource = GroupResource -> extends TrashableResourceService { - constructor(serverApi: AxiosInstance, actions: ApiActions) { - super(serverApi, 'groups', actions); - } + T extends GroupResource = GroupResource + > extends TrashableResourceService { + constructor(serverApi: AxiosInstance, actions: ApiActions) { + super(serverApi, 'groups', actions); + } -async contents(uuid: string, args: ContentsArguments = {}, session?: Session, cancelToken?: CancelToken): Promise> { - const { filters, order, ...other } = args; - const params = { - ...other, - filters: filters ? `[${filters}]` : undefined, - order: order ? order : undefined - }; - const pathUrl = uuid ? `/${uuid}/contents` : '/contents'; - const cfg: AxiosRequestConfig = { - params: CommonResourceService.mapKeys(snakeCase)(params), - }; + async contents(uuid: string, args: ContentsArguments = {}, session?: Session, cancelToken?: CancelToken): Promise> { + const { filters, order, select, ...other } = args; + const params = { + ...other, + filters: filters ? `[${filters}]` : undefined, + order: order ? order : undefined, + select: select + ? JSON.stringify(select.map(sel => { + const sp = sel.split("."); + return sp.length == 2 ? (sp[0] + "." + snakeCase(sp[1])) : snakeCase(sel); + })) + : undefined + }; + const pathUrl = uuid ? `/${uuid}/contents` : '/contents'; + const cfg: AxiosRequestConfig = { + params: CommonResourceService.mapKeys(snakeCase)(params), + }; - if (session) { - cfg.baseURL = session.baseUrl; - cfg.headers = { Authorization: 'Bearer ' + session.token }; - } + if (session) { + cfg.baseURL = session.baseUrl; + cfg.headers = { Authorization: 'Bearer ' + session.token }; + } - if (cancelToken) { - cfg.cancelToken = cancelToken; - } + if (cancelToken) { + cfg.cancelToken = cancelToken; + } - const response = await CommonResourceService.defaultResponse( - this.serverApi.get(this.resourceType + pathUrl, cfg), - this.actions, - false - ); + const response = await CommonResourceService.defaultResponse( + this.serverApi.get(this.resourceType + pathUrl, cfg), + this.actions, + false + ); - return { - ...TrashableResourceService.mapKeys(camelCase)(response), - clusterId: session && session.clusterId, - }; - } + return { + ...TrashableResourceService.mapKeys(camelCase)(response), + clusterId: session && session.clusterId, + }; + } - shared( - params: SharedArguments = {} - ): Promise> { - return CommonResourceService.defaultResponse( - this.serverApi.get(this.resourceType + '/shared', { params }), - this.actions - ); - } + shared( + params: SharedArguments = {} + ): Promise> { + return CommonResourceService.defaultResponse( + this.serverApi.get(this.resourceType + '/shared', { params }), + this.actions + ); + } } export enum GroupContentsResourcePrefix { - COLLECTION = 'collections', - PROJECT = 'groups', - PROCESS = 'container_requests', - WORKFLOW = 'workflows', + COLLECTION = 'collections', + PROJECT = 'groups', + PROCESS = 'container_requests', + WORKFLOW = 'workflows', } diff --git a/src/store/project-panel/project-panel-middleware-service.ts b/src/store/project-panel/project-panel-middleware-service.ts index 7051d062..c9aafd52 100644 --- a/src/store/project-panel/project-panel-middleware-service.ts +++ b/src/store/project-panel/project-panel-middleware-service.ts @@ -38,6 +38,9 @@ import { buildProcessStatusFilters } from 'store/resource-type-filters/resource-type-filters'; import { updatePublicFavorites } from 'store/public-favorites/public-favorites-actions'; +import { selectedFieldsOfGroup } from 'models/group'; +import { defaultCollectionSelectedFields } from 'models/collection'; +import { containerRequestFieldsNoMounts } from 'models/container-request'; export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService { constructor(private services: ServiceRepository, id: string) { @@ -82,8 +85,8 @@ export const loadMissingProcessesInformation = (resources: GroupContentsResource async (dispatch: Dispatch) => { const containerUuids = resources.reduce((uuids, resource) => { return resource.kind === ResourceKind.CONTAINER_REQUEST && - resource.containerUuid && - !uuids.includes(resource.containerUuid) + resource.containerUuid && + !uuids.includes(resource.containerUuid) ? [...uuids, resource.containerUuid] : uuids; }, [] as string[]); @@ -105,7 +108,8 @@ export const getParams = (dataExplorer: DataExplorer, isProjectTrashed: boolean) ...dataExplorerToListParams(dataExplorer), order: getOrder(dataExplorer), filters: getFilters(dataExplorer), - includeTrash: isProjectTrashed + includeTrash: isProjectTrashed, + select: selectedFieldsOfGroup.concat(defaultCollectionSelectedFields, containerRequestFieldsNoMounts) }); export const getFilters = (dataExplorer: DataExplorer) => { -- 2.30.2