From 0293b83cf57ad4bf5d47da30358a4f6ec41d3a82 Mon Sep 17 00:00:00 2001 From: guerler Date: Mon, 7 Feb 2022 19:32:28 -0500 Subject: [PATCH] Remove legacy caching model --- .../DatasetInformation/DatasetError.test.js | 1 - .../DatasetInformation.test.js | 2 +- .../History/CurrentCollection/Panel.vue | 4 - client/src/components/History/History.vue | 4 - .../DisplayApplications.test.js | 1 - .../CollectionContentProvider.js | 39 - .../CollectionContentProvider.test.js | 160 - .../collectionPayload.js | 77 - .../CollectionContentProvider/index.js | 18 - .../watchCollection.js | 38 - .../watchCollection.test.js | 125 - .../ContentProvider/ContentProvider.js | 119 - .../ContentProvider/aggregateCacheUpdates.js | 109 - .../History/ContentProvider/aggregation.js | 158 - .../ContentProvider/aggregation.test.js | 283 -- .../History/ContentProvider/helpers.js | 27 - .../History/ContentProvider/index.js | 18 - .../ContentProvider/processContentStreams.js | 70 - .../History/DscProvider/DscProvider.js | 95 - .../History/DscProvider/DscProvider.test.js | 131 - .../providers/History/DscProvider/index.js | 3 - .../HistoryContentProvider.js | 34 - .../HistoryContentProvider.test.js | 161 - .../__mocks__/loadContents.js | 34 - .../HistoryContentProvider/contentPayload.js | 321 -- .../contentPayload.test.js | 154 - .../History/HistoryContentProvider/index.js | 3 - .../HistoryContentProvider/loadContents.js | 57 - .../History/HistoryContentProvider/readme.md | 73 - .../watchHistoryContents.js | 37 - .../watchHistoryContents.test.js | 211 -- .../providers/History/SearchParams.js | 228 -- .../providers/History/SearchParams.test.js | 376 --- .../UserHistories/UserHistories.test.js | 1 - .../src/components/providers/History/index.js | 13 - .../providers/History/test/json/History.json | 23 - .../History/test/json/collectionContent.json | 842 ----- .../test/json/collectionContent.nested.json | 30 - .../History/test/json/historyContent.json | 2797 ----------------- .../json/historyContentWithCollection.json | 256 -- .../History/test/providerTestHelpers.js | 43 - .../providers/History/test/testCollection.js | 25 - .../providers/History/test/testHistory.js | 29 - client/src/components/providers/fetch.js | 25 - 44 files changed, 1 insertion(+), 7254 deletions(-) delete mode 100644 client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.js delete mode 100644 client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.test.js delete mode 100644 client/src/components/providers/History/CollectionContentProvider/collectionPayload.js delete mode 100644 client/src/components/providers/History/CollectionContentProvider/index.js delete mode 100644 client/src/components/providers/History/CollectionContentProvider/watchCollection.js delete mode 100644 client/src/components/providers/History/CollectionContentProvider/watchCollection.test.js delete mode 100644 client/src/components/providers/History/ContentProvider/ContentProvider.js delete mode 100644 client/src/components/providers/History/ContentProvider/aggregateCacheUpdates.js delete mode 100644 client/src/components/providers/History/ContentProvider/aggregation.js delete mode 100644 client/src/components/providers/History/ContentProvider/aggregation.test.js delete mode 100644 client/src/components/providers/History/ContentProvider/helpers.js delete mode 100644 client/src/components/providers/History/ContentProvider/index.js delete mode 100644 client/src/components/providers/History/ContentProvider/processContentStreams.js delete mode 100644 client/src/components/providers/History/DscProvider/DscProvider.js delete mode 100644 client/src/components/providers/History/DscProvider/DscProvider.test.js delete mode 100644 client/src/components/providers/History/DscProvider/index.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.test.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/__mocks__/loadContents.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/contentPayload.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/contentPayload.test.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/index.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/loadContents.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/readme.md delete mode 100644 client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.js delete mode 100644 client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.test.js delete mode 100644 client/src/components/providers/History/SearchParams.js delete mode 100644 client/src/components/providers/History/SearchParams.test.js delete mode 100644 client/src/components/providers/History/test/json/History.json delete mode 100644 client/src/components/providers/History/test/json/collectionContent.json delete mode 100644 client/src/components/providers/History/test/json/collectionContent.nested.json delete mode 100644 client/src/components/providers/History/test/json/historyContent.json delete mode 100644 client/src/components/providers/History/test/json/historyContentWithCollection.json delete mode 100644 client/src/components/providers/History/test/providerTestHelpers.js delete mode 100644 client/src/components/providers/History/test/testCollection.js delete mode 100644 client/src/components/providers/History/test/testHistory.js delete mode 100644 client/src/components/providers/fetch.js diff --git a/client/src/components/DatasetInformation/DatasetError.test.js b/client/src/components/DatasetInformation/DatasetError.test.js index 1d1ccfa44f3..39c8b513a29 100644 --- a/client/src/components/DatasetInformation/DatasetError.test.js +++ b/client/src/components/DatasetInformation/DatasetError.test.js @@ -29,7 +29,6 @@ function buildWrapper(has_duplicate_inputs = true, has_empty_inputs = true, user result: { has_duplicate_inputs: has_duplicate_inputs, has_empty_inputs: has_empty_inputs }, }), DatasetProvider: MockProvider({ - resultLabel: "item", result: { id: "dataset_id", creating_job: "creating_job" }, }), FontAwesomeIcon: false, diff --git a/client/src/components/DatasetInformation/DatasetInformation.test.js b/client/src/components/DatasetInformation/DatasetInformation.test.js index 27f1b23b845..192c9390a06 100644 --- a/client/src/components/DatasetInformation/DatasetInformation.test.js +++ b/client/src/components/DatasetInformation/DatasetInformation.test.js @@ -13,7 +13,7 @@ const mockDatasetProvider = { render() { return this.$scopedSlots.default({ loading: false, - item: datasetResponse, + result: datasetResponse, }); }, }; diff --git a/client/src/components/History/CurrentCollection/Panel.vue b/client/src/components/History/CurrentCollection/Panel.vue index 77259f3484a..fc64db7143c 100644 --- a/client/src/components/History/CurrentCollection/Panel.vue +++ b/client/src/components/History/CurrentCollection/Panel.vue @@ -58,13 +58,9 @@ import CollectionOperations from "./CollectionOperations.vue"; import Details from "./Details"; import { CollectionContentItem } from "../ContentItem"; import HistoryListing from "components/History/HistoryListing"; -import { reportPayload } from "components/providers/History/ContentProvider/helpers"; import { UrlDataProvider } from "components/providers/UrlDataProvider"; export default { - filters: { - reportPayload, - }, components: { UrlDataProvider, Layout, diff --git a/client/src/components/History/History.vue b/client/src/components/History/History.vue index 4bea1ef5a55..0553b98a763 100644 --- a/client/src/components/History/History.vue +++ b/client/src/components/History/History.vue @@ -96,15 +96,11 @@ import HistoryDetails from "./HistoryDetails"; import HistoryEmpty from "./HistoryEmpty"; import ContentOperations from "./ContentOperations"; import ToolHelpModal from "./ToolHelpModal"; -import { reportPayload } from "components/providers/History/ContentProvider/helpers"; import HistoryMenu from "./HistoryMenu"; import HistoryListing from "./HistoryListing"; import { HistoryContentItem } from "./ContentItem"; export default { - filters: { - reportPayload, - }, components: { LoadingSpan, UrlDataProvider, diff --git a/client/src/components/Visualizations/DisplayApplications.test.js b/client/src/components/Visualizations/DisplayApplications.test.js index 045a9dd67a4..1cafa13934a 100644 --- a/client/src/components/Visualizations/DisplayApplications.test.js +++ b/client/src/components/Visualizations/DisplayApplications.test.js @@ -44,7 +44,6 @@ describe("DisplayApplications", () => { }, ], }, - resultLabel: "item", }), }, localVue, diff --git a/client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.js b/client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.js deleted file mode 100644 index 4e0c94f1e75..00000000000 --- a/client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.js +++ /dev/null @@ -1,39 +0,0 @@ -import { DatasetCollection } from "components/History/model/DatasetCollection"; -import { SearchParams } from "components/providers/History/SearchParams"; -import { ContentProvider, processContentStreams } from "../ContentProvider"; -import { collectionPayload } from "./collectionPayload"; - -export default { - mixins: [ContentProvider], - - props: { - params: { type: SearchParams, default: () => new SearchParams({ showHidden: false }) }, - }, - - computed: { - dsc() { - if (this.parent instanceof DatasetCollection) { - return this.parent; - } - return new DatasetCollection(this.parent); - }, - }, - - watch: { - dsc(newDsc, oldDsc) { - if (!(newDsc.id == oldDsc.id)) { - this.resetScrollPos(); - } - }, - }, - - methods: { - initStreams() { - const { debouncePeriod, pageSize, params$, scrollPos$, debug } = this; - const parent$ = this.watch$("dsc", true); - const sources = { params$, parent$, scrollPos$ }; - const settings = { debouncePeriod, pageSize, debug }; - return processContentStreams(collectionPayload, sources, settings); - }, - }, -}; diff --git a/client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.test.js b/client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.test.js deleted file mode 100644 index a59c41d2b23..00000000000 --- a/client/src/components/providers/History/CollectionContentProvider/CollectionContentProvider.test.js +++ /dev/null @@ -1,160 +0,0 @@ -import { map } from "rxjs/operators"; -import { watchUntil, getLocalVue } from "jest/helpers"; -import { shallowMount } from "@vue/test-utils"; -import { - cacheContent, - cacheCollectionContent, - wipeDatabase, - loadDscContent, -} from "components/providers/History/caching"; -import { bulkCacheDscContent } from "components/providers/History/caching/db/observables"; -import { summarizeCacheOperation } from "components/providers/History/caching/loadHistoryContents"; -import { SearchParams } from "components/providers/History/SearchParams"; -import CollectionContentProvider from "./CollectionContentProvider"; -import { sameVueObj, payloadChange } from "components/providers/History/test/providerTestHelpers"; -import { testCollection, testCollectionContent } from "components/providers/History/test/testCollection"; -import { defaultPayload } from "../ContentProvider"; - -// mocking -jest.mock("app"); -jest.mock("components/providers/History/caching"); - -// fake server call -// prettier-ignore -loadDscContent.mockImplementation((cfg) => (inputs$) => { - return inputs$.pipe( - map((inputs) => { - const [url, , pagination] = inputs; - const { offset, limit } = pagination; - // console.log("mock loader", url, pagination); - const result = testCollectionContent - .filter((row) => url == row.parent_url) - .slice(offset, offset + limit); - return result; - }), - bulkCacheDscContent(), - summarizeCacheOperation() - ); -}); - -let dsc; -const localVue = getLocalVue(); - -beforeEach(async () => { - dsc = await cacheContent(testCollection, true); -}); - -afterEach(async () => { - dsc = null; - await wipeDatabase(); -}); - -describe("CollectionContentProvider", () => { - const pageSize = 5; - const debouncePeriod = 250; - let wrapper; - - afterEach(async () => { - if (wrapper) { - wrapper.destroy(); - } - wrapper = undefined; - }); - - describe("blank initialization state", () => { - // current payload - beforeEach(async () => { - wrapper = await shallowMount(CollectionContentProvider, { - localVue, - propsData: { - parent: dsc, - pageSize, - debug: false, - debouncePeriod, - }, - scopedSlots: { - default() {}, - }, - }); - await wrapper.vm.$nextTick(); - }); - - test("should expose update methods", () => { - // allows child scroller component to update the position in the history - // via an event handler - expect(wrapper.vm.setScrollPos).toBeInstanceOf(Function); - }); - - test("should show an empty payload", () => { - expect(SearchParams.equals(new SearchParams(), wrapper.vm.params)).toBe(true); - expect(sameVueObj(wrapper.vm.payload, defaultPayload)); - }); - }); - - describe("waiting for simulated server loads", () => { - beforeEach(async () => { - wrapper = await shallowMount(CollectionContentProvider, { - localVue, - propsData: { - parent: dsc, - pageSize, - debug: false, - debouncePeriod, - }, - scopedSlots: { - default: function (props) { - // reportPayload(props.payload, { indexKey: "element_index" }); - // payload = props.payload; - }, - }, - }); - - // eslint-disable-next-line no-unused-vars - const spinUp = await watchUntil(wrapper.vm, function () { - const allDone = wrapper.vm.payload.contents.length > 0; - // console.log("done?", allDone); - return allDone; - }); - - // console.log(spinUp); - }); - - test("initial load, no scrolling", async () => { - const payload = wrapper.vm.payload; - expect(payload).toBeDefined(); - // reportPayload(payload, { indexKey: "element_index" }); - // reportPayload(initialPayload, { indexKey: "element_index" }); - const { contents, topRows, bottomRows, startKey, totalMatches } = payload; - expect(topRows).toEqual(0); - expect(contents.length).toBeGreaterThanOrEqual(2 * wrapper.vm.pageSize); - expect(totalMatches).toEqual(testCollectionContent.length); - expect(bottomRows).toBeGreaterThan(0); - expect(bottomRows).toEqual(testCollectionContent.length - contents.length); - - const testStartIndex = testCollectionContent[0].element_index; - expect(startKey).toEqual(testStartIndex); - }); - - test("should update to reflect independent cache changes", async () => { - let hasFoobar; - const payload = wrapper.vm.payload; - - // check initial emit, for foobars - expect(payload).toBeDefined(); - hasFoobar = payload.contents.some((o) => o.foobar == 123); - expect(hasFoobar).toBeFalsy(); - - // add a foobar - const testChild = payload.contents[0]; - testChild.foobar = 123; - const updateResult = await cacheCollectionContent(testChild, true); - expect(updateResult.foobar).toEqual(123); - - // check subsequent payload for a foobar - const updatedPayload = await payloadChange({ vm: wrapper.vm }); - // reportPayload(updatedPayload, { label: "updated", indexKey: "element_index" }); - hasFoobar = updatedPayload.contents.some((o) => o.foobar == 123); - expect(hasFoobar).toBeTruthy(); - }); - }); -}); diff --git a/client/src/components/providers/History/CollectionContentProvider/collectionPayload.js b/client/src/components/providers/History/CollectionContentProvider/collectionPayload.js deleted file mode 100644 index b2e56de0860..00000000000 --- a/client/src/components/providers/History/CollectionContentProvider/collectionPayload.js +++ /dev/null @@ -1,77 +0,0 @@ -import { of, Observable, Subject, partition, merge } from "rxjs"; -import { tap, map, pluck, switchMap, publish, distinctUntilChanged, share, throttleTime } from "rxjs/operators"; -import { chunk } from "utils/observable"; -import { SearchParams } from "components/providers/History/SearchParams"; -import { loadDscContent } from "components/providers/History/caching"; -import { watchCollection } from "./watchCollection"; - -// prettier-ignore -export const collectionPayload = (cfg = {}) => { - const { - parent: dsc, - filters = new SearchParams(), - pageSize = SearchParams.pageSize, - debug = false, - loadingEvents$ = new Subject(), - debouncePeriod = 100, - chunkSize = pageSize - } = cfg; - - const { totalElements: totalMatches, contents_url } = dsc; - - return publish((pos$) => { - - // split scroll position into objects where we exactly know which key to focus on, and those - // where we have to figure out where to start - const [ noKey$, hasKey$ ] = partition(pos$, (pos) => pos.key === null); - - // if we don't know the exact elementIndex we need to calculate it from the cursor (portion - // of the total scroller height) and the total matches which we should have from the dsc props - const calculatedIndex$ = noKey$.pipe( - pluck('cursor'), - map((cursor) => Math.round(cursor * totalMatches)), - ); - const knownIndex$ = hasKey$.pipe(pluck('key')); - const elementIndex$ = merge(knownIndex$, calculatedIndex$).pipe(share()); - - // chunk the input to the server request so we don't request for every single mouse move - const chunked$ = elementIndex$.pipe( - chunk(chunkSize), - distinctUntilChanged(), - ); - - // overlap one page before and one page after, 3 total pages queried - const pagination$ = chunked$.pipe( - map(targetRow => { - const offset = Math.max(0, targetRow - pageSize); - const limit = 3 * pageSize; - return { offset, limit, targetRow }; - }), - ); - - const serverLoad$ = pagination$.pipe( - throttleTime(debouncePeriod, undefined, { trailing: true }), - switchMap(pagination => of([contents_url, filters, pagination]).pipe( - tap(() => loadingEvents$.next(true)), - loadDscContent({ debug }), - tap(() => loadingEvents$.next(false)), - )), - ); - - const payload$ = elementIndex$.pipe( - watchCollection({ dsc, filters, ...cfg}), - map((result) => { - const { contents } = result; - const topRows = contents.length ? contents[0].element_index : 0; - const bottomRows = Math.max(0, totalMatches - contents.length - topRows); - return { ...result, topRows, bottomRows, totalMatches }; - }), - ); - - return new Observable((obs) => { - const watchSub = payload$.subscribe(obs); - watchSub.add(serverLoad$.subscribe()); - return watchSub; - }); - }) -}; diff --git a/client/src/components/providers/History/CollectionContentProvider/index.js b/client/src/components/providers/History/CollectionContentProvider/index.js deleted file mode 100644 index 2f49418948b..00000000000 --- a/client/src/components/providers/History/CollectionContentProvider/index.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Same basic format as historyContentProvider, but it should be simpler than - * the history because: - * - * 1. Collections are immutable after creation so they don't change over time, - * meaning there is no polling and no need to do "random access" as we do for - * histories since we can just limit/offset to reach everything since the - * total matches count will always be the same. A "total matches" exists in - * the basic content record in the form of "element_count", and we already - * have that value in the DSC which is passed in. - * - * 2. There is no filtering for collections on the server so all we can do is - * page through the results - */ - -import CollectionContentProvider from "./CollectionContentProvider"; - -export default CollectionContentProvider; diff --git a/client/src/components/providers/History/CollectionContentProvider/watchCollection.js b/client/src/components/providers/History/CollectionContentProvider/watchCollection.js deleted file mode 100644 index 2d024c61819..00000000000 --- a/client/src/components/providers/History/CollectionContentProvider/watchCollection.js +++ /dev/null @@ -1,38 +0,0 @@ -import { of } from "rxjs"; -import { map } from "rxjs/operators"; -import { aggregateCacheUpdates } from "../ContentProvider"; -import { monitorCollectionContent } from "components/providers/History/caching"; -import { SEEK } from "components/providers/History/caching/enums"; -import { SearchParams } from "components/providers/History/SearchParams"; -// import { show } from "utils/observable"; - -// prettier-ignore -export const watchCollection = (cfg = {}) => elementIndex$ => { - const { - dsc, - filters = new SearchParams(), - pageSize = SearchParams.pageSize, - debug = false, - keyField = "element_index", - keyDirection = SEEK.ASC, - ...otherConfig - } = cfg; - - // builds a monitor observable based on a element_index - const monitor = (idx) => of([dsc.contents_url, filters, idx]).pipe( - monitorCollectionContent({ pageSize, debug: false, keyField }), - ); - - // handles the plumbing for observing the query (monitor) and collecting the output into an - // aggregate ordered list focused around the current target key (element_index in this case) - return elementIndex$.pipe( - map(val => parseInt(val)), - aggregateCacheUpdates(monitor, { - keyField, - keyDirection, - pageSize, - debug, - ...otherConfig, - }), - ); -}; diff --git a/client/src/components/providers/History/CollectionContentProvider/watchCollection.test.js b/client/src/components/providers/History/CollectionContentProvider/watchCollection.test.js deleted file mode 100644 index 55f7307ce58..00000000000 --- a/client/src/components/providers/History/CollectionContentProvider/watchCollection.test.js +++ /dev/null @@ -1,125 +0,0 @@ -import { of, timer } from "rxjs"; -import { takeUntil, share } from "rxjs/operators"; -import { ObserverSpy } from "@hirez_io/observer-spy"; -import { watchCollection } from "./watchCollection"; -import { cacheCollectionContent, bulkCacheDscContent, wipeDatabase } from "components/providers/History/caching"; -import { testCollectionContent, testCollection } from "components/providers/History/test/testCollection"; -import { untilNthEmission } from "jest/helpers"; - -// need to mock monitorHistoryContent which is instantiated inside the worker, -// but we can't actually fire up threads.js in a unit test because you can't -// call expose() on the main thread, so we mock the adapter functions which -// generate observables from the worker. -jest.mock("app"); -jest.mock("components/providers/History/caching"); - -const debouncePeriod = 250; -const safetyTimeout = 1000; -const pageSize = 5; -const pluckAll = (arr, prop) => arr.map((o) => o[prop]); - -let cachedCollectionContent; - -beforeEach(async () => { - await wipeDatabase(); - cachedCollectionContent = await bulkCacheDscContent(testCollectionContent, true); - // const cachedIds = pluckAll(cachedCollectionContent, "_id"); - // console.log(cachedIds); -}); - -afterEach(async () => { - await wipeDatabase(); -}); - -describe("watchCollection", () => { - test("should observe pre-inserted content on the initial emission", async () => { - // the srource stream for the operator is an element_index - const watcher$ = of(0).pipe( - watchCollection({ - dsc: testCollection, - pageSize, - debouncePeriod, - debug: false, - }), - takeUntil(timer(safetyTimeout)) - ); - - // spy on output of observable, wait for it to end - const spy = new ObserverSpy(); - watcher$.subscribe(spy); - await spy.onComplete(); - - expect(spy.receivedNext()).toBe(true); - expect(spy.receivedComplete()).toBe(true); - expect(spy.getValuesLength()).toBe(1); - - const payload = spy.getFirstValue(); - { - const { startKey, startKeyIndex, targetKey, contents } = payload; - - // at the top of the list, should get the match (element_index = 0) + 2 pages - expect(startKey).toEqual(0); - expect(startKeyIndex).toEqual(0); - expect(targetKey).toEqual(0); - expect(Array.isArray(contents)).toBe(true); - - // should get back the exact match (element_index = 0, the following page, + 1 - // additional page of buffer-room after the current page - const returnedIndexes = pluckAll(contents, "element_index"); - // console.log(returnedIndexes); - - expect(contents.length).toBeGreaterThanOrEqual(2 * pageSize); - expect(returnedIndexes).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - } - }); - - test("should observe subsequent updates", async () => { - // the srource stream for the operator is an element_index - const watcher$ = of(0).pipe( - watchCollection({ - dsc: testCollection, - debouncePeriod, - pageSize, - }), - takeUntil(timer(safetyTimeout)), - share() - ); - - const spy = new ObserverSpy(); - watcher$.subscribe(spy); - - // After the first event, change some stuff on the first row - // need to delay a little to wait for first emissions to run through - // otherwise the debouncing will think the 2nd update is the same as the - await untilNthEmission(watcher$, 1); - const testChild = cachedCollectionContent[0]; - testChild.foobar = 123; - const updateResult = await cacheCollectionContent(testChild, true); - // console.log("after update", updateResult); - expect(updateResult.foobar).toEqual(123); - expect(updateResult._rev).not.toEqual(testCollection._rev); - - await spy.onComplete(); - expect(spy.receivedNext()).toBe(true); - expect(spy.receivedComplete()).toBe(true); - expect(spy.getValuesLength()).toEqual(2); - - const firstPayload = spy.getFirstValue(); - { - const { contents } = firstPayload; - expect(Array.isArray(contents)).toBe(true); - // no foobar because this happened before the update - const foobars = pluckAll(contents, "foobar"); - expect(foobars.every((val) => val === undefined)).toBe(true); - } - - const lastPayload = spy.getLastValue(); - { - const { contents } = lastPayload; - expect(Array.isArray(contents)).toBe(true); - // should have a foobar - const foobars = pluckAll(contents, "foobar"); - expect(foobars.every((val) => val === undefined)).toBe(false); - } - }); -}); diff --git a/client/src/components/providers/History/ContentProvider/ContentProvider.js b/client/src/components/providers/History/ContentProvider/ContentProvider.js deleted file mode 100644 index 6e5ed121902..00000000000 --- a/client/src/components/providers/History/ContentProvider/ContentProvider.js +++ /dev/null @@ -1,119 +0,0 @@ -import { NEVER } from "rxjs"; -import { ScrollPos } from "components/History/model/ScrollPos"; -import { SearchParams } from "components/providers/History/SearchParams"; -import { isValidNumber } from "utils/validation"; - -// first emission, emitted when parent (history) or filters changes to reset the view -export const defaultPayload = { - contents: [], - targetKey: null, - startKey: null, - startKeyIndex: 0, - topRows: 0, - bottomRows: 0, - totalMatches: 0, -}; - -export const ContentProvider = { - props: { - parent: { type: Object, required: true }, - params: { type: SearchParams, default: () => new SearchParams() }, - pageSize: { type: Number, default: SearchParams.pageSize }, - debouncePeriod: { type: Number, default: 1000 }, - debug: { type: Boolean, default: false }, - }, - - computed: { - busy() { - return this.loading || this.scrolling; - }, - slotProps() { - return { - // actual content delivery - payload: this.payload, - - // local vars/settings/props passthrough - scrollPos: this.scrollPos, - loading: this.loading, - scrolling: this.scrolling, - busy: this.busy, - params: this.params, - pageSize: this.pageSize, - - // update methods - setScrollPos: this.setScrollPos, - }; - }, - }, - - data() { - return { - payload: defaultPayload, - scrollPos: new ScrollPos(), - loading: false, - scrolling: false, - }; - }, - - watch: { - params(newParams, oldParams) { - if (!SearchParams.equals(newParams, oldParams)) { - this.resetScrollPos(); - } - }, - }, - - created() { - this.params$ = this.watch$("params"); - this.scrollPos$ = this.watch$("scrollPos"); - const { payload$, loading$, scrolling$ } = this.initStreams(); - - this.listenTo(scrolling$, (val) => (this.scrolling = val)); - this.listenTo(loading$, (val) => (this.loading = val)); - - // render output - this.listenTo(payload$, { - next: (payload) => this.setPayload(payload), - error: (err) => console.warn("error in cache$", err), - complete: () => console.warn("why did cache$ complete?"), - }); - }, - - methods: { - resetScrollPos() { - this.setScrollPos(); - }, - - initStreams() { - console.warn("Override initStreams in ContentProvider"); - return { payload$: NEVER, loading$: NEVER, scrolling$: NEVER, resetPos$: NEVER }; - }, - - /** - * Handler for the scroller to update its position, either by key or - * cursor (0-1 value representing how far down it is) - * @param {object} Object consisting of key and cursor props - */ - setScrollPos({ cursor = null, key = null } = {}) { - if (isValidNumber(cursor) || key !== null) { - this.scrollPos = ScrollPos.create({ cursor, key }); - } - }, - - /** - * Render cache observable results to the payload property. It's best to - * set everything at once to avoid multiple render passes. - * @param {object} result Cache observable response - */ - setPayload(props = {}) { - const payload = Object.assign({}, defaultPayload, props); - this.$set(this, "payload", payload); - }, - }, - - render() { - return this.$scopedSlots.default(this.slotProps); - }, -}; - -export default ContentProvider; diff --git a/client/src/components/providers/History/ContentProvider/aggregateCacheUpdates.js b/client/src/components/providers/History/ContentProvider/aggregateCacheUpdates.js deleted file mode 100644 index eae7be69a01..00000000000 --- a/client/src/components/providers/History/ContentProvider/aggregateCacheUpdates.js +++ /dev/null @@ -1,109 +0,0 @@ -// Generalized bi-directional watch and aggregator. -// Looks at cache from starting index, then looks up and down - -import { throwError, from, EMPTY } from "rxjs"; -import { - map, - debounceTime, - distinctUntilChanged, - groupBy, - reduce, - mergeMap, - switchMap, - withLatestFrom, - timeoutWith, - ignoreElements, -} from "rxjs/operators"; -import { show, debounceBurst, shareButDie } from "utils/observable"; -import { SearchParams } from "components/providers/History/SearchParams"; -import { processContentUpdate, newUpdateMap, buildContentResult, getKeyForUpdateMap } from "./aggregation"; -import { SEEK } from "components/providers/History/caching/enums"; -import { reportPayload } from "./helpers"; - -// prettier-ignore -export const aggregateCacheUpdates = (monitor, cfg = {}) => (src$) => { - // monitor is a function that generates the update observable - if (!(monitor instanceof Function)) { - return throwError("monitor should be a function in aggregateCacheUpdates"); - } - - const { - // number of rows we roughly expect to be in the window - pageSize = SearchParams.pageSize, - - // input and output throttling - debouncePeriod = 250, - - // field and key order for the contents - keyField = "hid", - keyDirection = SEEK.DESC, - - // reduces duplicate updates to the skiplist - // which can be expensive - updateGroupLifetime = 2 * debouncePeriod, - - debug = false, - } = cfg; - - // function that extracts the key from a document - const getKey = getKeyForUpdateMap(keyField); - - // incoming target key - const targetKey$ = src$.pipe(shareButDie(1)); - - // avoids creating a new monitor for every single key emission - // chunk to ceiling if descending, floor if ascending - const monitorInputKey$ = targetKey$.pipe( - distinctUntilChanged(), - show(debug, (key) => console.log("monitorInputKey", key)), - ); - - // incoming stream of cache updates - // Monitor generation function is passed in via config so we can use it against different types of queries - const cacheUpdates$ = monitorInputKey$.pipe( - switchMap(monitor), - show(debug, (change) => console.log("monitor output", change)), - ); - - // groups updates by skiplist key and debounces those - // streams individually so we're not pointlessly updating - // when we're just going to change it again shortly - const groupedUpdates$ = cacheUpdates$.pipe( - groupBy( - update => update.key, - update => update, - updateByKey$ => updateByKey$.pipe( - timeoutWith(updateGroupLifetime, EMPTY), - ignoreElements() - ) - ), - // eliminates rapid double updates to same item - mergeMap(updateByKey$ => updateByKey$.pipe( - debounceTime(0.25 * debouncePeriod), - )), - debounceBurst(debouncePeriod), - show(debug, changeBurst => console.log('burst', changeBurst.map(o => o.key))), - ); - - // aggregates changes into a skiplist. - const storage = newUpdateMap(); - const currentMap$ = groupedUpdates$.pipe( - mergeMap(updateList => from(updateList).pipe( - reduce(processContentUpdate, storage) - )), - show(debug, () => console.log('grouped update burst done')), - ); - - const contentListInputs$ = currentMap$.pipe( - withLatestFrom(targetKey$), - ); - - // query skiplist with scroll position (transformed into a key from the skiplist) - // to produce list of nearby content - const contentList$ = contentListInputs$.pipe( - map(buildContentResult({ pageSize, keyDirection, getKey })), - show(debug, payload => reportPayload(payload, { indexKey: keyField, label: "aggregateCacheUpdates payload" })), - ); - - return contentList$; -}; diff --git a/client/src/components/providers/History/ContentProvider/aggregation.js b/client/src/components/providers/History/ContentProvider/aggregation.js deleted file mode 100644 index 40e17f342be..00000000000 --- a/client/src/components/providers/History/ContentProvider/aggregation.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Functions for aggregating incoming cache updates for presentation to the - * scroller. As cache changes roll in, the updates are summarized and sorted in - * a SkipList for fast, ordered retrieval. - * - * TODO: PouchDB has similar aggregation capabilities but when last I looked they - * were too difficult to get working properly with dynamically changing queries. - * I feel like this is the duty of the caching layer, however, and we should - * investigate again. - */ - -import SkipList from "proper-skip-list"; -import { pipe, take, filter } from "iter-tools"; -import { SEEK } from "components/providers/History/caching/enums"; -import { SearchParams } from "components/providers/History/SearchParams"; - -// utils for buildContentResult -const distance = (a, b) => Math.abs(+a - +b); - -export const buildContentResult = (cfg = {}) => { - const { keyDirection = SEEK.ASC, pageSize = SearchParams.pageSize } = cfg; - - if (!SEEK.isValid(keyDirection)) { - throw new Error(`buildContentResult: invalid sort direction: ${keyDirection}`); - } - - return ([updateMap, targetKey]) => { - // console.log("buildContentResult", updateMap, rawTargetKey, typeof targetKey); - - if (updateMap === undefined) { - throw new Error("missing skiplist"); - } - if (targetKey === undefined) { - throw new Error("missing target key"); - } - // make sure key is an int - if (!Number.isFinite(targetKey)) { - console.warn("Target key should be numeric", updateMap, targetKey); - throw new Error("buildContentResult: targetKey must be a numeric value", targetKey); - } - - const { matchingValue, desc, asc } = updateMap.findEntries(targetKey); - - // We want 3 whole pages, 1 behind us, the one we're on, and 1 ahead of us, this means - // we have to figure out what "behind" and "in front" mean based on the key direction - - // if the keys are ascending, "down" the list is the asc iterator - // if the keys are ascending, "up" the list is the desc iterator - - const isAscending = keyDirection == SEEK.ASC; - const topIterator = isAscending ? desc : asc; - const bottomIterator = isAscending ? asc : desc; - - const topFilter = pipe( - filter(([k]) => (isAscending ? k < targetKey : k > targetKey)), - take(pageSize) - ); - - const bottomFilter = pipe( - filter(([k]) => (isAscending ? k > targetKey : k < targetKey)), - take(2 * pageSize) - ); - - const top = Array.from(topFilter(topIterator)); - const bottom = Array.from(bottomFilter(bottomIterator)); - - // assemble contents array by combining the results - const match = matchingValue ? [[targetKey, matchingValue]] : []; - const contentEntries = [...top.reverse(), ...match, ...bottom]; - - // startKey is the closest key in the result set to the requested targetKey - const { startKey, startKeyIndex } = findClosestEntry(targetKey, contentEntries); - - const contents = contentEntries.map(([k, v]) => v); - - return { - // list of contents from the skiplist around the targetKey - contents, - - // original value used to query the skiplist, should be in - // the middle of the contents list - targetKey, - - // closest key to the targetKey that actually exists in the slice - startKey, - - // index of the closest row matching the targetKey, also should - // be in the middle of the contents - startKeyIndex, - }; - }; -}; - -/** - * Finds closest of keys by measuring numeric distance from targetKey - * - * @param {String|Number} targetKey Key to match - * @param {String|Number} entries content entries from the map i.e. list of [key,val] - * - * @return {Object} startKey, startKeyIndex - */ -const findClosestEntry = (targetKey, entries = []) => { - const startingVal = { startKey: null, startKeyIndex: -1, distance: Infinity }; - return entries - .filter((entry) => Array.isArray(entry)) - .reduce((result, entry, idx) => { - const [key] = entry; - const myDistance = distance(targetKey, key); - return myDistance < result.distance ? { startKey: key, startKeyIndex: idx, distance: myDistance } : result; - }, startingVal); -}; - -/** - * Fresh update map, gets built when inputs change - */ -export const newUpdateMap = () => { - return new SkipList(); -}; - -/** - * Generates a scan function for consuming updates from the pouchdb-live-find. - * Adds or removes incoming docs from the skiplist - */ -export const processContentUpdate = (resultMap, update) => { - const { doc, key, match } = update; - - // make sure key is an int - const storageKey = parseInt(key); - - if (match) { - resultMap.upsert(storageKey, doc); - } else if (resultMap.has(storageKey)) { - resultMap.delete(storageKey); - } - - return resultMap; -}; - -// Configurable function returns a key for the updateMap from a doc during upate operations -// aggregate results in a map for each set of id + params -export const getKeyForUpdateMap = (keyField) => (doc) => { - let rawKey; - if (keyField in doc) { - rawKey = doc[keyField]; - } else { - // won't have a full doc on a delete, but it's embeedded in the id - const parts = doc._id.split("-"); - rawKey = parseInt(parts[1]); - } - - const result = parseInt(rawKey); - if (isNaN(result)) { - console.warn("Non integer key for document", doc); - throw new Error("Key for update map should be an integer"); - } - - return result; -}; diff --git a/client/src/components/providers/History/ContentProvider/aggregation.test.js b/client/src/components/providers/History/ContentProvider/aggregation.test.js deleted file mode 100644 index a0788a9d7ab..00000000000 --- a/client/src/components/providers/History/ContentProvider/aggregation.test.js +++ /dev/null @@ -1,283 +0,0 @@ -import SkipList from "proper-skip-list"; -import { buildContentResult } from "./aggregation"; -import { SEEK } from "components/providers/History/caching/enums"; - -jest.mock("app"); -jest.mock("components/providers/History/caching"); - -describe("buildContentResult", () => { - describe("query history content from aggregate storage", () => { - const updateList = new SkipList(); - - // history content is keyed by hid, descending order - const keyDirection = SEEK.DESC; - const getKey = (item) => item.hid; - const pageSize = 2; - - // sample content, indexed by hid - const hids = [100, 95, 61, 60, 50, 44, 41, 17, 1].sort(); - hids.forEach((hid) => updateList.upsert(hid, { hid })); - - test("query key exists, query key in middle", () => { - const queryKey = 60; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - // returns the key we used to query the skiplist - expect(targetKey).toEqual(queryKey); - - // the closest key to targetKey in the event that targetKey does not exist - expect(startKey).toEqual(queryKey); - - // the array index of startKey - expect(startKeyIndex).toEqual(2); - - // pageSize causes aggregation to back up one page from start of list, then delivers - // the previous page, the exact match, then 2 pages after the match - const resultKeys = contents.map(getKey); - expect(resultKeys.length).toBeLessThanOrEqual(3 * pageSize + 1); - expect(resultKeys).toEqual([95, 61, 60, 50, 44, 41, 17]); - }); - - test("query key exists, query key at top", () => { - const queryKey = 100; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(queryKey); - expect(startKeyIndex).toEqual(0); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - // match (top) + 2 pages after - expect(resultKeys).toEqual([100, 95, 61, 60, 50]); - }); - - test("query key exists, query key at bottom", () => { - const queryKey = 1; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(queryKey); - expect(startKeyIndex).toEqual(2); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([41, 17, 1]); - }); - - test("query key doesn't exist, query key in middle", () => { - const queryKey = 51; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(50); - expect(startKeyIndex).toEqual(2); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([61, 60, 50, 44, 41, 17]); - }); - - test("query key doesn't exist, query key near top", () => { - const queryKey = 99; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(100); - expect(startKeyIndex).toEqual(0); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([100, 95, 61, 60, 50]); - }); - - test("query key doesn't exist, query key near bottom", () => { - const queryKey = 16; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(17); - expect(startKeyIndex).toEqual(1); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([41, 17, 1]); - }); - - test("query key beyond upper limit", () => { - const queryKey = 200; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(100); - expect(startKeyIndex).toEqual(0); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([100, 95, 61, 60]); - }); - - test("query key below lower limit", () => { - const queryKey = -300; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(1); - expect(startKeyIndex).toEqual(1); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([17, 1]); - }); - }); - - describe("query collection content from aggregate storage", () => { - const updateList = new SkipList(); - - // collection content is keyed by element_index, ascending order - const keyDirection = SEEK.ASC; - const getKey = (item) => item.element_index; - const pageSize = 2; - - // sample content, indexed by hid - const element_indexes = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - element_indexes.forEach((i) => updateList.upsert(i, { element_index: i })); - - test("query key exists, query key in middle", () => { - const queryKey = 5; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(queryKey); - expect(startKeyIndex).toEqual(2); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([3, 4, 5, 6, 7, 8, 9]); - }); - - test("query key exists, query key at top", () => { - const queryKey = 1; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(queryKey); - expect(startKeyIndex).toEqual(0); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([1, 2, 3, 4, 5]); - }); - - test("query key exists, query key at bottom", () => { - const queryKey = 9; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(queryKey); - expect(startKeyIndex).toEqual(2); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([7, 8, 9]); - }); - - test("query key doesn't exist, query key in middle", () => { - const queryKey = 4.2; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(4); - expect(startKeyIndex).toEqual(1); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([3, 4, 5, 6, 7, 8]); - }); - - test("query key doesn't exist, query key near top", () => { - const queryKey = 0.8; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(1); - expect(startKeyIndex).toEqual(0); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([1, 2, 3, 4]); - }); - - test("query key doesn't exist, query key near bottom", () => { - const queryKey = 8.1; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(8); - expect(startKeyIndex).toEqual(1); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([7, 8, 9]); - }); - - test("query key beyond upper limit", () => { - const queryKey = -1999; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(1); - expect(startKeyIndex).toEqual(0); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([1, 2, 3, 4]); - }); - - test("query key below lower limit", () => { - const queryKey = 300; - const summarize = buildContentResult({ keyDirection, pageSize, getKey }); - - // choose a hid we know is in the results - const { contents, targetKey, startKey, startKeyIndex } = summarize([updateList, queryKey]); - - expect(startKey).toEqual(9); - expect(startKeyIndex).toEqual(1); - expect(targetKey).toEqual(queryKey); - - const resultKeys = contents.map(getKey); - expect(resultKeys).toEqual([8, 9]); - }); - }); -}); diff --git a/client/src/components/providers/History/ContentProvider/helpers.js b/client/src/components/providers/History/ContentProvider/helpers.js deleted file mode 100644 index 7ec77cd0259..00000000000 --- a/client/src/components/providers/History/ContentProvider/helpers.js +++ /dev/null @@ -1,27 +0,0 @@ -import { SearchParams } from "components/providers/History/SearchParams"; - -// match object props -export const propMatch = (name) => (a, b) => { - return a[name] === b[name]; -}; - -// comparator for distinct() style operators inputs are an array of [id, SearchParams] -export const inputsSame = ([a0, a1], [b0, b1]) => { - return a0 == b0 && SearchParams.equals(a1, b1); -}; - -// inputs + hid/cursor comparison -export const loadInputsSame = ([inputsA, cursorA], [inputsB, cursorB]) => { - return cursorA == cursorB && inputsSame(inputsA, inputsB); -}; - -export const paginationEqual = (a, b) => { - return a.offset == b.offset && a.limit == b.limit; -}; - -// debugging func for looking at abbreviated payload output -export const reportPayload = (p, keyField = "hid") => { - const { contents = [], ...theRest } = p; - const keys = contents.map((o) => o[keyField]); - return { keys, ...theRest }; -}; diff --git a/client/src/components/providers/History/ContentProvider/index.js b/client/src/components/providers/History/ContentProvider/index.js deleted file mode 100644 index ae450991567..00000000000 --- a/client/src/components/providers/History/ContentProvider/index.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * A component mixin and a set of observable utilities used in common by HicstoryContentProvider and - * CollectionContentProvider - */ - -// base component definition for History & Collection content providers -export { ContentProvider, defaultPayload } from "./ContentProvider"; - -// aggreagtion functions collect an initial query and merge in subsequent updates which appear int -// he cache over time to present a unified list of results ordered by a relevant key -export { buildContentResult, newUpdateMap, processContentUpdate, getKeyForUpdateMap } from "./aggregation"; -export { aggregateCacheUpdates } from "./aggregateCacheUpdates"; - -// configurable operators encapsulating shared behavior for content and collections -export { processContentStreams } from "./processContentStreams"; - -// utils -export { paginationEqual } from "./helpers"; diff --git a/client/src/components/providers/History/ContentProvider/processContentStreams.js b/client/src/components/providers/History/ContentProvider/processContentStreams.js deleted file mode 100644 index 72141b0f6cd..00000000000 --- a/client/src/components/providers/History/ContentProvider/processContentStreams.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * General plumbing for the 2 types of content providers. This function returns 3 observables: - * loading, scrolling, and payload. Payload's the most important and the operator that genrates the - * payload from the inputs is passed in as a parameter to this factory. - */ -import { distinctUntilChanged, share, startWith, switchMap } from "rxjs/operators"; -import { activity, whenAny, show } from "utils/observable"; -import { propMatch } from "./helpers"; -import { ScrollPos } from "components/History/model/ScrollPos"; -import { SearchParams } from "components/providers/History/SearchParams"; -import { defaultPayload } from "../ContentProvider"; -import { Subject } from "rxjs"; - -/** - * Takes incoming history, filters and scroll position and generates loading, scrolling and payload - * observable for rendering the content. payload$ is an observable that emits the data that should - * be displaye - * - * @param {function} payloadOperator observable operator that delivers the payload for this list - * @param {object} sources object containing params$, history$, scrollPos$ source observables - * @param {object} settings configuration parameter object - * - * @return {object} payload$, loading$, scrolling$ observables - */ -// prettier-ignore -export function processContentStreams(payloadOperator, sources = {}, settings = {}) { - const { debouncePeriod, debug = false } = settings; - - // clean incoming source streams - const parent$ = sources.parent$.pipe( - distinctUntilChanged(propMatch("id")), - show(debug, (parent) => console.log('processContentStreams: parent changed', parent)), - ); - const params$ = sources.params$.pipe( - distinctUntilChanged(SearchParams.equals), - show(debug, (params) => console.log('processContentStreams: params changed', params)), - ); - const pos$ = sources.scrollPos$.pipe( - show(debug, (pos) => console.log('processContentStreams: pos changed', pos)), - distinctUntilChanged(ScrollPos.equals), - ); - const scrolling$ = sources.scrollPos$.pipe( - activity(200) - ); - - const loadingEvents$ = new Subject(); - const loading$ = loadingEvents$.pipe( - activity(debouncePeriod), - startWith(true) - ); - - const resetPos$ = new Subject(); - - // The actual loader, when history or params change we poll against the api and - // set up a cachewatcher, both of which are controlled by the scroll position - const loaderReset$ = whenAny(parent$, params$); - const payload$ = loaderReset$.pipe( - switchMap(([parent, filters]) => pos$.pipe( - show(debug, pos => { - console.clear(); - console.log("processContentStreams: pos", JSON.stringify(pos)); - }), - payloadOperator({ parent, filters, loadingEvents$, resetPos$, ...settings }), - startWith({ ...defaultPayload, placeholder: true }), - )), - share() - ); - - return { payload$, scrolling$, loading$, resetPos$ }; -} diff --git a/client/src/components/providers/History/DscProvider/DscProvider.js b/client/src/components/providers/History/DscProvider/DscProvider.js deleted file mode 100644 index 855cd2a770c..00000000000 --- a/client/src/components/providers/History/DscProvider/DscProvider.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Given a collection, tracks cache changes to the object. - * - * Dataset collections are stored in two places depending on how deeply nested - * it is in the tree. At the top level are root dataset collections which are - * elements of a history's contents. These source their data from the content - * cache. Then inside a dataset collection, it's possible to nest other - * collections arbitrarily, these collections come from the collections cache - * and the api does not necessarily deliver the same fields for both scenarios, - * but we run both raw objects into a DatasetCollection model class. - */ - -import { of } from "rxjs"; -import { map, pluck, switchMap, distinctUntilChanged } from "rxjs/operators"; -import { whenAny } from "utils/observable/whenAny"; -import { monitorContentQuery, monitorDscQuery } from "components/providers/History/caching"; -import { DatasetCollection } from "components/History/model/DatasetCollection"; -import deepEqual from "deep-equal"; - -// passed object should have a pouch _id for monitoring -const hasPouchId = (o) => "_id" in o; - -export default { - props: { - collection: { type: Object, required: true, validator: hasPouchId }, - isRoot: { type: Boolean, required: true }, - }, - data() { - return { - raw: this.collection, - }; - }, - computed: { - dsc() { - const cleanObj = JSON.parse(JSON.stringify(this.raw)); - return new DatasetCollection(cleanObj); - }, - }, - watch: { - collection(newVal, oldVal) { - if (newVal && !deepEqual(newVal, oldVal)) { - this.raw = newVal; - } - }, - dsc(newVal, oldVal) { - if (newVal && !deepEqual(newVal, oldVal)) { - this.$emit("update:collection", newVal); - } - }, - }, - // prettier-ignore - created() { - const root$ = this.watch$("isRoot", true).pipe( - distinctUntilChanged() - ); - - const id$ = this.watch$("collection", true).pipe( - pluck("_id"), - distinctUntilChanged() - ); - - const monitor$ = whenAny(id$, root$).pipe( - switchMap((inputs) => { - const [_id, isRoot] = inputs; - const monitorOperator = isRoot ? monitorContentQuery : monitorDscQuery; - const selector = { _id }; - const request = { selector, offset: 0, limit: 1 }; - - return of(request).pipe( - monitorOperator(), - map((update) => { - const { initialMatches = [], doc = null, deleted } = update; - if (deleted) { - return null; - } - let updatedDoc = doc; - if (initialMatches.length == 1) { - updatedDoc = initialMatches[0]; - } - return updatedDoc; - }), - ); - }) - ); - - this.$subscribeTo(monitor$, (doc) => { - this.raw = doc; - }); - }, - render() { - return this.$scopedSlots.default({ - dsc: this.dsc, - }); - }, -}; diff --git a/client/src/components/providers/History/DscProvider/DscProvider.test.js b/client/src/components/providers/History/DscProvider/DscProvider.test.js deleted file mode 100644 index 37173bcb43c..00000000000 --- a/client/src/components/providers/History/DscProvider/DscProvider.test.js +++ /dev/null @@ -1,131 +0,0 @@ -/* eslint-disable no-unused-vars */ -import { mountRenderless, watchForChange } from "jest/helpers"; -import { wipeDatabase } from "components/providers/History/caching"; -import { cacheContent, cacheCollectionContent } from "components/providers/History/caching"; -import { DatasetCollection } from "components/History/model/DatasetCollection"; -import DscProvider from "./DscProvider"; - -import { testCollection, testNestedCollection } from "components/providers/History/test/testCollection"; - -// Imports dependencies without firing up worker because that blows with Jest -jest.mock("app"); -jest.mock("components/providers/History/caching"); - -beforeEach(wipeDatabase); -afterEach(wipeDatabase); - -describe("DscProvider", () => { - let wrapper; - - afterEach(async () => { - if (wrapper) { - wrapper.destroy(); - } - wrapper = undefined; - }); - - describe("monitors a root collection (direct child of a history)", () => { - let rootCollection; - - beforeEach(async () => { - rootCollection = await cacheContent(testCollection, true); - expect(rootCollection).toBeDefined(); - - wrapper = await mountRenderless(DscProvider, { - propsData: { - collection: rootCollection, - isRoot: true, - }, - }); - expect(wrapper).toBeDefined(); - - const { newVal: dsc } = await watchForChange({ vm: wrapper.vm, propName: "dsc" }); - expect(dsc._id).toEqual(rootCollection._id); - }); - - afterEach(() => { - rootCollection = undefined; - }); - - test("should successfully mount and emit the pre-cached data", () => { - // compare output to input prop, should be the same because we didn't change anything - const root = new DatasetCollection(rootCollection); - const emitted = new DatasetCollection(wrapper.vm.dsc); - const { _rev, cached_at, ...originalProps } = root; - const { _rev: new_rev, cached_at: new_cached_at, ...newProps } = emitted; - expect(originalProps).toEqual(newProps); - }); - - test("should emit updates as they occur", async () => { - const { cached_at: old_cached_at, _rev: old_rev, ...oldProps } = wrapper.vm.dsc; - - // write a new field to the collection - const fooVal = "abc123"; - rootCollection.foo = fooVal; - const updatedRoot = await cacheContent(rootCollection, true); - expect(updatedRoot.foo).toEqual(fooVal); - - // wait for next update then check the foo val - await wrapper.vm.$nextTick(); - - // all same props except _rev and cached_at and foo - const { cached_at, _rev, foo, ...newProps } = wrapper.vm.dsc; - expect(foo).toEqual(fooVal); - expect(old_cached_at).toBeLessThan(cached_at); - expect(old_rev).not.toEqual(_rev); - expect(newProps).toEqual(oldProps); - }); - }); - - describe("monitors nested collection", () => { - let nestedCollection; - const parent_url = "/foo"; - - beforeEach(async () => { - // cache a collection root - nestedCollection = await cacheCollectionContent(testNestedCollection, true); - expect(nestedCollection).toBeDefined(); - - // mount and monitor - wrapper = await mountRenderless(DscProvider, { - propsData: { - collection: nestedCollection, - isRoot: false, - }, - }); - expect(wrapper).toBeDefined(); - - const { newVal: dsc } = await watchForChange({ vm: wrapper.vm, propName: "dsc" }); - expect(dsc._id).toEqual(nestedCollection._id); - }); - - afterEach(() => { - nestedCollection = undefined; - }); - - test("should successfully mount and emit the pre-cached data", () => { - const orig = new DatasetCollection(nestedCollection); - const emitted = new DatasetCollection(wrapper.vm.dsc); - const { _rev, cached_at, ...originalProps } = orig; - const { _rev: new_rev, cached_at: new_cached_at, ...newProps } = emitted; - expect(originalProps).toEqual(newProps); - }); - - test("should emit updates as they occur", async () => { - const { cached_at: old_cached_at, _rev: old_rev, ...oldProps } = wrapper.vm.dsc; - - // write a new field to the collection - const fooVal = "abc123"; - nestedCollection.foo = fooVal; - const updateResult = await cacheCollectionContent(nestedCollection, true); - expect(updateResult.foo).toEqual(fooVal); - - // wait for next update then check the foo val - // await wait(500); - await wrapper.vm.$nextTick(); - - // all same props except _rev and cached_at and foo - expect(wrapper.vm.dsc.foo).toEqual(fooVal); - }); - }); -}); diff --git a/client/src/components/providers/History/DscProvider/index.js b/client/src/components/providers/History/DscProvider/index.js deleted file mode 100644 index 57b55f84fcf..00000000000 --- a/client/src/components/providers/History/DscProvider/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import DscProvider from "./DscProvider"; - -export default DscProvider; diff --git a/client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.js b/client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.js deleted file mode 100644 index b6d04598c22..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.js +++ /dev/null @@ -1,34 +0,0 @@ -import { ContentProvider, processContentStreams } from "../ContentProvider"; -import { contentPayload } from "./contentPayload"; - -export default { - mixins: [ContentProvider], - - props: { - disablePoll: { type: Boolean, default: false }, - }, - - computed: { - history() { - return this.parent; - }, - }, - - watch: { - history(newHistory, oldHistory) { - if (!(newHistory.id == oldHistory.id)) { - this.resetScrollPos(); - } - }, - }, - - methods: { - initStreams() { - const { disablePoll, debouncePeriod, pageSize, params$, scrollPos$, debug } = this; - const parent$ = this.watch$("history"); - const sources = { params$, parent$, scrollPos$ }; - const settings = { disablePoll, debouncePeriod, pageSize, debug }; - return processContentStreams(contentPayload, sources, settings); - }, - }, -}; diff --git a/client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.test.js b/client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.test.js deleted file mode 100644 index be79728f2d8..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/HistoryContentProvider.test.js +++ /dev/null @@ -1,161 +0,0 @@ -import { shallowMount } from "@vue/test-utils"; -import { watchUntil, getLocalVue } from "jest/helpers"; -import { sameVueObj, payloadChange } from "components/providers/History/test/providerTestHelpers"; -import HistoryContentProvider from "./HistoryContentProvider"; -import { SearchParams } from "components/providers/History/SearchParams"; -import { bulkCacheContent, wipeDatabase } from "components/providers/History/caching"; -import { defaultPayload } from "../ContentProvider"; -import { serverContent, testHistory, testHistoryContent } from "components/providers/History/test/testHistory"; - -// reads hids -const payloadHids = (payload) => payload.contents?.map((o) => o.hid) || []; -const localVue = getLocalVue(); - -// mocking -jest.mock("app"); -jest.mock("components/providers/History/caching"); -jest.mock("./loadContents"); - -afterEach(() => wipeDatabase()); - -describe("HistoryContentProvider", () => { - let wrapper; - - beforeEach(async () => {}); - - afterEach(async () => { - if (wrapper) { - await wrapper.destroy(); - } - }); - - describe("blank initialization state", () => { - beforeEach(async () => { - wrapper = await shallowMount(HistoryContentProvider, { - localVue, - propsData: { - parent: testHistory, - pageSize: 10, - debug: false, - debouncePeriod: 200, - }, - scopedSlots: { - default() {}, - }, - }); - // wait for default emit - await payloadChange({ vm: wrapper.vm }); - }); - - test("should expose update methods", async () => { - expect(wrapper.vm.setScrollPos).toBeInstanceOf(Function); - }); - - test("should show an empty payload", () => { - expect(SearchParams.equals(new SearchParams(), wrapper.vm.params)).toBe(true); - expect(sameVueObj(wrapper.vm.payload, defaultPayload)); - }); - }); - - describe("with pre-inserted content", () => { - beforeEach(async () => { - // eslint-disable-next-line no-unused-vars - const cachedContent = await bulkCacheContent(testHistoryContent, true); - - wrapper = await shallowMount(HistoryContentProvider, { - localVue, - propsData: { - parent: testHistory, - pageSize: 10, - debug: false, - debouncePeriod: 200, - }, - scopedSlots: { - default() {}, - }, - }); - - // eslint-disable-next-line no-unused-vars - const spinUp = await watchUntil(wrapper.vm, function () { - const allDone = wrapper.vm.payload.contents.length > 0; - // console.log("done?", allDone); - return allDone; - }); - }); - - // If the cache adds some content, should still be at the top, but the - // bottomRows should change to reflect the difference between the - // returned content rows and the total matches - - test("initial load, no scrolling", async () => { - const payload = wrapper.vm.payload; - // reportPayload(payload); - - // test data on server - const allContent = serverContent(); - // maximum hid in the fake server content - const maxServerHid = allContent[0].hid; - expect(payload).toBeDefined(); - - const { contents, topRows, bottomRows, startKey, totalMatches } = payload; - expect(topRows).toEqual(0); - expect(contents.length).toBeGreaterThanOrEqual(2 * wrapper.vm.pageSize); - expect(bottomRows).toBeGreaterThan(0); - expect(bottomRows).toEqual(allContent.length - contents.length); - expect(startKey).toEqual(maxServerHid); - expect(totalMatches).toEqual(allContent.length); - }); - - // When the scroller moves, we may end up over a known content row, in - // which case the scroller handler will get an exact HID match, if so, - // we should have new content values from the hidMap and some topRows - // bottomRows - - test("scroll to known key", async () => { - const payload = wrapper.vm.payload; - - // shift the scroller down to half way through that content list - // make sure it's visible and not hidden - const targetElement = testHistoryContent[Math.floor(testHistoryContent.length / 2)]; - expect(targetElement.visible).toBe(true); - expect(targetElement.deleted).toBe(false); - - const targetKey = targetElement.hid; - expect(targetKey).toBeDefined(); - expect(targetKey).toBeGreaterThan(0); - - // console.log("setting scroll pos to targetKey", targetKey); - wrapper.vm.setScrollPos({ key: targetKey }); - - // need to wait for it to settle down - await await payloadChange({ vm: wrapper.vm }); - - // check to see if what we want is there - const scrollPayload = wrapper.vm.payload; - expect(payload).toBeDefined(); - const { startKey } = scrollPayload; - const hids = payloadHids(scrollPayload); - // console.log("hids", hids); - - expect(hids).toContain(targetKey); - expect(startKey).toEqual(targetKey); - }); - - // This simulates dragging the scrollbar to a place in the history where - // there is no exact match of HID. The provider should still render - // contents around the targetHID, if they exist - - test("should show results when we pick a HID by scroller height", async () => { - // set scroller to non-existent hid - wrapper.vm.setScrollPos({ cursor: 0.52323 }); - const scrollPayload = await payloadChange({ vm: wrapper.vm }); - const { contents, startKey, topRows, bottomRows, totalMatches } = scrollPayload; - const hids = payloadHids(scrollPayload); - - expect(hids).toContain(startKey); - expect(startKey).toBeGreaterThan(0); - expect(topRows).toBeGreaterThan(0); - expect(bottomRows).toEqual(totalMatches - contents.length - topRows); - }); - }); -}); diff --git a/client/src/components/providers/History/HistoryContentProvider/__mocks__/loadContents.js b/client/src/components/providers/History/HistoryContentProvider/__mocks__/loadContents.js deleted file mode 100644 index 3965b9f2d11..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/__mocks__/loadContents.js +++ /dev/null @@ -1,34 +0,0 @@ -// common mock implementation -// having a hard time making jest manually mock this properly - -import { map } from "rxjs/operators"; -import { getPropRange } from "components/providers/History/caching/loadHistoryContents"; -import { serverContent } from "components/providers/History/test/testHistory"; - -export const loadContents = jest.fn().mockImplementation((config) => { - const { filters } = config; - - return map((pagination) => { - const { offset, limit } = pagination; - - // server side result set - const searchResults = serverContent(filters); - const { min: minHid, max: maxHid } = getPropRange(searchResults, "hid"); - - // window slice returned - const result = searchResults.slice(offset, offset + limit); - const { min: minContentHid, max: maxContentHid } = getPropRange(result, "hid"); - - return { - summary: {}, - matches: result.length, - totalMatches: searchResults.length, - minHid, - maxHid, - minContentHid, - maxContentHid, - limit, - offset, - }; - }); -}); diff --git a/client/src/components/providers/History/HistoryContentProvider/contentPayload.js b/client/src/components/providers/History/HistoryContentProvider/contentPayload.js deleted file mode 100644 index 3643ebe4246..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/contentPayload.js +++ /dev/null @@ -1,321 +0,0 @@ -import { concat, race, timer, partition, Observable, BehaviorSubject, Subject } from "rxjs"; -import { - debounceTime, - distinctUntilChanged, - filter, - map, - mapTo, - mergeAll, - pairwise, - pluck, - publish, - share, - shareReplay, - take, - tap, - window, - withLatestFrom, -} from "rxjs/operators"; -import { show } from "utils/observable"; -import { CurveFit } from "components/History/model/CurveFit"; -import { ScrollPos } from "components/History/model/ScrollPos"; -import { SearchParams } from "components/providers/History/SearchParams"; -import { loadContents } from "./loadContents"; -import { watchHistoryContents } from "./watchHistoryContents"; -import { default as store } from "store/index"; -import { defaultPayload } from "../ContentProvider"; - -/** - * Observable operator accepts history, search filters as config values, then uses an observable - * scroll position to periodically poll the server for new data and watch the cache for - * corresponding updates for a window of content defined by the cfg props. - * - * @param {object} cfg history, filters, other operation parameters - * @return {Observable} Observable that emits payloads suitable for use in the scroller - */ -// prettier-ignore -export const contentPayload = (cfg = {}) => { - const { - parent: history, - filters = new SearchParams(), - pageSize = SearchParams.pageSize, - debouncePeriod = 250, - loadingTimeout = 2000, - disablePoll = false, - debug = false, - // optional feedback indicators - loadingEvents$ = new Subject(), - resetPos$ = new Subject(), - chunkSize = pageSize - } = cfg; - - // These running totals are shared between instances of content payload because a lot of the - // stats do not get returned on every single pol. That means the most recent values need to be - // preserved when the user switches the filters back and forth - const totalMatches$ = getSubject("totalMatches", history, filters, () => new BehaviorSubject(history.hidItems)); - const cursorToHid$ = getSubject("cursorToHid", history, filters, () => new BehaviorSubject(createCursorToHid(history))); - const hidToTopRows$ = getSubject("hidToTopRows", history, filters, () => new BehaviorSubject(createHidToTopRows(history))); - - return publish((pos$) => { - - // #region establish HID by either having exact value or estimating from scroll position - - const [ hasKey$ ] = partition(pos$, (pos) => pos.key === null); - - const knownHid$ = hasKey$.pipe( - pluck('key') - ); - - const hid$ = knownHid$.pipe( - distinctUntilChanged(), - filter(hid => !isNaN(hid)), - share(), - ); - - // #endregion - - // #region server loading - - const serverHid$ = hid$.pipe( - chunk({ chunkSize, debug, label: "serverHid" }), - distinctUntilChanged(), - debounceTime(debouncePeriod), - show(debug, hid => console.log("serverHid", hid)), - share(), - ); - - const serverLoad$ = serverHid$.pipe( - tap(() => loadingEvents$.next(true)), - loadContents({ history, filters, disablePoll, debug }), - tap(() => loadingEvents$.next(false)), - tap((response) => updateVuexHistory(history.id, response)), - share(), - ); - - //#endregion - - // #region Cache monitor - - // after a fresh server request has been made, wait for first response before allowing - // an input to the cache, avoids bounciness - const cacheHid$ = hid$.pipe( - window(serverHid$), - mergeAll(), - debounceTime(100), - ); - - const cacheMonitor$ = cacheHid$.pipe( - watchHistoryContents({ history, filters, pageSize, debouncePeriod, debug }), - show(debug, (result) => console.log("cacheMonitor.contents (hid)", result.contents.map(o => o.hid))), - shareReplay(1) - ); - - const cachePayload$ = cacheMonitor$.pipe( - withLatestFrom(totalMatches$, hidToTopRows$), - map(buildPayload(pageSize)), - show(debug, (payload) => console.log("payload", payload)), - ); - - // An empty cache response, wait a while then emit an empty payload - const noResults$ = timer(loadingTimeout).pipe( - mapTo({ ...defaultPayload, noResults: true }), - take(1) - ); - const noInitialResults$ = concat(noResults$, cachePayload$); - const payload$ = race(noInitialResults$, cachePayload$); - - // #endregion - - // #region Reposition View to accomodate recent updates - - // When new updates to the history come in, we should shift the scrollPos so that we can see - // them. Without some kind of explicit move, the system will think they're just random - // updates that are happening outside the region of interest, and there would be no - // particular reason to shift the view. But that's not ideal when you're already looking at - // the top of the history and expect to see the most recent updates as they come in. - - const adjustedScrollPos$ = serverLoad$.pipe( - pairwise(), - filter(([a,b]) => !isNaN(a.maxHid) && !isNaN(b.maxHid)), - withLatestFrom(pos$, hid$), - map(([[lastResponse, response], pos, hid]) => { - const updatesAtTop = response.maxHid >= lastResponse.maxHid; - - const scrollerExactlyAtTop = pos.cursor === 0 || pos.key === lastResponse.maxHid; - const fudge = 2; - const scrollNearLastTop = pos.key !== null ? Math.abs(pos.key - lastResponse.maxContentHid) < fudge : false; - const scrollerAtTop = scrollerExactlyAtTop || scrollNearLastTop; - - if (updatesAtTop && scrollerAtTop) { - return ScrollPos.create({ cursor: 0, key: response.maxContentHid }); - } - return null; - }), - filter(Boolean), - ); - - // #endregion - - // #region serverLoad side-effects, keeps track of important stats via feedback loops - - const newCursorToHid$ = serverLoad$.pipe( - withLatestFrom(cursorToHid$), - map(([result, fit]) => adjustCursorToHid(result, fit)) - ); - - const newHidToTopRows$ = serverLoad$.pipe( - withLatestFrom(hidToTopRows$), - map(([result, fit]) => adjustHidToTopRows(result, fit)) - ); - - const newMatches$ = serverLoad$.pipe( - pluck('totalMatches'), - map(val => parseInt(val)), - ); - - //#endregion - - return new Observable((obs) => { - const sub = payload$.subscribe(obs); - - // Tie stat feedback subscriptions to main payload sub - // Make sure not to combineLatest these subject accumulators or we'll - // end up with an infinite loop - sub.add(newCursorToHid$.subscribe(cursorToHid$)); - sub.add(newHidToTopRows$.subscribe(hidToTopRows$)); - sub.add(newMatches$.subscribe(totalMatches$)); - sub.add(adjustedScrollPos$.subscribe(resetPos$)); - - return sub; - }) - }) -}; - -const adjustCursorToHid = (result, fit) => { - const { maxHid, minHid, maxContentHid, minContentHid, matches, totalMatchesUp, totalMatches } = result; - - // set 0, 1 for min/max hids - fit.set(0, maxHid); - fit.set(1, minHid); - - // find cursor for top & bottom of returned content - if (totalMatches > 0) { - fit.set(totalMatchesUp / totalMatches, maxContentHid); - fit.set((matches + totalMatchesUp) / totalMatches, minContentHid); - } - - return fit; -}; - -const adjustHidToTopRows = (result, fit) => { - const { - // min and max of returned data - minContentHid, - maxContentHid, - - // endpoints for all of history, that match filters - minHid, - maxHid, - - // num matches up/down from request hid - matchesUp, - matchesDown, - matches, - - // total matches up/down from request hid - totalMatchesUp, - totalMatches, - } = result; - - if (matches > 0) { - fit.set(maxContentHid, totalMatchesUp - matchesUp); - fit.set(minContentHid, Math.max(0, totalMatchesUp + matchesDown - 1)); - } - - fit.set(maxHid, 0); - if (totalMatches > 0) { - fit.set(minHid, totalMatches - 1); - } - - fit.domain = [minHid, maxHid]; - - return fit; -}; - -const buildPayload = (pageSize) => (inputs) => { - // cacheWatchResult is the value from the cache watcher - // hidToTopRows is a dataset for estimating toprows from HID - // since we can't possibly have that information at the time - // of the cache-read - const [cacheWatchResult, totalMatches, hidToTopRows] = inputs; - - // contents is the list from the aggregator - // targetKey was the request value for the aggregation - const { contents = [] } = cacheWatchResult; - - let topRows = 0; - let bottomRows = Math.max(0, totalMatches - contents.length - 1); - - // missing rows above & below content - if (hidToTopRows.size && contents.length && totalMatches > pageSize) { - const maxHid = contents[0].hid; - const rowsAboveTop = hidToTopRows.get(maxHid, { interpolate: true }); - topRows = Math.max(0, Math.round(rowsAboveTop)); - bottomRows = Math.max(0, totalMatches - topRows - contents.length); - } - - return { topRows, bottomRows, totalMatches, ...cacheWatchResult }; -}; - -const createHidToTopRows = (history) => { - const fit = new CurveFit(); - fit.domain = [0.0, +history.hidItems]; - fit.xPrecision = 3; - fit.yPrecision = 3; - fit.set(history.hidItems, 0.0); - fit.set(0.0, history.hidItems); - return fit; -}; - -const createCursorToHid = (history) => { - const fit = new CurveFit(); - fit.domain = [0.0, 1.0]; - fit.xPrecision = 3; - fit.yPrecision = 2; - fit.set(0.0, history.hidItems); - fit.set(1.0, 1); - return fit; -}; - -// Need to stash these subjects in memory since we don't get the counts -// back on every single poll request - -const subjects = new Map(); - -const getSubject = (label, history, filters, subjectFactory) => { - const key = makeSubjectKey(label, history, filters); - if (!subjects.has(key)) { - subjects.set(key, subjectFactory()); - } - return subjects.get(key); -}; - -const makeSubjectKey = (label, history, filters) => { - return JSON.stringify({ label, historyId: history.id, filters: filters.export() }); -}; - -/** - * Updates the vuex history when a polling result comes back. - * TODO: consider storing histories in cache instead of Vuex, since some users have very large lists - * of histories. - * - * @param {string} historyId History id from poll result - * @param {object} pollResponse Poll summary response - */ -const updateVuexHistory = (historyId, pollResponse) => { - const getter = store.getters["betaHistory/getHistoryById"]; - const existingHistory = getter(historyId); - const { historySize: size, historyEmpty: empty } = pollResponse; - const history = { ...existingHistory, size, empty }; - store.dispatch("betaHistory/setHistory", history); -}; diff --git a/client/src/components/providers/History/HistoryContentProvider/contentPayload.test.js b/client/src/components/providers/History/HistoryContentProvider/contentPayload.test.js deleted file mode 100644 index ef3ea321186..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/contentPayload.test.js +++ /dev/null @@ -1,154 +0,0 @@ -import { BehaviorSubject, timer } from "rxjs"; -import { takeUntil, share } from "rxjs/operators"; -import { ObserverSpy } from "@hirez_io/observer-spy"; -import { ScrollPos } from "components/History/model/ScrollPos"; -import { bulkCacheContent, wipeDatabase } from "components/providers/History/caching"; -import { contentPayload } from "./contentPayload"; -import { loadContents } from "./loadContents"; -import { serverContent, testHistory, testHistoryContent } from "components/providers/History/test/testHistory"; -import { untilNthEmission } from "jest/helpers"; - -jest.mock("app"); -jest.mock("components/providers/History/caching"); -jest.mock("./loadContents"); - -// Create a history and a set of filters then wire up a scrollPos to -// the contentPayload operator, check the payloads that come out - -describe("contentPayload operator", () => { - let sub; - const safetyTimeout = 2000; - const disablePoll = true; - const debouncePeriod = 250; - - beforeEach(async () => { - await wipeDatabase(); - await bulkCacheContent(testHistoryContent, true); - }); - - afterEach(async () => { - if (sub) { - sub.unsubscribe(); - } - await wipeDatabase(); - }); - - // The first emission any time we subscribe to the payload should - // be the top of the history, this is because we do not yet have any - // way to gauge how big the history is, so our first emission is always - // from the top of the list, which is where we reset the scroller when - // the inputs change anyway - - test("single emission, no scrolling, top of list", async () => { - const spy = new ObserverSpy(); - const start = new ScrollPos(); - const input$ = new BehaviorSubject(start); - const pageSize = 10; - - // prettier-ignore - sub = input$.pipe( - contentPayload({ - parent: testHistory, - pageSize, - disablePoll, - debouncePeriod - }), - takeUntil(timer(safetyTimeout)) - ).subscribe(spy); - - await spy.onComplete(); - - // should finish - expect(spy.receivedComplete()).toBe(true); - - // should call the loader once - expect(loadContents.mock.calls.length).toEqual(1); - - // should only emit one result - expect(spy.receivedNext()).toBe(true); - expect(spy.getValues().length).toEqual(1); - - // expect a payload with results from the top of the list (cursor = 0) - const { contents } = spy.getFirstValue(); - - expect(contents).toBeDefined(); - expect(contents).toBeInstanceOf(Array); - expect(contents.length).toBeGreaterThanOrEqual(2 * pageSize); - - const payloadHids = contents.map((c) => c.hid); - expect(payloadHids[0]).toEqual(testHistoryContent[0].hid); - }); - - // The first emission must be from the top of the list, but then - // the user moves the scroller down half-way. Should get results - // from the middle of the sample contents - - test("move half way down the list", async () => { - const pageSize = 5; - - // scroll position (cursor/key) - const pos$ = new BehaviorSubject(ScrollPos.create()); - - // subscribe to payload emitter - // first emission needs to be at top of list - const payload$ = pos$.pipe( - contentPayload({ - parent: testHistory, - pageSize, - disablePoll, - }), - takeUntil(timer(safetyTimeout)), - share() - ); - - const spy = new ObserverSpy(); - sub = payload$.subscribe(spy); - - // wait until first emission, then move scroller - await untilNthEmission(payload$, 1); - pos$.next(ScrollPos.create({ cursor: 0.5 })); - - await spy.onComplete(); - expect(spy.receivedComplete()).toBe(true); - expect(spy.receivedNext()).toBe(true); - // spy.getValues().forEach(reportPayload); - - // should call the loader once - expect(loadContents.mock.calls.length).toBeGreaterThan(0); - - const serverResults = serverContent(); - const serverResultHids = serverResults.map((o) => o.hid); - - const initialPayload = spy.getFirstValue(); - { - const { contents, startKey, startKeyIndex, topRows, bottomRows, totalMatches } = initialPayload; - const listLength = 2 * pageSize; - const payloadHids = contents.map((o) => o.hid); - const historyHids = serverResultHids.slice(startKeyIndex, contents.length); - - expect(contents).toBeDefined(); - expect(contents).toBeInstanceOf(Array); - expect(contents.length).toBeGreaterThanOrEqual(listLength); - expect(startKey).toEqual(serverResultHids[0]); - expect(startKeyIndex).toEqual(0); - expect(topRows).toEqual(0); - expect(totalMatches).toEqual(serverResults.length); - expect(payloadHids).toEqual(historyHids); - expect(topRows + bottomRows + contents.length).toEqual(totalMatches); - } - - const secondPayload = spy.getLastValue(); - { - const { contents, startKey, startKeyIndex, topRows, bottomRows, totalMatches } = secondPayload; - const payloadHids = contents.map((o) => o.hid); - - expect(contents).toBeDefined(); - expect(contents).toBeInstanceOf(Array); - expect(topRows).toBeGreaterThan(0); - expect(totalMatches).toEqual(serverResults.length); - expect(startKeyIndex).toBeGreaterThan(0); - expect(payloadHids).toContain(startKey); - expect(topRows + bottomRows + contents.length).toEqual(totalMatches); - } - }); -}); diff --git a/client/src/components/providers/History/HistoryContentProvider/index.js b/client/src/components/providers/History/HistoryContentProvider/index.js deleted file mode 100644 index 244046fb02a..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import HistoryContentProvider from "./HistoryContentProvider"; - -export default HistoryContentProvider; diff --git a/client/src/components/providers/History/HistoryContentProvider/loadContents.js b/client/src/components/providers/History/HistoryContentProvider/loadContents.js deleted file mode 100644 index f42ffd81f46..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/loadContents.js +++ /dev/null @@ -1,57 +0,0 @@ -import { defer, of, throwError } from "rxjs"; -import { switchMap, debounceTime, startWith, repeatWhen } from "rxjs/operators"; -import { decay } from "utils/observable"; -import { monitorXHR } from "utils/observable/monitorXHR"; -import { loadHistoryContents } from "components/providers/History/caching"; -import { SearchParams } from "components/providers/History/SearchParams"; - -// prettier-ignore -export const loadContents = (cfg = {}) => { - const { - history, - filters, - initialInterval = 2 * 1000, - maxInterval = 10 * initialInterval, - disablePoll = false, - debug = false, - windowSize = 2 * SearchParams.pageSize, - } = cfg; - - if (history === undefined) { - return throwError(new Error("Missing history in loadContents")); - } - if (filters === undefined) { - return throwError(new Error("Missing filters in loadContents")); - } - - const { id } = history; - - const singleLoad = (hid) => defer(() => of([id, filters, hid]).pipe( - loadHistoryContents({ windowSize }), - )); - - const poll = (request$) => resetPoll(100).pipe( - switchMap(() => request$.pipe( - repeatWhen(completed$ => completed$.pipe( - decay({ initialInterval, maxInterval, debug }), - )) - )) - ); - - return switchMap((hid) => { - const request$ = singleLoad(hid); - return disablePoll ? request$ : poll(request$); - }) -}; - -// history, tools routes all refresh -// prettier-ignore -const resetPoll = (debouncePeriod) => { - const routes = [/api\/(history|tools|histories)/]; - const methods = ["POST", "PUT", "DELETE"]; - - return monitorXHR({ methods, routes }).pipe( - startWith(true), - debounceTime(debouncePeriod) - ); -}; diff --git a/client/src/components/providers/History/HistoryContentProvider/readme.md b/client/src/components/providers/History/HistoryContentProvider/readme.md deleted file mode 100644 index 71b633e8127..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/readme.md +++ /dev/null @@ -1,73 +0,0 @@ -The history content provider is where the grunt-work of loading, polling and caching -happens. The output of the provider is a list of current data suitable for rendering in the companion Scroller component. - -### Design - -The API of the provider is a renderless Vue component. Its inputs are the history and the -currently selected filters. Internally, it tracks the user's current scroll position on the scrolling list then combines those 3 values to ultimately expose an object containing all the -currently-visible content for the history along with some other values that are useful -for the scroller to render the visible window of data. - -#### Composition -```html static - - - - - - - - - - - -``` - -#### History Content Provider exposed slot props (outputs) -```js -{ - // a function to update the internal scroll position - setScrollPos: fn, - - // current content window - payload: { - contents: [] - topRows: 10 - botttomRows: 100, - startKey: "123", - }, - - // flags - loading: true, - scrolling: false, -} -``` - -### Implementation - -Because actually delivering that data is kind of a complex process (see dependency graph below) and has multiple goals, Vue's rather -simplistic observability system is not by itself be an ideal means to actually deliver the -constantly shifting payload value. Instead, we used RxJS and its more sophisticated, but admittedly -more complex API. - -The goal of this section is to explain how the RxJS works inside the history content provider to -deliver the payload from the 3 changing inputs. - -I believe it's easiest to follow RxJS streams by simply drawing a map of them. An rxjs operator is a -functional transformation of a source observable emitter into a new observable emitter and therefore -a combined composition of them (often called a stream) is essentially its own dependency tree. All -you have to do is connect the inputs to the outputs. - -### RxJS Flowchart - diff --git a/client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.js b/client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.js deleted file mode 100644 index da47d46b08f..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.js +++ /dev/null @@ -1,37 +0,0 @@ -import { of } from "rxjs"; -import { map } from "rxjs/operators"; -import { aggregateCacheUpdates } from "../ContentProvider"; -import { monitorHistoryContent } from "components/providers/History/caching"; -import { SEEK } from "components/providers/History/caching/enums"; -import { SearchParams } from "components/providers/History/SearchParams"; - -// prettier-ignore -export const watchHistoryContents = (cfg = {}) => hid$ => { - const { - history, - filters = new SearchParams(), - pageSize = SearchParams.pageSize, - debug = false, - keyField = "hid", - keyDirection = SEEK.DESC, - ...otherConfig - } = cfg; - - // builds a monitor observable based on a hid - const monitor = (hid) => of([history.id, filters, hid]).pipe( - monitorHistoryContent({ pageSize, debug, keyField }) - ); - - // handles the plumbing for observing the query (monitor) and collecting the output into an - // aggregate ordered list focused around the current target key (hid in this case) - return hid$.pipe( - map(val => parseInt(val)), - aggregateCacheUpdates(monitor, { - keyField, - keyDirection, - pageSize, - debug, - ...otherConfig - }), - ); -}; diff --git a/client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.test.js b/client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.test.js deleted file mode 100644 index b6cccd40eb0..00000000000 --- a/client/src/components/providers/History/HistoryContentProvider/watchHistoryContents.test.js +++ /dev/null @@ -1,211 +0,0 @@ -import { of, isObservable, timer } from "rxjs"; -import { take, takeUntil } from "rxjs/operators"; -import { ObserverSpy } from "@hirez_io/observer-spy"; -import { untilNthEmission } from "jest/helpers"; - -import { SearchParams } from "components/providers/History/SearchParams"; -import { buildContentId } from "components/providers/History/caching/db/observables"; -import { watchHistoryContents } from "./watchHistoryContents"; -import { cacheContent, getCachedContent, bulkCacheContent, wipeDatabase } from "components/providers/History/caching"; - -import historyContent from "components/providers/History/test/json/historyContent.json"; - -// need to mock monitorHistoryContent which is instantiated inside the worker, -// but we can't actually fire up threads.js in a unit test because you can't -// call expose() on the main thread, so we mock the adapter functions which -// generate observables from the worker. -jest.mock("app"); -jest.mock("components/providers/History/caching"); - -beforeEach(async () => { - await wipeDatabase(); - // eslint-disable-next-line no-unused-vars - const cachedContent = await bulkCacheContent(historyContent, true); - // console.log(cachedContent.map((o) => o.hid)); -}); - -afterEach(async () => { - await wipeDatabase(); -}); - -// We're testing observables and we're assuming they complete, -// but we add a takeUntil() to each one in the event that something -// is wrong to avoid making the tests take forever -const safetyTimeout = 1000; - -describe("watchHistoryContents", () => { - const firstDoc = historyContent[0]; - - describe("simple loading scenario", () => { - const hid$ = of(firstDoc.hid); - const history = { id: firstDoc.history_id }; - const filters = new SearchParams(); - const pageSize = 5; - - test("should observe pre-inserted content on the initial emission", async () => { - const watcher$ = hid$.pipe( - watchHistoryContents({ - history, - filters, - pageSize, - debug: false, - }), - takeUntil(timer(safetyTimeout)) - ); - - expect(isObservable(watcher$)).toBe(true); - - // spy on output of observable, wait for it to end - const spy = new ObserverSpy(); - watcher$.subscribe(spy); - await spy.onComplete(); - - expect(spy.receivedNext()).toBe(true); - expect(spy.receivedComplete()).toBe(true); - expect(spy.getValuesLength()).toBe(1); - - const { startKey, contents } = spy.getFirstValue(); - // we know there should be an exactd match - expect(startKey).toEqual(firstDoc.hid); - expect(Array.isArray(contents)).toEqual(true); - // Top of list, match + 2 * pageSize - expect(contents.length).toBeGreaterThanOrEqual(2 * pageSize); - }); - - test("should observe subsequently updated data", async () => { - const watcher$ = hid$.pipe( - watchHistoryContents({ - history, - filters, - debouncePeriod: 100, - pageSize: 5, - }), - takeUntil(timer(safetyTimeout)) - ); - - // spy on output of observable, wait for it to end - const spy = new ObserverSpy(); - watcher$.subscribe(spy); - - // wait for the first event (take(n) as a promise for easier testing) - await untilNthEmission(watcher$, 1, safetyTimeout); - - // then update the first doc, need to delay longer than - // the debounce on the watch operator or the aggregation will - // think it's all part of the same update - const docId = buildContentId(firstDoc); - const lookup = await getCachedContent(docId); - expect(lookup.hid).toEqual(firstDoc.hid); - expect(lookup._id).toEqual(docId); - - lookup.foo = "abc"; - const update = await cacheContent(lookup); - expect(update.updated).toEqual(true); - expect(update.id).toEqual(lookup._id); - expect(update.id).toEqual(docId); - - // Should see 2 sets of content, the last of which should have the - // foo field in one of its entries - await spy.onComplete(); - expect(spy.receivedNext()).toBe(true); - expect(spy.receivedComplete()).toBe(true); - expect(spy.getValuesLength()).toBe(2); - - const { contents: lastContents } = spy.getLastValue(); - expect(lastContents.some((doc) => doc.foo == "abc")).toBe(true); - }); - }); - - describe("should respect filter inputs", () => { - const hid$ = of(firstDoc.hid); - const history = { id: firstDoc.history_id }; - let filters; - - beforeEach(() => { - filters = new SearchParams(); - }); - - test("deleted flag", async () => { - filters.showDeleted = true; - - const watcher$ = hid$.pipe( - watchHistoryContents({ - history, - filters, - pageSize: 5, - }), - take(1), - takeUntil(timer(safetyTimeout)) - ); - expect(isObservable(watcher$)).toBe(true); - - // spy on output of observable, wait for it to end - const spy = new ObserverSpy(); - watcher$.subscribe(spy); - await spy.onComplete(); - - expect(spy.receivedNext()).toBe(true); - expect(spy.receivedComplete()).toBe(true); - - const { contents } = spy.getFirstValue(); - expect(Array.isArray(contents)).toEqual(true); - expect(contents.every((doc) => doc.isDeleted == true)).toBe(true); - }); - - test("hidden flag", async () => { - filters.showHidden = true; - - const watcher$ = hid$.pipe( - watchHistoryContents({ - history, - filters, - pageSize: 5, - }), - take(1), - takeUntil(timer(safetyTimeout)) - ); - expect(isObservable(watcher$)).toBe(true); - - // spy on output of observable, wait for it to end - const spy = new ObserverSpy(); - watcher$.subscribe(spy); - await spy.onComplete(); - - expect(spy.receivedNext()).toBe(true); - expect(spy.receivedComplete()).toBe(true); - - const { contents } = spy.getFirstValue(); - expect(Array.isArray(contents)).toEqual(true); - expect(contents.every((doc) => doc.visible == false)).toBe(true); - }); - - test("deleted and hidden flag", async () => { - filters.showDeleted = true; - filters.showHidden = true; - - const watcher$ = hid$.pipe( - watchHistoryContents({ - history, - filters, - pageSize: 5, - }), - take(1), - takeUntil(timer(safetyTimeout)) - ); - expect(isObservable(watcher$)).toBe(true); - - // spy on output of observable, wait for it to end - const spy = new ObserverSpy(); - watcher$.subscribe(spy); - await spy.onComplete(); - - expect(spy.receivedNext()).toBe(true); - expect(spy.receivedComplete()).toBe(true); - - const { contents } = spy.getFirstValue(); - expect(Array.isArray(contents)).toEqual(true); - expect(contents.every((doc) => doc.visible == false)).toBe(true); - expect(contents.every((doc) => doc.isDeleted == true)).toBe(true); - }); - }); -}); diff --git a/client/src/components/providers/History/SearchParams.js b/client/src/components/providers/History/SearchParams.js deleted file mode 100644 index 23a85b7dba3..00000000000 --- a/client/src/components/providers/History/SearchParams.js +++ /dev/null @@ -1,228 +0,0 @@ -import deepEqual from "deep-equal"; -import { isString } from "underscore"; - -const pairSplitRE = /(\w+=\w+)|(\w+="(\w|\s)+")/g; -const scrubFieldRE = /[^\w]/g; -const scrubQuotesRE = /'|"/g; - -// Fields that can be used for text searches -const validTextFields = new Set([ - "name", - "history_content_type", - "type", - "format", - "extension", - "misc_info", - "state", - "hid", - "database", - "annotation", - "description", - "tag", - "tags", -]); - -// alias search field to internal field (requestd name: pouch field name) -const pouchFieldAlias = { - format: "file_ext", - database: "genome_build", - description: "annotation", - tag: "tags", - deleted: "isDeleted", - type: "history_content_type", -}; - -// maps user-field -> server querystring field -// if maps to null, that filter not available on server -const serverFieldAlias = { - tags: "tag", - file_ext: null, - genome_build: null, -}; - -// Convert actualy boolean into objectively incorrect python value our server accepts -const dumbBool = (val) => (val ? "True" : "False"); - -export class SearchParams { - constructor(props = {}) { - this.filterText = ""; - this.showDeleted = false; - this.showHidden = false; - Object.assign(this, props); - } - - get pageSize() { - return SearchParams.pageSize; - } - - clone() { - return new SearchParams(this); - } - - // need this because of what Vue does to objects to make them reactive - export() { - const { filterText, showDeleted, showHidden } = this; - return { filterText, showDeleted, showHidden }; - } - - // Filtering, parses single text input into a map of field->value - // in the case of multiples, maps to field -> [value, value] - get textCriteria() { - const raw = this.filterText; - - const result = new Map(); - if (!raw.length) { - return result; - } - - let matches = raw.match(pairSplitRE); - if (matches === null && raw.length) { - matches = [`name=${raw}`]; - } - - const criteria = matches.reduce((result, pair) => { - const [field, val] = pair.split("="); - - if (validTextFields.has(field)) { - let cleanVal = val.replace(scrubQuotesRE, ""); - // set an array of criteria if we have multiples of the same field name - if (result.has(field)) { - cleanVal = [result.get(field), cleanVal].flat(); - } - - result.set(field, cleanVal); - } - - return result; - }, result); - - return criteria; - } - - // all criteria, map of field->value, includes our non-standard boolean filters - get criteria() { - const criteria = new Map(this.textCriteria); - criteria.set("visible", !this.showHidden); - criteria.set("deleted", this.showDeleted); - return criteria; - } - - // Generates an array of pouchDB selector objects - // { field: { $operator: value }} - get pouchFilters() { - const filters = Array.from(this.criteria) - // generate multiple objects for duplicated field=val entries - // these will be AND-ed together in the final pouch selector - // map userfield to pouchfield, userfield = what the user typed in the box - // pouchfield = the actual field in the cache - .map(([userField, val]) => [this.getPouchFieldName(userField), val]) - .map(([pouchField, val]) => { - const vals = Array.isArray(val) ? val : [val]; - return vals.map((v) => [pouchField, v]); - }) - .flat() - .map(([pouchField, val]) => { - const comparator = isString(val) ? { $regex: new RegExp(val) } : { $eq: val }; - return { [pouchField]: comparator }; - }); - - return filters; - } - - // Creates an object of query criteria for use with the api - get historyContentQueryFields() { - return Array.from(this.criteria) - .map(([userField, val]) => { - let serverField = this.getServerFieldName(userField); - let serverVal = val; - - switch (serverField) { - // some client-side filters do not correspond to filters on the server - // they can be used to filter local results but will not affect the polling - // TODO: consider adding them as available filter options on the api? - case null: - return []; - - // This is advertised to work, but is broken on the current api - case "annotation": - case "description": - return []; - - // non-standard REST bools - // deleted serverField was reserved by pouchDB, needed to rename it to "isDeleted" - case "deleted": - case "visible": - serverVal = dumbBool(val); - break; - - // no text searching in some fields - case "hid": - case "state": - case "history_content_type": - case "type": - break; - - // assume text-contains search - default: - serverField = serverField + "-contains"; - serverVal = encodeURIComponent(val); - break; - } - - return [serverField, serverVal]; - }) - .filter((pair) => pair.length == 2) - .reduce((fields, [k, v]) => { - fields[k] = v; - return fields; - }, {}); - } - - // legacy q/qv syntax for content api - // TODO: Delete when we no longer use q/qv - get legacyContentQueryString() { - return Object.entries(this.historyContentQueryFields) - .map(([f, v]) => `q=${f}&qv=${v}`) - .join("&"); - } - - // Standard query string (field=val&field=val...) - get historyContentQueryString() { - return Object.entries(this.historyContentQueryFields) - .map(([f, v]) => `${f}=${v}`) - .join("&"); - } - - // maps friendly user field name to internal data field if necessary - getPouchFieldName(field) { - const cleanName = field.replace(scrubFieldRE, ""); - return cleanName in pouchFieldAlias ? pouchFieldAlias[cleanName] : cleanName; - } - - getServerFieldName(field) { - const cleanName = field.replace(scrubFieldRE, ""); - return cleanName in serverFieldAlias ? serverFieldAlias[cleanName] : cleanName; - } - - // output current state to log - report(label = "params", collapsed = true) { - const { showDeleted, showHidden, filterText } = this; - const consoleOpen = collapsed ? console.groupCollapsed : console.group; - consoleOpen.call(console, label); - console.log("showDeleted", showDeleted); - console.log("showHidden", showHidden); - console.log("filterText", filterText); - console.groupEnd(); - } -} - -// Statics - -SearchParams.pageSize = 30; - -SearchParams.equals = function (a, b) { - if (a !== undefined && b !== undefined) { - return deepEqual(a.export(), b.export()); - } - return false; -}; diff --git a/client/src/components/providers/History/SearchParams.test.js b/client/src/components/providers/History/SearchParams.test.js deleted file mode 100644 index e921b5a9ce2..00000000000 --- a/client/src/components/providers/History/SearchParams.test.js +++ /dev/null @@ -1,376 +0,0 @@ -// I'm using this as the reference for the requirement: -// https://training.galaxyproject.org/training-material/topics/galaxy-interface/tutorials/history/tutorial.html#advanced-searching - -import { SearchParams } from "./SearchParams"; -import { matchesSelector } from "pouchdb-selector-core"; -import { STATES } from "components/History/model/states"; - -// #region Test generators -const testPouchSelector = (userField, searchVal, goodDoc, badDoc) => { - let pouchFieldName; - let params; - let selector; - - beforeEach(() => { - params = new SearchParams(); - params.filterText = `${userField}="${searchVal}"`; - selector = { $and: params.pouchFilters }; - pouchFieldName = params.getPouchFieldName(userField); - }); - - describe("pouchdb selector", () => { - it("should have a row in the selector", () => { - const hasRow = selector.$and.some((row) => row[pouchFieldName] !== undefined); - expect(hasRow).toBeTruthy(); - }); - - it("should return results with matching name field", () => { - expect(matchesSelector(goodDoc, selector)).toBeTruthy(); - }); - - it("should not return results where the name string appears in other fields", () => { - expect(matchesSelector(badDoc, selector)).toBeFalsy(); - }); - }); -}; - -const testUrlGeneration = (userField, searchVal) => { - describe("request querystring", () => { - it("should generate a query string with the expected server-side parameter", () => { - const params = new SearchParams(); - params.filterText = `${userField}="${searchVal}"`; - const serverField = params.getServerFieldName(userField); - if (serverField) { - const qs = params.historyContentQueryString; - const queryParam = `${serverField}-contains=${encodeURIComponent(searchVal)}`; - expect(qs.includes(queryParam)).toBeTruthy(); - } - }); - }); -}; - -// TODO: fix api to actually process the fields that it says it will -const testNotInUrl = (userField, searchVal) => { - describe("request querystring", () => { - it("should not send this filter, because it does not work on the api as described", () => { - const params = new SearchParams(); - params.filterText = `${userField}="${searchVal}"`; - const serverField = params.getServerFieldName(userField); - const qs = params.historyContentQueryString; - expect(qs.includes(serverField)).toBeFalsy(); - }); - }); -}; - -//#endregion - -describe("history contents search field text parsing", () => { - describe("single field criteria", () => { - // name="FASTQC on" - // Any datasets with “FASTQC on” in the title, but avoids items which - // have “FASTQC on” in other fields like the description or annotation. - describe("name", () => { - const searchField = "name"; - const searchTerm = "FASTQC on"; - - const goodDoc = { - _id: "anything", - name: "asfasdfasdfasdf FASTQC onsdfasdfasdf", - visible: true, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - otherField: "asfasdfasdfasdf FASTQC onsdfasdfasdf", - visible: true, - isDeleted: false, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - testUrlGeneration(searchField, searchTerm); - }); - - // format=vcf - // Datasets with a specific format. Some formats are hierarchical, e.g. - // searching for fastq will find fastq files but also fastqsanger and - // fastqillumina files. You can see more formats in the upload dialogue - describe("format", () => { - const searchField = "format"; - const searchTerm = "vcf"; - - const goodDoc = { - _id: "anything", - file_ext: "vcf", - visible: true, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - file_ext: "notgonnamatch", - visible: true, - isDeleted: false, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - testUrlGeneration(searchField, searchTerm); - }); - - // database=hg19 Datasets with a specific reference genome - describe("database", () => { - const searchField = "database"; - const searchTerm = "hg19"; - - const goodDoc = { - _id: "anything", - genome_build: "hg19", - visible: true, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - genome_build: "somethingelse", - visible: true, - isDeleted: false, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - testUrlGeneration(searchField, searchTerm); - }); - - // annotation="first of five" - describe("annotation", () => { - const searchField = "annotation"; - const searchTerm = "first of fiv"; - - const goodDoc = { - _id: "anything", - annotation: "this is the first of five", - visible: true, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - annotation: "somethingelse", - visible: true, - isDeleted: false, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - testNotInUrl(searchField, searchTerm); - }); - - // NOTE: is annotation different from description? - // description="This is data of a Borneo Orangutan" for dataset summary - describe("description (same as annotation?)", () => { - const searchField = "description"; - const searchTerm = "This is data of a Borneo Orangutan"; - - const goodDoc = { - _id: "anything", - annotation: "asdfasdfThis is data of a Borneo Orangutansdfasdf", - visible: true, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - annotation: "somethingelse", - visible: true, - isDeleted: false, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - testNotInUrl(searchField, searchTerm); - }); - - // info="started mapping" - // for searching on job’s info field. - // describe("job info", () => {}); - - // tag=experiment1 tag=to_publish - // for searching on (a partial) dataset tag. - describe("tags", () => { - const searchField = "tags"; - const searchTerm = "experiment1"; - - const goodDoc = { - _id: "anything", - tags: ["experiment1", "experiment2"], - visible: true, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - tags: ["nodice"], - visible: true, - isDeleted: false, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - testUrlGeneration(searchField, searchTerm); - }); - - // hid=25 - // A specific history item ID (based on the ordering in the history) - describe("hid", () => { - const searchField = "hid"; - const searchTerm = 25; - - const goodDoc = { - _id: "anything", - hid: 25, - visible: true, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - hid: 200, - visible: true, - isDeleted: false, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - - describe("request querystring", () => { - it("hid should show up with an =, no text-search", () => { - const params = new SearchParams(); - params.filterText = `${searchField}="${searchTerm}"`; - const qs = params.historyContentQueryString; - const serverField = params.getServerFieldName(searchField); - const fragment = `${serverField}=${searchTerm}`; - expect(qs.includes(fragment)).toBeTruthy(); - }); - }); - }); - - // state=error - // To show only datasets in a given state. Other options include ok, - // running, paused, and new. - describe("state", () => { - const searchField = "state"; - const searchTerm = STATES.OK; - - const goodDoc = { - _id: "anything", - hid: 25, - visible: true, - state: STATES.OK, - isDeleted: false, - }; - - const badDoc = { - _id: "anything", - hid: 200, - visible: true, - isDeleted: false, - state: STATES.ERROR, - }; - - testPouchSelector(searchField, searchTerm, goodDoc, badDoc); - - describe("request querystring", () => { - it("state should show up with an =, no text-search", () => { - const params = new SearchParams(); - params.filterText = `${searchField}="${searchTerm}"`; - const qs = params.historyContentQueryString; - const serverField = params.getServerFieldName(searchField); - const fragment = `${serverField}=${searchTerm}`; - expect(qs.includes(fragment)).toBeTruthy(); - }); - }); - }); - }); - - describe("multiple field criteria", () => { - it("should allow a boolean AND combination of 2 filters", () => { - const goodDoc = { - _id: "anything", - name: "sadfasdffooasdfasdf", - tags: ["abc", "def", "blah"], - visible: true, - isDeleted: false, - }; - - const onlyOneMatch = { - _id: "anything", - name: "sadfasdffooasdfasdf", - visible: true, - isDeleted: false, - }; - - const theOtherMatch = { - _id: "anything", - tags: ["abc", "def", "blah"], - visible: true, - isDeleted: false, - }; - - const params = new SearchParams(); - params.filterText = "name=foo tag=blah"; - - const selector = { $and: params.pouchFilters }; - - expect(matchesSelector(goodDoc, selector)).toBeTruthy(); - expect(matchesSelector(onlyOneMatch, selector)).toBeFalsy(); - expect(matchesSelector(theOtherMatch, selector)).toBeFalsy(); - }); - }); - - // TODO: There is a bug in the mongo query syntax implementation that stops us from having - // two simultaneous criteria for the same field with the same type of operator, example - // can't have { $and: [ { tag: { $regex: /abc/ }, { tag: { $regex: /def/ }}]} - // https://github.com/pouchdb/pouchdb/issues/8265 - - // I'll have to come up with a better solution for that AND intersection feature. - - xdescribe("deferring this functionality for now", () => { - it("should allow a boolean AND combination of 2 of the same filter", () => { - const doc = { - _id: "anything", - name: "abc def", - visible: true, - isDeleted: false, - }; - - // this should match - const params = new SearchParams(); - params.filterText = "name=abc name=def"; - const selector = { $and: params.pouchFilters }; - expect(matchesSelector(doc, selector)).toBeTruthy(); - - // this should not, it fails because of the bug which overwrites the regex on the field, - // making it impossible to run 2 regexes against "name" - const params2 = new SearchParams(); - params2.filterText = "name=sfsfssf name=def"; - const selector2 = params2.buildHistoryContentSelector(); - expect(matchesSelector(doc, selector2)).toBeFalsy(); - }); - - it("should allow a boolean AND combination of 2 filters of for the same field, partial matches", () => { - const doc = { - _id: "anything", - tags: ["abcasdfasdf", "def"], - visible: true, - isDeleted: false, - }; - - // this should match - const params = new SearchParams(); - params.filterText = "tags=abc tag=def"; - const selector = { $and: params.pouchFilters }; - expect(matchesSelector(doc, selector)).toBeTruthy(); - - // this should not - const params2 = new SearchParams(); - params2.filterText = "tags=foo tag=def"; - const selector2 = { $and: params2.pouchFilters }; - expect(matchesSelector(doc, selector2)).toBeFalsy(); - }); - }); -}); diff --git a/client/src/components/providers/History/UserHistories/UserHistories.test.js b/client/src/components/providers/History/UserHistories/UserHistories.test.js index f3dfa4c6264..23eb9cdb8be 100644 --- a/client/src/components/providers/History/UserHistories/UserHistories.test.js +++ b/client/src/components/providers/History/UserHistories/UserHistories.test.js @@ -35,7 +35,6 @@ import { } from "components/History/model/queries"; jest.mock("app"); -jest.mock("components/providers/History/caching"); jest.mock("components/History/model/queries"); const maxServerDelay = 60; diff --git a/client/src/components/providers/History/index.js b/client/src/components/providers/History/index.js index a9b8b60b39c..e95469dd61c 100644 --- a/client/src/components/providers/History/index.js +++ b/client/src/components/providers/History/index.js @@ -3,18 +3,5 @@ * cache or other observables to emit end results as slot props. */ -// These are pretty complex. Input parameters from "the top" are the History or -// selected collection, but they also expose slot-prop methods to update -// internal data such as user-provided filter parameters or the physical -// position of the scroll cursor in the list UI -export { default as HistoryContentProvider } from "./HistoryContentProvider"; -export { default as CollectionContentProvider } from "./CollectionContentProvider"; - -// The DscProvider is only complex because we store dataset collection data in -// two places depending on its place in the data hierarchy. At the root level, a -// dataset collection is stored as history content. But a collection can nest -// other collections, and sub-collections are stored as collection-content -export { default as DscProvider } from "./DscProvider"; - // Management for current user's histories. Largely a passthrough of store methods export { default as UserHistories } from "./UserHistories"; diff --git a/client/src/components/providers/History/test/json/History.json b/client/src/components/providers/History/test/json/History.json deleted file mode 100644 index 95cf20b9cda..00000000000 --- a/client/src/components/providers/History/test/json/History.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "importable": false, - "username_and_slug": null, - "hid_counter": 101, - "contents_url": "/api/histories/2f94e8ae9edff68a/contents", - "annotation": "this is the annotation", - "genome_build": null, - "create_time": "2020-06-22T20:24:57.630416", - "empty": false, - "purged": false, - "update_time": "2020-07-07T21:03:42.514499", - "user_id": "f2db41e1fa331b3e", - "name": "160-ish items", - "slug": null, - "tags": [], - "published": false, - "nice_size": "708 bytes", - "size": 708, - "url": "/api/histories/2f94e8ae9edff68a", - "deleted": false, - "state": "ok", - "id": "2f94e8ae9edff68a" -} diff --git a/client/src/components/providers/History/test/json/collectionContent.json b/client/src/components/providers/History/test/json/collectionContent.json deleted file mode 100644 index 66dcfbd45a6..00000000000 --- a/client/src/components/providers/History/test/json/collectionContent.json +++ /dev/null @@ -1,842 +0,0 @@ -[ - { - "model_class": "DatasetCollectionElement", - "id": "068bb135123e39c3", - "element_type": "hda", - "element_index": 0, - "element_identifier": "0", - "object": { - "id": "e746d19c9c8cc71c", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "cc0e2ba29cc1d8af", - "element_type": "hda", - "element_index": 1, - "element_identifier": "1", - "object": { - "id": "bd2618511bd6d954", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "088766ba409c97ae", - "element_type": "hda", - "element_index": 2, - "element_identifier": "10", - "object": { - "id": "b1aecce06b45adc8", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "e48823c5da673276", - "element_type": "hda", - "element_index": 3, - "element_identifier": "100", - "object": { - "id": "01cda2950d5e63c3", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "cf17043882bf0911", - "element_type": "hda", - "element_index": 4, - "element_identifier": "1000", - "object": { - "id": "5f2de0d744e8c295", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "a088eb6d1a3dbcab", - "element_type": "hda", - "element_index": 5, - "element_identifier": "10000", - "object": { - "id": "43bce5ef002caad3", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "35cddac7ff46d42d", - "element_type": "hda", - "element_index": 6, - "element_identifier": "100000", - "object": { - "id": "5fb23b4e4319a7c5", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "eac6cd9007b1908f", - "element_type": "hda", - "element_index": 7, - "element_identifier": "100001", - "object": { - "id": "80233f5f28a6c72f", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "aa4f9dc4708b54b6", - "element_type": "hda", - "element_index": 8, - "element_identifier": "100002", - "object": { - "id": "1c5156c6a0363f35", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "cbd3da2c4f117e14", - "element_type": "hda", - "element_index": 9, - "element_identifier": "100003", - "object": { - "id": "af091cf96ab275f3", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "68a588a2a9524bc5", - "element_type": "hda", - "element_index": 10, - "element_identifier": "100004", - "object": { - "id": "97b2c68eeabafb3d", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "a58d0afa3c515242", - "element_type": "hda", - "element_index": 11, - "element_identifier": "100005", - "object": { - "id": "33867d668bd83fde", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "f0c8870154edf2d6", - "element_type": "hda", - "element_index": 12, - "element_identifier": "100006", - "object": { - "id": "1914213279532687", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "018c8c5d62a8df97", - "element_type": "hda", - "element_index": 13, - "element_identifier": "100007", - "object": { - "id": "713b988311601359", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "d0c151b99af9360b", - "element_type": "hda", - "element_index": 14, - "element_identifier": "100008", - "object": { - "id": "f38a73020009daba", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "29eac6dcbd14f883", - "element_type": "hda", - "element_index": 15, - "element_identifier": "100009", - "object": { - "id": "622229cf50f04387", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "a158574d58234118", - "element_type": "hda", - "element_index": 16, - "element_identifier": "10001", - "object": { - "id": "b68d17846c7fbc83", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "2b98540a14173828", - "element_type": "hda", - "element_index": 17, - "element_identifier": "100010", - "object": { - "id": "6eeb1155086b617b", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "8e114d54b2d1f419", - "element_type": "hda", - "element_index": 18, - "element_identifier": "100011", - "object": { - "id": "e7746068f68fc864", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "749fa1ed60051f98", - "element_type": "hda", - "element_index": 19, - "element_identifier": "100012", - "object": { - "id": "8051d6590bfd64e9", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "911f2df796ad747c", - "element_type": "hda", - "element_index": 20, - "element_identifier": "100013", - "object": { - "id": "5cba928dd1a05f48", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "faa6c009defd91d0", - "element_type": "hda", - "element_index": 21, - "element_identifier": "100014", - "object": { - "id": "eac6ce67595195ec", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "6129b0ae6f8527f0", - "element_type": "hda", - "element_index": 22, - "element_identifier": "100015", - "object": { - "id": "98d427a4631d635a", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "789438fb3dff9d11", - "element_type": "hda", - "element_index": 23, - "element_identifier": "100016", - "object": { - "id": "ddf8d1e1eb7b0fb7", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "a7d7479d06608eca", - "element_type": "hda", - "element_index": 24, - "element_identifier": "100017", - "object": { - "id": "7083648ea486ebf6", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "440b7cc14c8c4d06", - "element_type": "hda", - "element_index": 25, - "element_identifier": "100018", - "object": { - "id": "aaf0f2ebe11ae45c", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "fb4f28349f5baf2d", - "element_type": "hda", - "element_index": 26, - "element_identifier": "100019", - "object": { - "id": "c78ca882684b7434", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "87fd7db76c544224", - "element_type": "hda", - "element_index": 27, - "element_identifier": "10002", - "object": { - "id": "c9c548cca771bdbc", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "a9431fe40e66ea34", - "element_type": "hda", - "element_index": 28, - "element_identifier": "100020", - "object": { - "id": "2fbde361d6a31e7e", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "43acf2f33287edcb", - "element_type": "hda", - "element_index": 29, - "element_identifier": "100021", - "object": { - "id": "b73abcd044761674", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "9a74eaab42e02827", - "element_type": "hda", - "element_index": 30, - "element_identifier": "100022", - "object": { - "id": "7326e2004b6d8758", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "6d8e4d965b771ea5", - "element_type": "hda", - "element_index": 31, - "element_identifier": "100023", - "object": { - "id": "e16a1758d8c32a91", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "c69237419b0ccecb", - "element_type": "hda", - "element_index": 32, - "element_identifier": "100024", - "object": { - "id": "16d9d7a5407b90bb", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "2d09ebff4dc98b05", - "element_type": "hda", - "element_index": 33, - "element_identifier": "100025", - "object": { - "id": "be6aaa8b33c20354", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "359f5b7c99fbb2a6", - "element_type": "hda", - "element_index": 34, - "element_identifier": "100026", - "object": { - "id": "f0d2dd7ce1a0d1d7", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "890b48f1534ba81c", - "element_type": "hda", - "element_index": 35, - "element_identifier": "100027", - "object": { - "id": "a4243929ecd1e137", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "4220951a437ba60e", - "element_type": "hda", - "element_index": 36, - "element_identifier": "100028", - "object": { - "id": "efdbb5c431ed86c4", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "f306434746a46cb6", - "element_type": "hda", - "element_index": 37, - "element_identifier": "100029", - "object": { - "id": "0c7525f276af0cb2", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "abc747938ed8a600", - "element_type": "hda", - "element_index": 38, - "element_identifier": "10003", - "object": { - "id": "0032a856b26c744e", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "63636a455c5b21fa", - "element_type": "hda", - "element_index": 39, - "element_identifier": "100030", - "object": { - "id": "aa1ea414cbd09e79", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "e8c3a4e75936ee34", - "element_type": "hda", - "element_index": 40, - "element_identifier": "100031", - "object": { - "id": "9a0d644f6e3ebb6f", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "25dce1f99c32a06f", - "element_type": "hda", - "element_index": 41, - "element_identifier": "100032", - "object": { - "id": "c6d7ec9dd85960fd", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "0f308c8bc2dba01e", - "element_type": "hda", - "element_index": 42, - "element_identifier": "100033", - "object": { - "id": "c1e28fb74593e606", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "134707f5254d3467", - "element_type": "hda", - "element_index": 43, - "element_identifier": "100034", - "object": { - "id": "edb9e58b575cfb18", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "af2a47bf25ac31c6", - "element_type": "hda", - "element_index": 44, - "element_identifier": "100035", - "object": { - "id": "595375e544772627", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "9b4142aa13cacd8d", - "element_type": "hda", - "element_index": 45, - "element_identifier": "100036", - "object": { - "id": "d917f9554bc7b276", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "8732705714d1b967", - "element_type": "hda", - "element_index": 46, - "element_identifier": "100037", - "object": { - "id": "17ac36cd25e09d75", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "9faac61c404df8d0", - "element_type": "hda", - "element_index": 47, - "element_identifier": "100038", - "object": { - "id": "fc587326c65e935c", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "eec6329884514299", - "element_type": "hda", - "element_index": 48, - "element_identifier": "100039", - "object": { - "id": "0f1c2717b9554064", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "0a7c50c76808cb45", - "element_type": "hda", - "element_index": 49, - "element_identifier": "10004", - "object": { - "id": "175262dbcbd9987f", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "1ff31d34983529f8", - "element_type": "hda", - "element_index": 50, - "element_identifier": "100040", - "object": { - "id": "7c3fb968df7e50f1", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "0af255ba4961216c", - "element_type": "hda", - "element_index": 51, - "element_identifier": "100041", - "object": { - "id": "cf83f2dcc9f7362b", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "5be07bbe21af2e4a", - "element_type": "hda", - "element_index": 52, - "element_identifier": "100042", - "object": { - "id": "4efb7c25e2bb7fa8", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "8ab1435b8102e81e", - "element_type": "hda", - "element_index": 53, - "element_identifier": "100043", - "object": { - "id": "defeea39a9509c16", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "842e3a8e9b827812", - "element_type": "hda", - "element_index": 54, - "element_identifier": "100044", - "object": { - "id": "5f5b885264688585", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "a5824a57e59503dc", - "element_type": "hda", - "element_index": 55, - "element_identifier": "100045", - "object": { - "id": "041689872363985f", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "616698141b35a61f", - "element_type": "hda", - "element_index": 56, - "element_identifier": "100046", - "object": { - "id": "2839cb63aea76bb4", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "d36010717df75f3d", - "element_type": "hda", - "element_index": 57, - "element_identifier": "100047", - "object": { - "id": "4236bdc00992172f", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "f5d1282ba4e61ea9", - "element_type": "hda", - "element_index": 58, - "element_identifier": "100048", - "object": { - "id": "bf8ded787d0c5b53", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - }, - { - "model_class": "DatasetCollectionElement", - "id": "8dc4bd112d29b27d", - "element_type": "hda", - "element_index": 59, - "element_identifier": "100049", - "object": { - "id": "023453c935463dba", - "model_class": "HistoryDatasetAssociation", - "state": "ok", - "hda_ldda": "hda", - "history_id": "e90facaf332c3038" - } - } -] diff --git a/client/src/components/providers/History/test/json/collectionContent.nested.json b/client/src/components/providers/History/test/json/collectionContent.nested.json deleted file mode 100644 index 59f5c7aa840..00000000000 --- a/client/src/components/providers/History/test/json/collectionContent.nested.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "element_identifier": "forward", - "object": { - "hda_ldda": "hda", - "history_id": "4ff6f47412c3e65e", - "state": "ok", - "model_class": "HistoryDatasetAssociation", - "id": "d5836ddca35af8fe" - }, - "id": "40876639881ca029", - "element_index": 0, - "element_type": "hda", - "model_class": "DatasetCollectionElement" - }, - { - "element_identifier": "reverse", - "object": { - "hda_ldda": "hda", - "history_id": "4ff6f47412c3e65e", - "state": "ok", - "model_class": "HistoryDatasetAssociation", - "id": "c1209dcf6a15c53b" - }, - "id": "d071e794759ab192", - "element_index": 1, - "element_type": "hda", - "model_class": "DatasetCollectionElement" - } -] diff --git a/client/src/components/providers/History/test/json/historyContent.json b/client/src/components/providers/History/test/json/historyContent.json deleted file mode 100644 index 21240416443..00000000000 --- a/client/src/components/providers/History/test/json/historyContent.json +++ /dev/null @@ -1,2797 +0,0 @@ -[ - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "9c019bbfa7322549", - "name": "Select random lines on data 108", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:14.598049", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1151.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "cffbf0b3-37f5-44d7-845c-daef7bab22a3", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-ee74a7a2152289f5", - "url": "/api/histories/2f94e8ae9edff68a/contents/ee74a7a2152289f5", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 165, - "visible": true, - "creating_job": "9c019bbfa7322549", - "update_time": "2020-07-02T17:14:35.084070", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/ee74a7a2152289f5/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "ee74a7a2152289f5" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "0fec89153aa8743d", - "name": "Select random lines on data 107", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:14.358836", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1150.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "e8b1cd57-9d0b-47d3-8dd4-8bb1515d5c01", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-65b05d9846015547", - "url": "/api/histories/2f94e8ae9edff68a/contents/65b05d9846015547", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 164, - "visible": false, - "creating_job": "0fec89153aa8743d", - "update_time": "2020-07-02T17:14:30.779839", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/65b05d9846015547/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "65b05d9846015547" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "182bab19390d12f7", - "name": "Select random lines on data 106", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:13.967109", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1149.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "0ff390c7-4c59-4076-84e7-a932c62679b0", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-bf99977736808be6", - "url": "/api/histories/2f94e8ae9edff68a/contents/bf99977736808be6", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 163, - "visible": false, - "creating_job": "182bab19390d12f7", - "update_time": "2020-07-02T17:14:30.801856", - "rerunnable": true, - "deleted": true, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/bf99977736808be6/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "bf99977736808be6" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "6df8ec04e60b3b26", - "name": "Select random lines on data 105", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:13.680997", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1148.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "eee66bc1-c344-4e6f-aa70-64c8e71086d2", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-9d5d229c62e3f271", - "url": "/api/histories/2f94e8ae9edff68a/contents/9d5d229c62e3f271", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 162, - "visible": true, - "creating_job": "6df8ec04e60b3b26", - "update_time": "2020-07-02T17:14:30.742075", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/9d5d229c62e3f271/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "9d5d229c62e3f271" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "3cdbf23a5a13103b", - "name": "Select random lines on data 104", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:13.540450", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1147.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "7b6b8d9a-bbd0-454c-900f-c2bdfc0b771e", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-e87d5b3bf14d5c06", - "url": "/api/histories/2f94e8ae9edff68a/contents/e87d5b3bf14d5c06", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 161, - "visible": true, - "creating_job": "3cdbf23a5a13103b", - "update_time": "2020-07-02T17:14:29.392503", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/e87d5b3bf14d5c06/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "e87d5b3bf14d5c06" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "ada85e82199e3fc1", - "name": "Select random lines on data 103", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:13.450379", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1146.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "7368bd7f-63d3-41c6-9869-7443dd36ab58", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-01611285b1b754d4", - "url": "/api/histories/2f94e8ae9edff68a/contents/01611285b1b754d4", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 160, - "visible": true, - "creating_job": "ada85e82199e3fc1", - "update_time": "2020-07-02T17:14:21.003319", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/01611285b1b754d4/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "01611285b1b754d4" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "e4b800ee43da817e", - "name": "Select random lines on data 102", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:13.156049", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1145.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "c0572def-614f-46f0-b0f1-c7c53330b068", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-21fb8edef9e06aee", - "url": "/api/histories/2f94e8ae9edff68a/contents/21fb8edef9e06aee", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 159, - "visible": true, - "creating_job": "e4b800ee43da817e", - "update_time": "2020-07-02T17:14:21.028645", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/21fb8edef9e06aee/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "21fb8edef9e06aee" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "13b397a1ea2c1dbf", - "name": "Select random lines on data 101", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:12.918074", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1144.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "01522715-eb0e-421d-8bc7-42a3785a8bbe", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-e2cd7fe532848756", - "url": "/api/histories/2f94e8ae9edff68a/contents/e2cd7fe532848756", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 158, - "visible": true, - "creating_job": "13b397a1ea2c1dbf", - "update_time": "2020-07-02T17:14:20.944971", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/e2cd7fe532848756/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "e2cd7fe532848756" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "169175a66f863459", - "name": "Select random lines on data 100", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:12.595760", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1143.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "ef597777-20ac-4d3e-a5d9-99e09fd38831", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-9d5bdb551832597a", - "url": "/api/histories/2f94e8ae9edff68a/contents/9d5bdb551832597a", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 157, - "visible": true, - "creating_job": "169175a66f863459", - "update_time": "2020-07-02T17:14:20.145028", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/9d5bdb551832597a/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "9d5bdb551832597a" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "43c04a4df15a1f7a", - "name": "Select random lines on data 99", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:12.417473", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1142.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "3f477ffd-7e06-4c60-85d3-11e1ee251ef3", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-0d7418ad8754e1ba", - "url": "/api/histories/2f94e8ae9edff68a/contents/0d7418ad8754e1ba", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 156, - "visible": true, - "creating_job": "43c04a4df15a1f7a", - "update_time": "2020-07-02T17:14:08.322766", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/0d7418ad8754e1ba/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "0d7418ad8754e1ba" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "78176dfc865c8302", - "name": "Select random lines on data 98", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:12.126872", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1141.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "719fa5b5-f898-45f3-a279-76329c6913b4", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-cc5fb41fa467c62f", - "url": "/api/histories/2f94e8ae9edff68a/contents/cc5fb41fa467c62f", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 155, - "visible": true, - "creating_job": "78176dfc865c8302", - "update_time": "2020-07-02T17:14:08.341521", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/cc5fb41fa467c62f/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "cc5fb41fa467c62f" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "7e5a6282b7150cce", - "name": "Select random lines on data 97", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:11.898501", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1140.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "9ec6c5fc-08da-44d7-8259-3179c95689bb", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-be164d1018ed2499", - "url": "/api/histories/2f94e8ae9edff68a/contents/be164d1018ed2499", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 154, - "visible": true, - "creating_job": "7e5a6282b7150cce", - "update_time": "2020-07-02T17:14:06.969005", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/be164d1018ed2499/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "be164d1018ed2499" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "fb1af791c00dd0e4", - "name": "Select random lines on data 96", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:11.636493", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1139.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "7904faba-9cfe-411c-bf5d-2e52b80c6d63", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-9c7fc3db9aebaa60", - "url": "/api/histories/2f94e8ae9edff68a/contents/9c7fc3db9aebaa60", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 153, - "visible": true, - "creating_job": "fb1af791c00dd0e4", - "update_time": "2020-07-02T17:14:08.355740", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/9c7fc3db9aebaa60/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "9c7fc3db9aebaa60" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "18c1ddee9d6509e0", - "name": "Select random lines on data 95", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:11.276238", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1138.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "023752c7-6fad-4eef-accf-cdf7a6624788", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-5583febb78070f6e", - "url": "/api/histories/2f94e8ae9edff68a/contents/5583febb78070f6e", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 152, - "visible": true, - "creating_job": "18c1ddee9d6509e0", - "update_time": "2020-07-02T17:13:55.258074", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/5583febb78070f6e/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "5583febb78070f6e" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "fae76ced2b7e97d7", - "name": "Select random lines on data 94", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:10.847345", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1137.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "70900478-12a9-43a1-ab04-3ca3c4445592", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-a3034dc0fe6363f2", - "url": "/api/histories/2f94e8ae9edff68a/contents/a3034dc0fe6363f2", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 151, - "visible": true, - "creating_job": "fae76ced2b7e97d7", - "update_time": "2020-07-02T17:13:55.210624", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/a3034dc0fe6363f2/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "a3034dc0fe6363f2" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "07630b166a59bdad", - "name": "Select random lines on data 93", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:10.630512", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1136.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "3703cf59-cecf-47a0-a96d-638f66ecf58d", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-e865c3fa6b646e8b", - "url": "/api/histories/2f94e8ae9edff68a/contents/e865c3fa6b646e8b", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 150, - "visible": true, - "creating_job": "07630b166a59bdad", - "update_time": "2020-07-02T17:13:55.253801", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/e865c3fa6b646e8b/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "e865c3fa6b646e8b" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "13c07ce0ed2cea74", - "name": "Select random lines on data 92", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:10.474227", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1135.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "bf91813f-e082-40cf-a0a8-85a9646eeb00", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-fc39b4da94a2e68f", - "url": "/api/histories/2f94e8ae9edff68a/contents/fc39b4da94a2e68f", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 149, - "visible": true, - "creating_job": "13c07ce0ed2cea74", - "update_time": "2020-07-02T17:13:54.932915", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/fc39b4da94a2e68f/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "fc39b4da94a2e68f" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "4a86c8de6f7e9376", - "name": "Select random lines on data 91", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:10.341217", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1134.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "12233e16-7128-4bdc-a708-12b29607823f", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-bb349edfde212365", - "url": "/api/histories/2f94e8ae9edff68a/contents/bb349edfde212365", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 148, - "visible": true, - "creating_job": "4a86c8de6f7e9376", - "update_time": "2020-07-02T17:13:44.549193", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/bb349edfde212365/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "bb349edfde212365" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "0ff195fdd529b966", - "name": "Select random lines on data 90", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:10.196285", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1133.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "44525832-3a54-4e36-be65-b584141846f8", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-129ca6c26a6931c9", - "url": "/api/histories/2f94e8ae9edff68a/contents/129ca6c26a6931c9", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 147, - "visible": false, - "creating_job": "0ff195fdd529b966", - "update_time": "2020-07-02T17:13:44.566149", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/129ca6c26a6931c9/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "129ca6c26a6931c9" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "80c7a7e8240dd658", - "name": "Select random lines on data 87", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:10.068164", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1132.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "a85c004f-c513-4e04-b8f8-a83dbf8a2975", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-8c4acef511ce6a13", - "url": "/api/histories/2f94e8ae9edff68a/contents/8c4acef511ce6a13", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 146, - "visible": true, - "creating_job": "80c7a7e8240dd658", - "update_time": "2020-07-02T17:13:44.501758", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/8c4acef511ce6a13/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "8c4acef511ce6a13" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "5786ce0546cbc07f", - "name": "Select random lines on data 86", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:09.895745", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1131.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "e2d0cbd2-db2e-45e9-8ddc-43f939ade175", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-cb39084e4b94595e", - "url": "/api/histories/2f94e8ae9edff68a/contents/cb39084e4b94595e", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 145, - "visible": true, - "creating_job": "5786ce0546cbc07f", - "update_time": "2020-07-02T17:13:44.540544", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/cb39084e4b94595e/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "cb39084e4b94595e" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "26d704460e4a4985", - "name": "Select random lines on data 85", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:09.779313", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1130.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "ecf8e87f-0512-4129-8acb-f1b22fc44af9", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-a54402b4d6323562", - "url": "/api/histories/2f94e8ae9edff68a/contents/a54402b4d6323562", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 144, - "visible": true, - "creating_job": "26d704460e4a4985", - "update_time": "2020-07-02T17:13:35.150171", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/a54402b4d6323562/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "a54402b4d6323562" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "dc72786b0d4875fb", - "name": "Select random lines on data 84", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:09.462394", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1129.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "575ca4f6-6e7c-4890-922b-462e6f4ba055", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-b0ac2b753662f808", - "url": "/api/histories/2f94e8ae9edff68a/contents/b0ac2b753662f808", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 143, - "visible": true, - "creating_job": "dc72786b0d4875fb", - "update_time": "2020-07-02T17:13:35.215070", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/b0ac2b753662f808/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "b0ac2b753662f808" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "303d4722059b63c2", - "name": "Select random lines on data 83", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:09.024308", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1128.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "660e243c-c794-43ba-b070-f6ffa67941e8", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-0bb53d1c0b73db00", - "url": "/api/histories/2f94e8ae9edff68a/contents/0bb53d1c0b73db00", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 142, - "visible": true, - "creating_job": "303d4722059b63c2", - "update_time": "2020-07-02T17:13:35.048004", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/0bb53d1c0b73db00/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "0bb53d1c0b73db00" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "e373ca7c82675833", - "name": "Select random lines on data 82", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:08.839549", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1127.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "d06c6b69-32e0-46a4-9f63-b5e6a6b7b8f9", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-c8d221932b740453", - "url": "/api/histories/2f94e8ae9edff68a/contents/c8d221932b740453", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 141, - "visible": true, - "creating_job": "e373ca7c82675833", - "update_time": "2020-07-02T17:13:34.966640", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/c8d221932b740453/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "c8d221932b740453" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "4969f1ebf8379add", - "name": "Select random lines on data 81", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:08.678261", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1126.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "ad3c7ddf-93d7-4102-8b65-6ee950c0e53e", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-fd5d271453b419bf", - "url": "/api/histories/2f94e8ae9edff68a/contents/fd5d271453b419bf", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 140, - "visible": true, - "creating_job": "4969f1ebf8379add", - "update_time": "2020-07-02T17:13:26.515907", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/fd5d271453b419bf/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "fd5d271453b419bf" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "871ce98d8c078309", - "name": "Select random lines on data 80", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:08.439740", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1125.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "85228002-5316-4408-8b30-d47e0687b47b", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-1b558b31eb840782", - "url": "/api/histories/2f94e8ae9edff68a/contents/1b558b31eb840782", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 139, - "visible": true, - "creating_job": "871ce98d8c078309", - "update_time": "2020-07-02T17:13:26.064511", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/1b558b31eb840782/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "1b558b31eb840782" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "1bca6b54cf56afed", - "name": "Select random lines on data 79", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:08.204846", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1124.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "e211cd1b-77d9-4b7d-b30c-7d4cd21b80dd", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-c1cba22c86ef1135", - "url": "/api/histories/2f94e8ae9edff68a/contents/c1cba22c86ef1135", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 138, - "visible": true, - "creating_job": "1bca6b54cf56afed", - "update_time": "2020-07-02T17:13:26.420395", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/c1cba22c86ef1135/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "c1cba22c86ef1135" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "8be3d18182a9e60b", - "name": "Select random lines on data 78", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:07.956424", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1123.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "5e3b5d07-2cb3-4360-afa9-35e939cae35e", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-d5974bc21ed0134c", - "url": "/api/histories/2f94e8ae9edff68a/contents/d5974bc21ed0134c", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 137, - "visible": true, - "creating_job": "8be3d18182a9e60b", - "update_time": "2020-07-02T17:13:26.380713", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/d5974bc21ed0134c/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "d5974bc21ed0134c" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "0375199fa16cf1e6", - "name": "Select random lines on data 77", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:07.838633", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1122.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "0262a34f-2f67-4f2a-afcd-1dafef6b8452", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-ef9838f9f223749f", - "url": "/api/histories/2f94e8ae9edff68a/contents/ef9838f9f223749f", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 136, - "visible": true, - "creating_job": "0375199fa16cf1e6", - "update_time": "2020-07-02T17:13:14.970221", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/ef9838f9f223749f/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "ef9838f9f223749f" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "b1da20f285d33353", - "name": "Select random lines on data 76", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:07.554284", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1121.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "217d8f4c-ab9f-44d4-bd48-1ef9ecf932cf", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-5f7733bbff4769c3", - "url": "/api/histories/2f94e8ae9edff68a/contents/5f7733bbff4769c3", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 135, - "visible": true, - "creating_job": "b1da20f285d33353", - "update_time": "2020-07-02T17:13:14.952092", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/5f7733bbff4769c3/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "5f7733bbff4769c3" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "a83adc160e0a77a0", - "name": "Select random lines on data 75", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:07.291121", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1120.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "f5f0dffa-4fe6-4bb9-9ddc-02fe75edb0f7", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-046c7f452ce7fd20", - "url": "/api/histories/2f94e8ae9edff68a/contents/046c7f452ce7fd20", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 134, - "visible": true, - "creating_job": "a83adc160e0a77a0", - "update_time": "2020-07-02T17:13:14.865652", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/046c7f452ce7fd20/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "046c7f452ce7fd20" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "3a437f8167ca4c87", - "name": "Select random lines on data 74", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:07.176345", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1119.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "82bd2e95-d89e-4e7a-aa98-58f96c004031", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-ff404b57ba36c247", - "url": "/api/histories/2f94e8ae9edff68a/contents/ff404b57ba36c247", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 133, - "visible": true, - "creating_job": "3a437f8167ca4c87", - "update_time": "2020-07-02T17:13:14.880696", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/ff404b57ba36c247/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "ff404b57ba36c247" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "39ac0e5728f31c3f", - "name": "Select random lines on data 73", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:07.015882", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1118.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "42146c48-a85e-4dc1-a3a3-1d8b34a56369", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-514bfe2c97b0d65e", - "url": "/api/histories/2f94e8ae9edff68a/contents/514bfe2c97b0d65e", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 132, - "visible": true, - "creating_job": "39ac0e5728f31c3f", - "update_time": "2020-07-02T17:13:04.669701", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/514bfe2c97b0d65e/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "514bfe2c97b0d65e" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "a87795113868c92b", - "name": "Select random lines on data 72", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:06.805947", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1117.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "9b0bce06-f1cc-4e6c-ba8c-08bd8b383b55", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-2bb5f5a4f02e625e", - "url": "/api/histories/2f94e8ae9edff68a/contents/2bb5f5a4f02e625e", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 131, - "visible": true, - "creating_job": "a87795113868c92b", - "update_time": "2020-07-02T17:13:04.593101", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/2bb5f5a4f02e625e/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "2bb5f5a4f02e625e" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "1fe8025a3eb5c482", - "name": "Select random lines on data 71", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:06.640136", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1116.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "3912edb6-4098-40c0-9897-2ace659cf519", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-fb5d33f2616836cb", - "url": "/api/histories/2f94e8ae9edff68a/contents/fb5d33f2616836cb", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 130, - "visible": true, - "creating_job": "1fe8025a3eb5c482", - "update_time": "2020-07-02T17:13:04.641115", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/fb5d33f2616836cb/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "fb5d33f2616836cb" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "6e01c0e0a145bde3", - "name": "Select random lines on data 70", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:06.390560", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1115.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "ea8b3418-b28c-471c-b0e9-776d71b5b981", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-e6c0d6c692fcb434", - "url": "/api/histories/2f94e8ae9edff68a/contents/e6c0d6c692fcb434", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 129, - "visible": true, - "creating_job": "6e01c0e0a145bde3", - "update_time": "2020-07-02T17:13:04.355401", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/e6c0d6c692fcb434/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "e6c0d6c692fcb434" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "be439a3589617e67", - "name": "Select random lines on data 69", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:06.151651", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1114.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "2dfe3fb3-43b8-4ff1-9bdc-622c48bd8dea", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-0c92c65fab74b1a4", - "url": "/api/histories/2f94e8ae9edff68a/contents/0c92c65fab74b1a4", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 128, - "visible": true, - "creating_job": "be439a3589617e67", - "update_time": "2020-07-02T17:12:55.245423", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/0c92c65fab74b1a4/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "0c92c65fab74b1a4" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "d216b0eb84f63cf4", - "name": "Select random lines on data 68", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:05.962884", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1113.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "e252492a-bcc7-431c-b34a-fdad068b1e0a", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-6bf3b9c89dac7d31", - "url": "/api/histories/2f94e8ae9edff68a/contents/6bf3b9c89dac7d31", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 127, - "visible": true, - "creating_job": "d216b0eb84f63cf4", - "update_time": "2020-07-02T17:12:55.242585", - "rerunnable": true, - "deleted": true, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/6bf3b9c89dac7d31/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "6bf3b9c89dac7d31" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "f7bbb5e66d40415a", - "name": "Select random lines on data 67", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:05.703961", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1112.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "ab55aa3e-d0b2-4996-a986-fdee374e19e3", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-4fe86edec13b16fc", - "url": "/api/histories/2f94e8ae9edff68a/contents/4fe86edec13b16fc", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 126, - "visible": true, - "creating_job": "f7bbb5e66d40415a", - "update_time": "2020-07-02T17:12:55.219388", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/4fe86edec13b16fc/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "4fe86edec13b16fc" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "dcf349068765fa56", - "name": "Select random lines on data 66", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:05.319558", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1111.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "93ab479e-b545-48ce-a9e2-d6ecebfd8ee4", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-93d8baed04ca4af1", - "url": "/api/histories/2f94e8ae9edff68a/contents/93d8baed04ca4af1", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 125, - "visible": true, - "creating_job": "dcf349068765fa56", - "update_time": "2020-07-02T17:12:55.201945", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/93d8baed04ca4af1/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "93d8baed04ca4af1" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "556237b7328da3af", - "name": "Select random lines on data 65", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:05.085542", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1110.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "6925b3a8-c31e-4180-ac51-c001568f2937", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-cf9547eabff54bee", - "url": "/api/histories/2f94e8ae9edff68a/contents/cf9547eabff54bee", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 124, - "visible": true, - "creating_job": "556237b7328da3af", - "update_time": "2020-07-02T17:12:45.807635", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/cf9547eabff54bee/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "cf9547eabff54bee" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "ed7fb4075bcdedec", - "name": "Select random lines on data 64", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:04.680743", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1109.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "abe20394-e9ad-4d4f-acb7-408bf7681a16", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-f70e420d6812c25f", - "url": "/api/histories/2f94e8ae9edff68a/contents/f70e420d6812c25f", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 123, - "visible": true, - "creating_job": "ed7fb4075bcdedec", - "update_time": "2020-07-02T17:12:45.746180", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/f70e420d6812c25f/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "f70e420d6812c25f" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "c1736909009d5cef", - "name": "Select random lines on data 63", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:03.908014", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1108.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "89b5a86f-6699-49fd-acad-2e968c16ad19", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-131a180e703d5f4c", - "url": "/api/histories/2f94e8ae9edff68a/contents/131a180e703d5f4c", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 122, - "visible": true, - "creating_job": "c1736909009d5cef", - "update_time": "2020-07-02T17:12:45.669314", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/131a180e703d5f4c/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "131a180e703d5f4c" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "5d2948302cdb9e75", - "name": "Select random lines on data 62", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:03.536610", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1107.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "98a90a2f-095d-4d3d-a396-1b873a27ced3", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-f23e895e293d0e9b", - "url": "/api/histories/2f94e8ae9edff68a/contents/f23e895e293d0e9b", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 121, - "visible": true, - "creating_job": "5d2948302cdb9e75", - "update_time": "2020-07-02T17:12:45.670944", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/f23e895e293d0e9b/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "f23e895e293d0e9b" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "a27b5c37ceef7a82", - "name": "Select random lines on data 61", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:03.286832", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1106.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "e2b38c6b-92c4-4bf5-9eea-21a26ff7e20d", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-014dd2f744a04c28", - "url": "/api/histories/2f94e8ae9edff68a/contents/014dd2f744a04c28", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 120, - "visible": true, - "creating_job": "a27b5c37ceef7a82", - "update_time": "2020-07-02T17:12:36.747722", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/014dd2f744a04c28/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "014dd2f744a04c28" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "d76cd3ffbd3d6b3a", - "name": "Select random lines on data 60", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:02.981696", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1105.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "25d49a2b-e698-4302-a95d-f79ebf875eb3", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-74040d11a5878de0", - "url": "/api/histories/2f94e8ae9edff68a/contents/74040d11a5878de0", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 119, - "visible": true, - "creating_job": "d76cd3ffbd3d6b3a", - "update_time": "2020-07-02T17:12:36.722427", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/74040d11a5878de0/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "74040d11a5878de0" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "05bf548021f41f6c", - "name": "Select random lines on data 59", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:02.595473", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1104.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "f574e108-11de-4446-a893-22039c1d59ad", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-055cc08a240db326", - "url": "/api/histories/2f94e8ae9edff68a/contents/055cc08a240db326", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 118, - "visible": true, - "creating_job": "05bf548021f41f6c", - "update_time": "2020-07-02T17:12:36.438954", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/055cc08a240db326/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "055cc08a240db326" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "c3e6313f0f678209", - "name": "Select random lines on data 58", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:02.244714", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1103.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "8bed0b33-ba35-46f7-9b28-cdd36e2b1887", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-8cd34530378e3e0c", - "url": "/api/histories/2f94e8ae9edff68a/contents/8cd34530378e3e0c", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 117, - "visible": true, - "creating_job": "c3e6313f0f678209", - "update_time": "2020-07-02T17:12:36.291137", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/8cd34530378e3e0c/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "8cd34530378e3e0c" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "ba195747b0d051d6", - "name": "Select random lines on data 57", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:01.955466", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1102.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "58ec487d-bbdc-43f7-9bdf-e6b0eff72b17", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-39c71ca2ebd30e0b", - "url": "/api/histories/2f94e8ae9edff68a/contents/39c71ca2ebd30e0b", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 116, - "visible": true, - "creating_job": "ba195747b0d051d6", - "update_time": "2020-07-02T17:12:26.178251", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/39c71ca2ebd30e0b/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "39c71ca2ebd30e0b" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "a96cf1e0fad42ad9", - "name": "Select random lines on data 56", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:01.696373", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1101.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "1ebcb32a-d067-417d-a686-ecc53042d756", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-fd71395d8c0f1155", - "url": "/api/histories/2f94e8ae9edff68a/contents/fd71395d8c0f1155", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 115, - "visible": true, - "creating_job": "a96cf1e0fad42ad9", - "update_time": "2020-07-02T17:12:26.293059", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/fd71395d8c0f1155/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "fd71395d8c0f1155" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "9105f12a25bf5d9e", - "name": "Select random lines on data 55", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:01.458797", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1100.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "1e45365d-20b2-4ec8-83d6-43581ffad771", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-d1e91c3db64140b0", - "url": "/api/histories/2f94e8ae9edff68a/contents/d1e91c3db64140b0", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 114, - "visible": true, - "creating_job": "9105f12a25bf5d9e", - "update_time": "2020-07-02T17:12:25.921361", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/d1e91c3db64140b0/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "d1e91c3db64140b0" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "e51a9291655ff7cd", - "name": "Select random lines on data 54", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:01.241452", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1099.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "b27dbd12-2ceb-44a1-997c-4ab968d48265", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-c0dd61e7648dddfe", - "url": "/api/histories/2f94e8ae9edff68a/contents/c0dd61e7648dddfe", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 113, - "visible": true, - "creating_job": "e51a9291655ff7cd", - "update_time": "2020-07-02T17:12:25.829743", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/c0dd61e7648dddfe/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "c0dd61e7648dddfe" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "4a3277a7f1f97c58", - "name": "Select random lines on data 4", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:01.016513", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1098.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "72804271-fab6-4ffe-a00f-fce78dd1d2ec", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-9bad2b56849bec8b", - "url": "/api/histories/2f94e8ae9edff68a/contents/9bad2b56849bec8b", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 112, - "visible": true, - "creating_job": "4a3277a7f1f97c58", - "update_time": "2020-07-02T17:12:15.459958", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/9bad2b56849bec8b/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "9bad2b56849bec8b" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "233d8b78eeff8302", - "name": "Select random lines on data 3", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:00.821573", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1097.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "ff0a7e87-ef17-4d21-8adf-e777ee9b552f", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-ac86fc9298249ba8", - "url": "/api/histories/2f94e8ae9edff68a/contents/ac86fc9298249ba8", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 111, - "visible": true, - "creating_job": "233d8b78eeff8302", - "update_time": "2020-07-02T17:12:15.528769", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/ac86fc9298249ba8/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "ac86fc9298249ba8" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "09ac4927b877e47e", - "name": "Select random lines on data 2", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:00.597906", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1096.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "7f4da894-7294-452d-a954-190a74ecb695", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-a6171316c00d613f", - "url": "/api/histories/2f94e8ae9edff68a/contents/a6171316c00d613f", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 110, - "visible": true, - "creating_job": "09ac4927b877e47e", - "update_time": "2020-07-02T17:12:15.165269", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/a6171316c00d613f/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "a6171316c00d613f" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "4e77bbc3b46ddd17", - "name": "Select random lines on data 1", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-07-02T17:12:00.358427", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1095.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "53e4f095-328f-4265-8e8b-6185620f63ac", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-11a7217485a18c95", - "url": "/api/histories/2f94e8ae9edff68a/contents/11a7217485a18c95", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 109, - "visible": true, - "creating_job": "4e77bbc3b46ddd17", - "update_time": "2020-07-02T17:12:15.170146", - "rerunnable": true, - "deleted": false, - "misc_info": "Kept 1 of 1 total lines.", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/11a7217485a18c95/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "11a7217485a18c95" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "a7f411be446bb522", - "name": "file_53.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:40.588045", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1094.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "d0066a2c-0f40-424e-8bac-5cda9571d7b1", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-927a35d35d4f4860", - "url": "/api/histories/2f94e8ae9edff68a/contents/927a35d35d4f4860", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 108, - "visible": true, - "creating_job": "a7f411be446bb522", - "update_time": "2020-07-02T17:12:14.713730", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/927a35d35d4f4860/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "927a35d35d4f4860" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "cd3649f8f517008c", - "name": "file_52.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:39.526953", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1093.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "b98773ec-d097-4484-b102-b9b006897204", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-d354ebeb1da9547c", - "url": "/api/histories/2f94e8ae9edff68a/contents/d354ebeb1da9547c", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 107, - "visible": true, - "creating_job": "cd3649f8f517008c", - "update_time": "2020-07-02T17:12:14.507095", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/d354ebeb1da9547c/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "d354ebeb1da9547c" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "f5da09edbdbab890", - "name": "file_51.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:38.197428", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1092.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "5327143b-e55e-409f-9b6c-dcd988d08a5d", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-c031430486d68421", - "url": "/api/histories/2f94e8ae9edff68a/contents/c031430486d68421", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 106, - "visible": true, - "creating_job": "f5da09edbdbab890", - "update_time": "2020-07-02T17:12:14.129077", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/c031430486d68421/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "c031430486d68421" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "297a73e30b2956ff", - "name": "file_50.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:37.429959", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1091.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "063d3763-17e7-43db-bbf3-48a0d2b3dd37", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-398f4c5cc135b0dd", - "url": "/api/histories/2f94e8ae9edff68a/contents/398f4c5cc135b0dd", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 105, - "visible": true, - "creating_job": "297a73e30b2956ff", - "update_time": "2020-07-02T17:12:13.854684", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/398f4c5cc135b0dd/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "398f4c5cc135b0dd" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "a8a5797f705e8237", - "name": "file_49.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:37.104929", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1090.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "6e7e05a4-c13a-4372-9fe3-eae1fb87ab09", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-f309dd72bc16e39b", - "url": "/api/histories/2f94e8ae9edff68a/contents/f309dd72bc16e39b", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 104, - "visible": true, - "creating_job": "a8a5797f705e8237", - "update_time": "2020-07-02T17:12:13.586169", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/f309dd72bc16e39b/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "f309dd72bc16e39b" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "f7d88bdd14b12f30", - "name": "file_48.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:35.390006", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1089.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "69414981-2dca-4e7c-941a-e9cacfbb5065", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-153c8b79e6a3fc75", - "url": "/api/histories/2f94e8ae9edff68a/contents/153c8b79e6a3fc75", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 103, - "visible": true, - "creating_job": "f7d88bdd14b12f30", - "update_time": "2020-07-02T17:12:13.493854", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/153c8b79e6a3fc75/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "153c8b79e6a3fc75" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "878d21f25ae61fc8", - "name": "file_47.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:34.850394", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1088.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "1758b148-025f-4ac7-b742-df8cea33d6e0", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-73c35346fd188ccb", - "url": "/api/histories/2f94e8ae9edff68a/contents/73c35346fd188ccb", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 102, - "visible": true, - "creating_job": "878d21f25ae61fc8", - "update_time": "2020-07-02T17:12:13.226133", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/73c35346fd188ccb/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "73c35346fd188ccb" - }, - { - "model_class": "HistoryDatasetAssociation", - "type": "file", - "display_types": [], - "history_id": "2f94e8ae9edff68a", - "dataset_id": "15851351f4d86d24", - "name": "file_46.txt", - "annotation": null, - "file_ext": "txt", - "validated_state_message": null, - "resubmitted": false, - "genome_build": "?", - "accessible": true, - "create_time": "2020-06-30T21:29:33.864461", - "history_content_type": "dataset", - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1087.dat", - "misc_blurb": "1 line", - "data_type": "galaxy.datatypes.data.Text", - "purged": false, - "validated_state": "unknown", - "meta_files": [], - "uuid": "930912bd-ce0f-418a-b1e1-ba69e69e76cd", - "tags": [], - "created_from_basename": null, - "type_id": "dataset-09bd879dc9508532", - "url": "/api/histories/2f94e8ae9edff68a/contents/09bd879dc9508532", - "peek": "
1 2 3
", - "api_type": "file", - "extension": "txt", - "hid": 101, - "visible": true, - "creating_job": "15851351f4d86d24", - "update_time": "2020-07-02T17:12:13.023050", - "rerunnable": false, - "deleted": false, - "misc_info": "uploaded txt file", - "download_url": "/api/histories/2f94e8ae9edff68a/contents/09bd879dc9508532/display", - "state": "ok", - "file_size": 6, - "display_apps": [], - "hda_ldda": "hda", - "id": "09bd879dc9508532" - } -] \ No newline at end of file diff --git a/client/src/components/providers/History/test/json/historyContentWithCollection.json b/client/src/components/providers/History/test/json/historyContentWithCollection.json deleted file mode 100644 index ef8302a0043..00000000000 --- a/client/src/components/providers/History/test/json/historyContentWithCollection.json +++ /dev/null @@ -1,256 +0,0 @@ -[ - { - "element_count": 2, - "tags": [], - "id": "a799d38679e985db", - "name": "asdaaa", - "type": "collection", - "type_id": "dataset_collection-a799d38679e985db", - "contents_url": "/api/dataset_collections/a799d38679e985db/contents/03501d7626bd192f", - "create_time": "2020-06-24T15:34:06.848662", - "populated": true, - "populated_state": "ok", - "collection_id": 10, - "collection_type": "list", - "job_state_summary": { - "running": 0, - "resubmitted": 0, - "upload": 0, - "deleted": 0, - "error": 0, - "all_jobs": 0, - "waiting": 0, - "queued": 0, - "ok": 0, - "new": 0, - "failed": 0, - "paused": 0, - "deleted_new": 0 - }, - "populated_state_message": null, - "job_source_id": null, - "deleted": false, - "visible": true, - "hid": 22, - "update_time": "2020-06-24T15:34:06.848669", - "history_id": "63cd3858d057a6d1", - "history_content_type": "dataset_collection", - "job_source_type": null, - "url": "/api/histories/63cd3858d057a6d1/contents/dataset_collections/a799d38679e985db" - }, - { - "hda_ldda": "hda", - "tags": [], - "type": "file", - "resubmitted": false, - "validated_state_message": null, - "misc_info": "uploaded fastqsanger file", - "deleted": false, - "id": "ab50e8da6b53023e", - "type_id": "dataset-ab50e8da6b53023e", - "rerunnable": false, - "display_types": [], - "create_time": "2020-06-24T11:31:35.680953", - "uuid": "92efa8a4-92ab-4941-977a-7d653e95c250", - "data_type": "galaxy.datatypes.sequence.FastqSanger", - "state": "ok", - "download_url": "/api/histories/63cd3858d057a6d1/contents/ab50e8da6b53023e/display", - "model_class": "HistoryDatasetAssociation", - "dataset_id": "ee712460b9af5737", - "file_ext": "fastqsanger", - "meta_files": [], - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1030.dat", - "annotation": null, - "creating_job": "ee712460b9af5737", - "accessible": true, - "name": "abcdeff", - "created_from_basename": null, - "visible": true, - "hid": 8, - "update_time": "2020-09-23T00:23:52.834927", - "history_id": "63cd3858d057a6d1", - "misc_blurb": "207.5 MB", - "peek": "
@M01368:20:000000000-A46F5:1:1101:10294:8369/2<\/td><\/tr>
CTCCAGGCCCATAACACTTGGGGGTAGCTAAAGTGAACTGTATCCGACATCTGGTTCCTACTTCAGGGCCATAAAGCCTAAATAGCCCACACGTTCCCCTTAAATAAGACATCACGATGGATCACAGGTCTATCACCCTATTAACCACTCACGGGAGCTCTCCATGCATTTGGTATTTTCGTCTGGGGGGTATGCACGCGATAGCATTGCGAGACGCTGGAGCCGGAGCACCCTATGTCGCAGTAT<\/td><\/tr>
+<\/td><\/tr>
BBCCCFFCCCCFGGGGGGGGGGGGGGGHHHHHGHHHHHHHHHHHHGGGGGHHHHHHHHHFHGHHHHGGGGCHGHHHHEHFHFHHGHHHHGGGGHHHHHHHHHHFHHFHHGHHHHHGGHGGHHHHHHGHGGGHHHHHHHGFHHGFHHHGHHHHHGGFGGHGHHHHHHHHHHHGHHEHHHHHGHGHGHGGGFFFFFFFFFFFFFDFFFFFFFF;D=DDFFFA.AFFFAA;A.;.AAFFFBBEECDFEF<\/td><\/tr>
@M01368:20:000000000-A46F5:1:1101:10302:11041/2<\/td><\/tr><\/table>", - "history_content_type": "dataset", - "purged": false, - "display_apps": [], - "file_size": 217570404, - "genome_build": "?", - "validated_state": "unknown", - "extension": "fastqsanger", - "url": "/api/histories/63cd3858d057a6d1/contents/ab50e8da6b53023e", - "api_type": "file" - }, - { - "hda_ldda": "hda", - "tags": [], - "type": "file", - "resubmitted": false, - "validated_state_message": null, - "misc_info": "uploaded fastqsanger file", - "deleted": false, - "id": "ee712460b9af5737", - "type_id": "dataset-ee712460b9af5737", - "rerunnable": false, - "display_types": [], - "create_time": "2020-06-24T11:31:25.377836", - "uuid": "a8a88acf-7cd4-4acc-9bf0-23a917e62d94", - "data_type": "galaxy.datatypes.sequence.FastqSanger", - "state": "ok", - "download_url": "/api/histories/63cd3858d057a6d1/contents/ee712460b9af5737/display", - "model_class": "HistoryDatasetAssociation", - "dataset_id": "9d04922baebb355f", - "file_ext": "fastqsanger", - "meta_files": [], - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1029.dat", - "annotation": null, - "creating_job": "9d04922baebb355f", - "accessible": true, - "name": "M117C1-ch_1.fq.fastqsan", - "created_from_basename": null, - "visible": true, - "hid": 7, - "update_time": "2020-09-10T18:21:32.734118", - "history_id": "63cd3858d057a6d1", - "misc_blurb": "207.5 MB", - "peek": "
@M01368:20:000000000-A46F5:1:1101:10294:8369/1<\/td><\/tr>
TATTGAACGTAGGTGCGATAAATAATGGGATGAGGCAGGAATCAAAGACAGATACTGCGACATAGGGTGCTCCGGCTCCAGCGTCTCGCAATGCTATCGCGTGCATACCCCCCAGACGAAAATACCAAATGCATGGAGAGCTCCCGTGAGTGGTTAATAGGGTGATAGACCTGTGATCCATCGTGATGTCTTATTTAAGGGGAACGTGTGGGCTATTTAGGCTTTATGGCCCTGAAGTAGGAACCAGATGT<\/td><\/tr>
+<\/td><\/tr>
BBBBBFFFFBFFGGGGGGGGGGHGFGHHHGHGHHHGGGGGHHHHHHHGGFHHHGHHGHGGGGGHHHHHGGHHHGGGGGGGHHGGGGHHGGGGHHHGHHGGGGGGHHHHHHHGGGGHGGGGGGHGHGHFGHGHHHHHGHFDHHHHGGAEEEDGFGGHFGFHHHGGHHHFGGHHHHHHHHHHHGGAFBFGGGGGFGGGGGGGGGGGGGGGGGFDFFFFFFFFFFFFFFFFFFFFFFF/9:BFFFFF?AF.BF/<\/td><\/tr>
@M01368:20:000000000-A46F5:1:1101:10302:11041/1<\/td><\/tr><\/table>", - "history_content_type": "dataset", - "purged": false, - "display_apps": [], - "file_size": 217620050, - "genome_build": "?", - "validated_state": "unknown", - "extension": "fastqsanger", - "url": "/api/histories/63cd3858d057a6d1/contents/ee712460b9af5737", - "api_type": "file" - }, - { - "hda_ldda": "hda", - "tags": [], - "type": "file", - "resubmitted": false, - "validated_state_message": null, - "misc_info": "uploaded fastqsanger file", - "deleted": false, - "id": "85f94a3b50966dc9", - "type_id": "dataset-85f94a3b50966dc9", - "rerunnable": false, - "display_types": [], - "create_time": "2020-06-24T11:30:35.766010", - "uuid": "fad0ccfa-f164-45d6-b779-1b433178da13", - "data_type": "galaxy.datatypes.sequence.FastqSanger", - "state": "ok", - "download_url": "/api/histories/63cd3858d057a6d1/contents/85f94a3b50966dc9/display", - "model_class": "HistoryDatasetAssociation", - "dataset_id": "5733d8d6dc37a408", - "file_ext": "fastqsanger", - "meta_files": [], - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1026.dat", - "annotation": null, - "creating_job": "5733d8d6dc37a408", - "accessible": true, - "name": "M117-ch_2.fq.fastqsanger", - "created_from_basename": null, - "visible": true, - "hid": 4, - "update_time": "2020-06-24T11:30:47.520492", - "history_id": "63cd3858d057a6d1", - "misc_blurb": "326.1 MB", - "peek": "
@M01368:13:000000000-A41AR:1:1101:10488:10383/2<\/td><\/tr>
CTTCAGGGCCATAAAGCCTAAATAGCCCACACGTTCCCCTTAAATAAGACATCACGATGGATCACAGGTCTATCACCCTATTAACCACTCACGGGAGCTCTCCATGCATTTGGTATTTTCGTCTGGGGGGTATGCACGCGATAGCATTGCGAGACGCTGGAGCCGGAGCACCCTATGTCGCAGTATCTGTCTTTGATTCCTGCCTCATCCCATTATTTATCGCACCTACGTTCAATATTACAGGCGAAC<\/td><\/tr>
+<\/td><\/tr>
CCCCCFFFCCCFGGGGGGGGGGHHHHHHHGGGGHHHHHHHHHHGHGHHHHHHHHHGGHGGHHHHHHHHHHHGHHHHHHHHHHGHHHHGHHHHHGGGGGHHHFHHHHHEHHHHHHFHHHHHGHGHGHFEGGCFGGGGGGGGGGFGGEFFGGGGFFFFFFFFFFFFFF@DAEFEFFFFFFFFFAFFFFFFFFFFFFFEFFFFFFFFFF0BBFFEFFFFBFFF09..:;FFFDFFFBBBBFFF0BFBEFF@B<\/td><\/tr>
@M01368:13:000000000-A41AR:1:1101:10763:9363/2<\/td><\/tr><\/table>", - "history_content_type": "dataset", - "purged": false, - "display_apps": [], - "file_size": 341989137, - "genome_build": "?", - "validated_state": "unknown", - "extension": "fastqsanger", - "url": "/api/histories/63cd3858d057a6d1/contents/85f94a3b50966dc9", - "api_type": "file" - }, - { - "hda_ldda": "hda", - "tags": [], - "type": "file", - "resubmitted": false, - "validated_state_message": null, - "misc_info": "uploaded fastqsanger file", - "deleted": false, - "id": "5733d8d6dc37a408", - "type_id": "dataset-5733d8d6dc37a408", - "rerunnable": false, - "display_types": [], - "create_time": "2020-06-24T11:30:22.204488", - "uuid": "1fbccf35-ef7c-4e67-9e9e-b7878b1db264", - "data_type": "galaxy.datatypes.sequence.FastqSanger", - "state": "ok", - "download_url": "/api/histories/63cd3858d057a6d1/contents/5733d8d6dc37a408/display", - "model_class": "HistoryDatasetAssociation", - "dataset_id": "e41dd4fdd9a586ef", - "file_ext": "fastqsanger", - "meta_files": [], - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1025.dat", - "annotation": null, - "creating_job": "e41dd4fdd9a586ef", - "accessible": true, - "name": "M117-ch_1.fq.fastqsanger", - "created_from_basename": null, - "visible": true, - "hid": 3, - "update_time": "2020-06-24T11:30:32.534455", - "history_id": "63cd3858d057a6d1", - "misc_blurb": "325.9 MB", - "peek": "
@M01368:13:000000000-A41AR:1:1101:10488:10383/1<\/td><\/tr>
CACTTTAGTAAGTATGTTCGCCTGTAATATTGAACGTAGGTGCGATAAATAATGGGATGAGGCAGGAATCAAAGACAGATACTGCGACATAGGGTGCTCCGGCTCCAGCGTCTCGCAATGCTATCGCGTGCATACCCCCCAGACGAAAATACCAAATGCATGGAGAGCTCCCGTGAGTGGTTAATAGGGTGATAGACCTGTGATCCATCGTGATGTCTTATTTAAGGGGAACGTGTGGGCTATTTAGGCTT<\/td><\/tr>
+<\/td><\/tr>
CCCCCFFFFFFFGGGGGGGGGGGHHHHHHHHHGHHHHHHGHHHGGHGGHHHHHHHHHHGHHHGGGGGHHHHHHGHHHHHHHHHHHGGGGGHHHHHGGHHHGGGGGGHHHGFGGHHGGGGHHHHHHGGGGGGHHHHHHHGGGGHGGGGGGHHHHHHHHHHHHHHHHHGHHGHGGGGAEGGGGGGGGEGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFF<\/td><\/tr>
@M01368:13:000000000-A41AR:1:1101:10763:9363/1<\/td><\/tr><\/table>", - "history_content_type": "dataset", - "purged": false, - "display_apps": [], - "file_size": 341692613, - "genome_build": "?", - "validated_state": "unknown", - "extension": "fastqsanger", - "url": "/api/histories/63cd3858d057a6d1/contents/5733d8d6dc37a408", - "api_type": "file" - }, - { - "hda_ldda": "hda", - "tags": [], - "type": "file", - "resubmitted": false, - "validated_state_message": null, - "misc_info": "uploaded fastqsanger file", - "deleted": false, - "id": "e41dd4fdd9a586ef", - "type_id": "dataset-e41dd4fdd9a586ef", - "rerunnable": false, - "display_types": [], - "create_time": "2020-06-24T11:30:08.266197", - "uuid": "37c3aaf0-c47d-4398-9f82-7f4218fb4c2f", - "data_type": "galaxy.datatypes.sequence.FastqSanger", - "state": "ok", - "download_url": "/api/histories/63cd3858d057a6d1/contents/e41dd4fdd9a586ef/display", - "model_class": "HistoryDatasetAssociation", - "dataset_id": "03feb7df0a14654f", - "file_ext": "fastqsanger", - "meta_files": [], - "file_name": "/Users/mason/Projects/ohsu/galaxy-data-files/001/dataset_1024.dat", - "annotation": null, - "creating_job": "03feb7df0a14654f", - "accessible": true, - "name": "M117-bl_2.fq.fastqsanger", - "created_from_basename": null, - "visible": true, - "hid": 2, - "update_time": "2020-06-24T11:30:20.546660", - "history_id": "63cd3858d057a6d1", - "misc_blurb": "497.4 MB", - "peek": "
@M01368:28:000000000-A5KYY:1:1101:10045:12104/2<\/td><\/tr>
CCATAAAGCCTAAATAGCCCACACGTTCCCCTTAAATAAGACATCACGATGGATCACAGGTCTATCACCCTATTAACCACTCACGGGAGCTCTCCATGCATTTGGTATTTTCGTCTGGGGGGTATGCACGCGATAGCATTGCGAGACGCTGGAGCCGGAGCACCCTATGTCGCAGTATCTGTCTTTGATTCCTGCCTCATCCCATTATTTATCGCACCTACGTTCAATAT<\/td><\/tr>
+<\/td><\/tr>
?????<<<B<BBBBB<>CFFFFHEHHH?-CEFFB?ECC??EFFDDGDEHFFDD?A?C??;5AEAEGCFFDFBEDC-AFHHFFFHHD*<DDDCGHHHHHFHFFF@@+77D@=DEFHFFBBA=8.?CEECC????8EEEEECC?.8??AA;A?'8??E;;'82AC*8AECCEEEE2AEEE?EE:?AC::AE?AEE::*0:C?A?EC?C*:?E:/?A?848:?CECEEEEECE<\/td><\/tr>
@M01368:28:000000000-A5KYY:1:1101:10126:23848/2<\/td><\/tr><\/table>", - "history_content_type": "dataset", - "purged": false, - "display_apps": [], - "file_size": 521548589, - "genome_build": "?", - "validated_state": "unknown", - "extension": "fastqsanger", - "url": "/api/histories/63cd3858d057a6d1/contents/e41dd4fdd9a586ef", - "api_type": "file" - } -] \ No newline at end of file diff --git a/client/src/components/providers/History/test/providerTestHelpers.js b/client/src/components/providers/History/test/providerTestHelpers.js deleted file mode 100644 index 7b97fc520a0..00000000000 --- a/client/src/components/providers/History/test/providerTestHelpers.js +++ /dev/null @@ -1,43 +0,0 @@ -import { watchForChange } from "jest/helpers"; -import { defaultPayload } from "components/providers/History/ContentProvider"; - -/** - * Vue adds a bunch of setters and getters so we need to create our own comparison fn - */ -export const sameVueObj = (a, b) => { - return JSON.stringify(a) == JSON.stringify(b); -}; - -/** - * Detects a new emission of a "payload" a standardized object delivered by HistoryContentProvider - * and CollectionContentProvider, skips the default value that's emitted when it initialized - * - * @param {Object} config vm, propName, label, other watchForChange configs - * @return {Promise} promise that resolves with the changed payload - */ -export const payloadChange = async (config = {}) => { - const { vm, propName = "payload", label = "payload change", skipDefault = false, ...cfg } = config; - const result = await watchForChange({ vm, propName, label, ...cfg }); - - // can see how fast the response comes back by monitoring this result - // console.log("payloadChange result", JSON.stringify(result.newVal)); - // chopout the placeholder flag for the default - // eslint-disable-next-line no-unused-vars - const { placeholder, ...payload } = result.newVal; - if (skipDefault && sameVueObj(payload, defaultPayload)) { - return await payloadChange(config); - } - - return payload; -}; - -export const reportPayload = (payload, { indexKey = "hid", label = "payload" } = {}) => { - const { contents = [], startKeyIndex, ...resultFields } = payload; - const keys = contents.map((o, idx) => { - const thisKey = o[indexKey]; - const keyString = idx == startKeyIndex ? `${thisKey}*` : thisKey; - return keyString; - }); - const report = { keys, startKeyIndex, ...resultFields }; - console.log(label, report); -}; diff --git a/client/src/components/providers/History/test/testCollection.js b/client/src/components/providers/History/test/testCollection.js deleted file mode 100644 index 70c6d59899a..00000000000 --- a/client/src/components/providers/History/test/testCollection.js +++ /dev/null @@ -1,25 +0,0 @@ -// Doctored collection & children for unit tests -import rawCollection from "./json/DatasetCollection"; -import rawNestedCollection from "./json/DatasetCollection.nested.json"; -import rawCollectionContent from "./json/collectionContent.json"; -import rawNestedCollectionContent from "./json/collectionContent.nested.json"; - -// Sample collection for CCP tests - -const parent_url = "/foo"; - -export const testCollectionContent = rawCollectionContent.map((props) => ({ ...props, parent_url })); - -export const testCollection = Object.assign({}, rawCollection, { - contents_url: parent_url, - element_count: testCollectionContent.length, -}); - -export const testNestedCollection = Object.assign({}, rawNestedCollection, { - parent_url: parent_url, - contents_url: "/foo/bar", - element_count: rawNestedCollectionContent.length, -}); - -// a list of element_indexes handy for testing -export const indices = (list) => list.map(({ element_index, _id, parent_url }) => ({ element_index, _id, parent_url })); diff --git a/client/src/components/providers/History/test/testHistory.js b/client/src/components/providers/History/test/testHistory.js deleted file mode 100644 index 6371bc79005..00000000000 --- a/client/src/components/providers/History/test/testHistory.js +++ /dev/null @@ -1,29 +0,0 @@ -import { History } from "components/History/model"; -import { SearchParams } from "components/providers/History/SearchParams"; -import rawHistory from "./json/History.json"; -import rawHistoryContent from "./json/historyContent.json"; - -// doctor the sample content -export const testHistoryContent = rawHistoryContent.map((item) => { - item.history_id = rawHistory.id; - return item; -}); - -// doctor the sample history -export const testHistory = new History({ - ...rawHistory, - hid_counter: testHistoryContent[0].hid + 1, -}); - -// simplified filter simlates server-side complete set -export const serverContent = (filters = new SearchParams()) => { - return testHistoryContent.filter((o) => { - if (!filters.showDeleted && o.deleted) { - return false; - } - if (!filters.showHidden && !o.visible) { - return false; - } - return true; - }); -}; diff --git a/client/src/components/providers/fetch.js b/client/src/components/providers/fetch.js deleted file mode 100644 index 185bc7d07cb..00000000000 --- a/client/src/components/providers/fetch.js +++ /dev/null @@ -1,25 +0,0 @@ -import { pipe } from "rxjs"; -import { map, mergeMap } from "rxjs/operators"; -import { ajax } from "rxjs/ajax"; -import { prependPath } from "utils/redirect"; - -export const fetchDatasetById = () => { - return pipe( - map((id) => prependPath(`/api/datasets/${id}`)), - mergeMap((url) => ajax.getJSON(url)) - ); -}; - -export const fetchDatasetCollectionById = () => { - return pipe( - map((id) => prependPath(`/api/dataset_collections/${id}?instance_type=history`)), - mergeMap((url) => ajax.getJSON(url)) - ); -}; - -export const fetchInvocationStepById = () => { - return pipe( - map((id) => prependPath(`/api/invocations/any/steps/${id}`)), - mergeMap((url) => ajax.getJSON(url)) - ); -};