diff --git a/.github/workflows/test_galaxy_packages.yaml b/.github/workflows/test_galaxy_packages.yaml index f2e5d88b52a7..402cee12b895 100644 --- a/.github/workflows/test_galaxy_packages.yaml +++ b/.github/workflows/test_galaxy_packages.yaml @@ -23,6 +23,11 @@ jobs: - uses: actions/checkout@v3 with: path: 'galaxy root' + - uses: actions/setup-node@v3 + with: + node-version: '18.12.1' + cache: 'yarn' + cache-dependency-path: 'galaxy root/client/yarn.lock' - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} diff --git a/client/src/api/histories.ts b/client/src/api/histories.ts index 65ad7e2d6b1d..cae87c145b8e 100644 --- a/client/src/api/histories.ts +++ b/client/src/api/histories.ts @@ -2,5 +2,6 @@ import { fetcher } from "@/api/schema"; export const historiesFetcher = fetcher.path("/api/histories").method("get").create(); export const archivedHistoriesFetcher = fetcher.path("/api/histories/archived").method("get").create(); +export const deleteHistory = fetcher.path("/api/histories/{history_id}").method("delete").create(); export const undeleteHistory = fetcher.path("/api/histories/deleted/{history_id}/undelete").method("post").create(); -export const purgeHistory = fetcher.path("/api/histories/{history_id}").method("delete").create(); +export const historiesQuery = fetcher.path("/api/histories/query").method("get").create(); diff --git a/client/src/api/schema/schema.ts b/client/src/api/schema/schema.ts index 6175fdc94d4b..3d737e261904 100644 --- a/client/src/api/schema/schema.ts +++ b/client/src/api/schema/schema.ts @@ -521,6 +521,10 @@ export interface paths { /** Return all histories that are published. */ get: operations["published_api_histories_published_get"]; }; + "/api/histories/query": { + /** Returns histories available to the current user. */ + get: operations["query_api_histories_query_get"]; + }; "/api/histories/shared_with_me": { /** Return all histories that are shared with the current user. */ get: operations["shared_with_me_api_histories_shared_with_me_get"]; @@ -904,6 +908,17 @@ export interface paths { /** Prepare history for export-style download and write to supplied URI. */ post: operations["write_store_api_histories__history_id__write_store_post"]; }; + "/api/invocations": { + /** Get the list of a user's workflow invocations. */ + get: operations["index_invocations_api_invocations_get"]; + }; + "/api/invocations/from_store": { + /** + * Create Invocations From Store + * @description Create invocation(s) from a supplied model store. + */ + post: operations["create_invocations_from_store_api_invocations_from_store_post"]; + }; "/api/invocations/steps/{step_id}": { /** Show details of workflow invocation step. */ get: operations["step_api_invocations_steps__step_id__get"]; @@ -1784,6 +1799,10 @@ export interface paths { */ put: operations["enable_link_access_api_workflows__workflow_id__enable_link_access_put"]; }; + "/api/workflows/{workflow_id}/invocations": { + /** Get the list of a user's workflow invocations. */ + get: operations["index_invocations_api_workflows__workflow_id__invocations_get"]; + }; "/api/workflows/{workflow_id}/invocations/{invocation_id}": { /** * Get detailed description of a workflow invocation. @@ -1889,6 +1908,13 @@ export interface paths { */ put: operations["unpublish_api_workflows__workflow_id__unpublish_put"]; }; + "/api/workflows/{workflow_id}/usage": { + /** + * Get the list of a user's workflow invocations. + * @deprecated + */ + get: operations["index_invocations_api_workflows__workflow_id__usage_get"]; + }; "/api/workflows/{workflow_id}/usage/{invocation_id}": { /** * Get detailed description of a workflow invocation. @@ -3018,6 +3044,41 @@ export interface components { /** Store Dict */ store_dict?: Record | null; }; + /** CreateInvocationsFromStorePayload */ + CreateInvocationsFromStorePayload: { + /** + * History ID + * @description The ID of the history associated with the invocations. + * @example 0123456789ABCDEF + */ + history_id: string; + /** + * Legacy Job State + * @deprecated + * @description Populate the invocation step state with the job state instead of the invocation step state. + * This will also produce one step per job in mapping jobs to mimic the older behavior with respect to collections. + * Partially scheduled steps may provide incomplete information and the listed steps outputs + * are not the mapped over step outputs but the individual job outputs. + * @default false + */ + legacy_job_state?: boolean; + model_store_format?: components["schemas"]["ModelStoreFormat"] | null; + /** + * Include step details + * @description Include details for individual invocation steps and populate a steps attribute in the resulting dictionary + * @default false + */ + step_details?: boolean; + /** Store Content Uri */ + store_content_uri?: string | null; + /** Store Dict */ + store_dict?: Record | null; + /** + * View + * @description The name of the view used to serialize this item. This will return a predefined set of attributes of the item. + */ + view?: components["schemas"]["InvocationSerializationView"] | null; + }; /** CreateLibrariesFromStore */ CreateLibrariesFromStore: { model_store_format?: components["schemas"]["ModelStoreFormat"] | null; @@ -4555,11 +4616,6 @@ export interface components { }; /** ExportTaskListResponse */ ExportTaskListResponse: components["schemas"]["ObjectExportTaskResponse"][]; - /** - * ExtendedInvocationStepState - * @enum {string} - */ - ExtendedInvocationStepState: "new" | "ready" | "scheduled" | "ok"; /** ExtraFileEntry */ ExtraFileEntry: { /** @description The class of this entry, either File or Directory. */ @@ -5495,6 +5551,11 @@ export interface components { * @example 0123456789ABCDEF */ id: string; + /** + * Implicit Collection Jobs Id + * @description Encoded ID for the ICJ object describing the collection of jobs corresponding to this collection + */ + implicit_collection_jobs_id?: string | null; /** * Job Source ID * @description The encoded ID of the Job that produced this dataset collection. Used to track the state of the job. @@ -6347,6 +6408,61 @@ export interface components { user_id?: string | null; [key: string]: unknown | undefined; }; + /** HistoryQueryResult */ + HistoryQueryResult: { + /** + * Annotation + * @description The annotation of this History. + */ + annotation?: string | null; + /** + * Create Time + * @description The time and date this item was created. + */ + create_time: string | null; + /** + * Deleted + * @description Whether this History has been deleted. + */ + deleted: boolean; + /** + * ID + * @description Encoded ID of the History. + * @example 0123456789ABCDEF + */ + id: string; + /** + * Importable + * @description Whether this History can be imported. + */ + importable: boolean; + /** + * Name + * @description The name of the History. + */ + name: string; + /** + * Published + * @description Whether this History has been published. + */ + published: boolean; + /** + * Tags + * @description A list of tags to add to this item. + */ + tags: components["schemas"]["TagCollection"] | null; + /** + * Update Time + * @description The last time and date this item was updated. + */ + update_time: string | null; + [key: string]: unknown | undefined; + }; + /** + * HistoryQueryResultList + * @default [] + */ + HistoryQueryResultList: components["schemas"]["HistoryQueryResult"][]; /** * HistorySummary * @description History summary information. @@ -6898,6 +7014,11 @@ export interface components { * @description Report describing workflow invocation */ InvocationReport: { + /** + * Errors + * @description Errors associated with the invocation. + */ + errors?: Record | null; /** * Galaxy Version * @description The version of Galaxy this object was generated with. @@ -6908,6 +7029,21 @@ export interface components { * @description The version of Galaxy this object was generated with. */ generate_version?: string | null; + /** + * Histories + * @description Histories associated with the invocation. + */ + histories?: Record | null; + /** + * History dataset collections + * @description History dataset collections associated with the invocation. + */ + history_dataset_collections?: Record | null; + /** + * History datasets + * @description History datasets associated with the invocation. + */ + history_datasets?: Record | null; /** * Workflow ID * @description The workflow this invocation has been triggered for. @@ -6917,13 +7053,21 @@ export interface components { /** * Markdown * @description Raw galaxy-flavored markdown contents of the report. - * @default */ invocation_markdown?: string | null; + /** + * Invocations + * @description Other invocations associated with the invocation. + */ + invocations?: Record | null; + /** + * Jobs + * @description Jobs associated with the invocation. + */ + jobs?: Record | null; /** * Markdown * @description Raw galaxy-flavored markdown contents of the report. - * @default */ markdown?: string | null; /** @@ -6949,8 +7093,22 @@ export interface components { * @description The name of the user who owns this report. */ username: string; - [key: string]: unknown | undefined; + /** + * Workflows + * @description Workflows associated with the invocation. + */ + workflows?: Record | null; }; + /** + * InvocationSerializationView + * @enum {string} + */ + InvocationSerializationView: "element" | "collection"; + /** + * InvocationSortByEnum + * @enum {string} + */ + InvocationSortByEnum: "create_time" | "update_time" | "None"; /** * InvocationState * @enum {string} @@ -7010,7 +7168,7 @@ export interface components { * State of the invocation step * @description Describes where in the scheduling process the workflow invocation step is. */ - state?: components["schemas"]["ExtendedInvocationStepState"] | null; + state?: components["schemas"]["InvocationStepState"] | components["schemas"]["JobState"] | null; /** Subworkflow Invocation Id */ subworkflow_invocation_id: string | null; /** @@ -7150,6 +7308,11 @@ export interface components { */ uuid?: string | null; }; + /** + * InvocationStepState + * @enum {string} + */ + InvocationStepState: "new" | "ready" | "scheduled"; /** InvocationUnexpectedFailureResponse */ InvocationUnexpectedFailureResponse: { /** @@ -14012,6 +14175,76 @@ export interface operations { }; }; }; + query_api_histories_query_get: { + /** Returns histories available to the current user. */ + parameters?: { + /** @description The maximum number of items to return. */ + /** @description Starts at the beginning skip the first ( offset - 1 ) items and begin returning at the Nth item */ + /** @description Sort index by this specified attribute */ + /** @description Sort in descending order? */ + /** + * @description A mix of free text and GitHub-style tags used to filter the index operation. + * + * ## Query Structure + * + * GitHub-style filter tags (not be confused with Galaxy tags) are tags of the form + * `:` or `:''`. The tag name + * *generally* (but not exclusively) corresponds to the name of an attribute on the model + * being indexed (i.e. a column in the database). + * + * If the tag is quoted, the attribute will be filtered exactly. If the tag is unquoted, + * generally a partial match will be used to filter the query (i.e. in terms of the implementation + * this means the database operation `ILIKE` will typically be used). + * + * Once the tagged filters are extracted from the search query, the remaining text is just + * used to search various documented attributes of the object. + * + * ## GitHub-style Tags Available + * + * `name` + * : The history's name. + * + * `annotation` + * : The history's annotation. (The tag `a` can be used a short hand alias for this tag to filter on this attribute.) + * + * `tag` + * : The history's tags. (The tag `t` can be used a short hand alias for this tag to filter on this attribute.) + * + * ## Free Text + * + * Free text search terms will be searched against the following attributes of the + * Historys: `title`, `description`, `slug`, `tag`. + */ + query?: { + limit?: number | null; + offset?: number | null; + show_own?: boolean; + show_published?: boolean; + show_shared?: boolean; + sort_by?: "create_time" | "name" | "update_time" | "username"; + sort_desc?: boolean; + search?: string | null; + }; + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["HistoryQueryResultList"]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; shared_with_me_api_histories_shared_with_me_get: { /** Return all histories that are shared with the current user. */ parameters?: { @@ -16331,6 +16564,86 @@ export interface operations { }; }; }; + index_invocations_api_invocations_get: { + /** Get the list of a user's workflow invocations. */ + parameters?: { + /** @description Return only invocations for this Workflow ID */ + /** @description Return only invocations for this History ID */ + /** @description Return only invocations for this Job ID */ + /** @description Return invocations for this User ID. */ + /** @description Sort Workflow Invocations by this attribute */ + /** @description Sort in descending order? */ + /** @description Set to false to only include terminal Invocations. */ + /** @description Limit the number of invocations to return. */ + /** @description Number of invocations to skip. */ + /** @description Is provided workflow id for Workflow instead of StoredWorkflow? */ + /** @description View to be passed to the serializer */ + /** @description Include details for individual invocation steps and populate a steps attribute in the resulting dictionary. */ + query?: { + workflow_id?: string | null; + history_id?: string | null; + job_id?: string | null; + user_id?: string | null; + sort_by?: components["schemas"]["InvocationSortByEnum"] | null; + sort_desc?: boolean; + include_terminal?: boolean | null; + limit?: number | null; + offset?: number | null; + instance?: boolean | null; + view?: string | null; + step_details?: boolean; + }; + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["WorkflowInvocationResponse"][]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + create_invocations_from_store_api_invocations_from_store_post: { + /** + * Create Invocations From Store + * @description Create invocation(s) from a supplied model store. + */ + parameters?: { + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CreateInvocationsFromStorePayload"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["WorkflowInvocationResponse"][]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; step_api_invocations_steps__step_id__get: { /** Show details of workflow invocation step. */ parameters: { @@ -16846,6 +17159,7 @@ export interface operations { /** @description Limit listing of jobs to those that match the history_id. If none, jobs from any history may be returned. */ /** @description Limit listing of jobs to those that match the specified workflow ID. If none, jobs from any workflow (or from no workflows) may be returned. */ /** @description Limit listing of jobs to those that match the specified workflow invocation ID. If none, jobs from any workflow invocation (or from no workflows) may be returned. */ + /** @description Limit listing of jobs to those that match the specified implicit collection job ID. If none, jobs from any implicit collection execution (or from no implicit collection execution) may be returned. */ /** @description Sort results by specified field. */ /** * @description A mix of free text and GitHub-style tags used to filter the index operation. @@ -16897,6 +17211,7 @@ export interface operations { history_id?: string | null; workflow_id?: string | null; invocation_id?: string | null; + implicit_collection_jobs_id?: string | null; order_by?: components["schemas"]["JobIndexSortByEnum"]; search?: string | null; limit?: number; @@ -19471,7 +19786,7 @@ export interface operations { /** Import a data manager bundle */ parameters?: { query?: { - tool_data_file_path?: Record; + tool_data_file_path?: string | null; }; /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ header?: { @@ -21158,6 +21473,57 @@ export interface operations { }; }; }; + index_invocations_api_workflows__workflow_id__invocations_get: { + /** Get the list of a user's workflow invocations. */ + parameters: { + /** @description Return only invocations for this History ID */ + /** @description Return only invocations for this Job ID */ + /** @description Return invocations for this User ID. */ + /** @description Sort Workflow Invocations by this attribute */ + /** @description Sort in descending order? */ + /** @description Set to false to only include terminal Invocations. */ + /** @description Limit the number of invocations to return. */ + /** @description Number of invocations to skip. */ + /** @description Is provided workflow id for Workflow instead of StoredWorkflow? */ + /** @description View to be passed to the serializer */ + /** @description Include details for individual invocation steps and populate a steps attribute in the resulting dictionary. */ + query?: { + history_id?: string | null; + job_id?: string | null; + user_id?: string | null; + sort_by?: components["schemas"]["InvocationSortByEnum"] | null; + sort_desc?: boolean; + include_terminal?: boolean | null; + limit?: number | null; + offset?: number | null; + instance?: boolean | null; + view?: string | null; + step_details?: boolean; + }; + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The encoded database identifier of the Stored Workflow. */ + path: { + workflow_id: string; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["WorkflowInvocationResponse"][]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; show_workflow_invocation_api_workflows__workflow_id__invocations__invocation_id__get: { /** * Get detailed description of a workflow invocation. @@ -21772,6 +22138,60 @@ export interface operations { }; }; }; + index_invocations_api_workflows__workflow_id__usage_get: { + /** + * Get the list of a user's workflow invocations. + * @deprecated + */ + parameters: { + /** @description Return only invocations for this History ID */ + /** @description Return only invocations for this Job ID */ + /** @description Return invocations for this User ID. */ + /** @description Sort Workflow Invocations by this attribute */ + /** @description Sort in descending order? */ + /** @description Set to false to only include terminal Invocations. */ + /** @description Limit the number of invocations to return. */ + /** @description Number of invocations to skip. */ + /** @description Is provided workflow id for Workflow instead of StoredWorkflow? */ + /** @description View to be passed to the serializer */ + /** @description Include details for individual invocation steps and populate a steps attribute in the resulting dictionary. */ + query?: { + history_id?: string | null; + job_id?: string | null; + user_id?: string | null; + sort_by?: components["schemas"]["InvocationSortByEnum"] | null; + sort_desc?: boolean; + include_terminal?: boolean | null; + limit?: number | null; + offset?: number | null; + instance?: boolean | null; + view?: string | null; + step_details?: boolean; + }; + /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ + header?: { + "run-as"?: string | null; + }; + /** @description The encoded database identifier of the Stored Workflow. */ + path: { + workflow_id: string; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + content: { + "application/json": components["schemas"]["WorkflowInvocationResponse"][]; + }; + }; + /** @description Validation Error */ + 422: { + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; show_workflow_invocation_api_workflows__workflow_id__usage__invocation_id__get: { /** * Get detailed description of a workflow invocation. diff --git a/client/src/components/Collections/ListCollectionCreatorModal.js b/client/src/components/Collections/ListCollectionCreatorModal.js index ab426dea35ee..9993f240aa0a 100644 --- a/client/src/components/Collections/ListCollectionCreatorModal.js +++ b/client/src/components/Collections/ListCollectionCreatorModal.js @@ -29,7 +29,6 @@ function listCollectionCreatorModal(elements, options) { */ function createListCollection(contents, defaultHideSourceItems = true) { const elements = contents.toJSON(); - let copyElements; const promise = listCollectionCreatorModal(elements, { defaultHideSourceItems: defaultHideSourceItems, creationFn: function (elements, name, hideSourceItems) { @@ -39,8 +38,7 @@ function createListCollection(contents, defaultHideSourceItems = true) { //TODO: this allows for list:list even if the filter above does not - reconcile src: element.src || (element.history_content_type == "dataset" ? "hda" : "hdca"), })); - copyElements = !hideSourceItems; - return contents.createHDCA(elements, "list", name, hideSourceItems, copyElements); + return contents.createHDCA(elements, "list", name, hideSourceItems); }, }); return promise; diff --git a/client/src/components/Collections/PairCollectionCreatorModal.js b/client/src/components/Collections/PairCollectionCreatorModal.js index 56b8d21d125f..1cfa2a64dc71 100644 --- a/client/src/components/Collections/PairCollectionCreatorModal.js +++ b/client/src/components/Collections/PairCollectionCreatorModal.js @@ -25,7 +25,6 @@ function pairCollectionCreatorModal(elements, options) { } function createPairCollection(contents, defaultHideSourceItems = true) { var elements = contents.toJSON(); - var copyElements; var promise = pairCollectionCreatorModal(elements, { defaultHideSourceItems: defaultHideSourceItems, creationFn: function (elements, name, hideSourceItems) { @@ -33,8 +32,7 @@ function createPairCollection(contents, defaultHideSourceItems = true) { { name: "forward", src: elements[0].src || "hda", id: elements[0].id }, { name: "reverse", src: elements[1].src || "hda", id: elements[1].id }, ]; - copyElements = !hideSourceItems; - return contents.createHDCA(elements, "paired", name, hideSourceItems, copyElements); + return contents.createHDCA(elements, "paired", name, hideSourceItems); }, }); return promise; diff --git a/client/src/components/Collections/PairedListCollectionCreatorModal.js b/client/src/components/Collections/PairedListCollectionCreatorModal.js index 0065e75526a0..cab346fc7c63 100644 --- a/client/src/components/Collections/PairedListCollectionCreatorModal.js +++ b/client/src/components/Collections/PairedListCollectionCreatorModal.js @@ -29,7 +29,6 @@ function pairedListCollectionCreatorModal(elements, options) { */ function createPairedListCollection(contents, defaultHideSourceItems) { const elements = contents.toJSON(); - var copyElements; const promise = pairedListCollectionCreatorModal(elements, { defaultHideSourceItems: defaultHideSourceItems, creationFn: function (elements, name, hideSourceItems) { @@ -50,8 +49,7 @@ function createPairedListCollection(contents, defaultHideSourceItems) { }, ], })); - copyElements = !hideSourceItems; - return contents.createHDCA(elements, "list:paired", name, hideSourceItems, copyElements); + return contents.createHDCA(elements, "list:paired", name, hideSourceItems); }, }); return promise; diff --git a/client/src/components/Collections/RuleBasedCollectionCreatorModal.js b/client/src/components/Collections/RuleBasedCollectionCreatorModal.js index 5e7602e5ba65..353f3e312c7c 100644 --- a/client/src/components/Collections/RuleBasedCollectionCreatorModal.js +++ b/client/src/components/Collections/RuleBasedCollectionCreatorModal.js @@ -48,7 +48,6 @@ function createCollectionViaRules(selection, defaultHideSourceItems = true) { let elementsType; let importType; const selectionType = selection.selectionType; - const copyElements = !defaultHideSourceItems; if (!selectionType) { // Have HDAs from the history panel. elements = selection.toJSON(); @@ -82,7 +81,7 @@ function createCollectionViaRules(selection, defaultHideSourceItems = true) { ftpUploadSite: selection.ftpUploadSite, defaultHideSourceItems: defaultHideSourceItems, creationFn: function (elements, collectionType, name, hideSourceItems) { - return selection.createHDCA(elements, collectionType, name, hideSourceItems, copyElements); + return selection.createHDCA(elements, collectionType, name, hideSourceItems); }, }); return promise; diff --git a/client/src/components/Grid/GridElements/GridDatasets.vue b/client/src/components/Grid/GridElements/GridDatasets.vue new file mode 100644 index 000000000000..005f5d96ce99 --- /dev/null +++ b/client/src/components/Grid/GridElements/GridDatasets.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/client/src/components/Grid/GridElements/GridOperations.vue b/client/src/components/Grid/GridElements/GridOperations.vue index 8f1fae493d6b..ff85e9832054 100644 --- a/client/src/components/Grid/GridElements/GridOperations.vue +++ b/client/src/components/Grid/GridElements/GridOperations.vue @@ -38,15 +38,16 @@ function hasCondition(conditionHandler: (rowData: RowData, config: GalaxyConfigu data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" - class="ui-link font-weight-bold"> + class="ui-link font-weight-bold text-nowrap"> {{ title }}