diff --git a/app/institutions/dashboard/-components/object-list/component-test.ts b/app/institutions/dashboard/-components/object-list/component-test.ts index 4c1ae753cb3..8c1fc4aacda 100644 --- a/app/institutions/dashboard/-components/object-list/component-test.ts +++ b/app/institutions/dashboard/-components/object-list/component-test.ts @@ -81,6 +81,12 @@ module('Integration | institutions | dashboard | -components | object-list', hoo // The table data is not blatantly incorrect assert.dom('[data-test-object-table-body-row]').exists({ count: 10 }, 'There are 10 rows'); + + // Download buttons are present + await click('[data-test-download-dropdown]'); + assert.dom('[data-test-download-csv-link]').exists('CSV download link exists'); + assert.dom('[data-test-download-tsv-link]').exists('TSV download link exists'); + assert.dom('[data-test-download-json-link]').exists('JSON download link exists'); }); test('the table supports filtering', async function(assert) { diff --git a/app/institutions/dashboard/-components/object-list/component.ts b/app/institutions/dashboard/-components/object-list/component.ts index 0333bfb59ad..ee3f4dce8b7 100644 --- a/app/institutions/dashboard/-components/object-list/component.ts +++ b/app/institutions/dashboard/-components/object-list/component.ts @@ -2,6 +2,7 @@ import { action } from '@ember/object'; import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; +import IndexCardSearchModel from 'ember-osf-web/models/index-card-search'; import InstitutionModel from 'ember-osf-web/models/institution'; import { SuggestedFilterOperators } from 'ember-osf-web/models/related-property-path'; import SearchResultModel from 'ember-osf-web/models/search-result'; @@ -73,6 +74,29 @@ export default class InstitutionalObjectList extends Component - - + + + {{t 'institutions.dashboard.format_labels.json'}} + diff --git a/app/models/index-card-search.ts b/app/models/index-card-search.ts index 103cf169dd3..fc5250db51c 100644 --- a/app/models/index-card-search.ts +++ b/app/models/index-card-search.ts @@ -1,4 +1,5 @@ import Model, { AsyncHasMany, attr, hasMany } from '@ember-data/model'; +import {Links} from 'jsonapi-typescript'; import RelatedPropertyPathModel from './related-property-path'; import SearchResultModel from './search-result'; @@ -15,6 +16,7 @@ export default class IndexCardSearchModel extends Model { @attr('string') cardSearchText!: string; @attr('array') cardSearchFilters!: SearchFilter[]; @attr('string') totalResultCount!: number | typeof ShareMoreThanTenThousand; + @attr('object') links!: Links; @hasMany('search-result', { inverse: null }) searchResultPage!: AsyncHasMany & SearchResultModel[]; diff --git a/app/serializers/index-card-search.ts b/app/serializers/index-card-search.ts index 5b86f0c5600..49a0e7514ad 100644 --- a/app/serializers/index-card-search.ts +++ b/app/serializers/index-card-search.ts @@ -1,6 +1,20 @@ +import * as JSONAPI from 'jsonapi-typescript'; + import ShareSerializer from './share-serializer'; export default class IndexCardSearchSerializer extends ShareSerializer { + // Taken from osf-serializer.ts + _mergeLinks(resourceHash: JSONAPI.ResourceObject): Partial { + const links = { ...(resourceHash.links || {}) }; + return { + attributes: { ...resourceHash.attributes, links: (links as any) }, + }; + } + + extractAttributes(modelClass: any, resourceHash: JSONAPI.ResourceObject) { + const attributeHash = this._mergeLinks(resourceHash); + return super.extractAttributes(modelClass, attributeHash); + } } declare module 'ember-data/types/registries/serializer' { diff --git a/lib/osf-components/addon/components/index-card-searcher/component.ts b/lib/osf-components/addon/components/index-card-searcher/component.ts index c0b36fc6672..c2e69d870b6 100644 --- a/lib/osf-components/addon/components/index-card-searcher/component.ts +++ b/lib/osf-components/addon/components/index-card-searcher/component.ts @@ -9,6 +9,7 @@ import Toast from 'ember-toastr/services/toast'; import SearchResultModel from 'ember-osf-web/models/search-result'; import { taskFor } from 'ember-concurrency-ts'; import RelatedPropertyPathModel, { SuggestedFilterOperators } from 'ember-osf-web/models/related-property-path'; +import IndexCardSearchModel from 'ember-osf-web/models/index-card-search'; interface IndexCardSearcherArgs { queryOptions: Record; @@ -27,6 +28,7 @@ export default class IndexCardSearcher extends Component @tracked relatedProperties?: RelatedPropertyPathModel[] = []; @tracked booleanFilters?: RelatedPropertyPathModel[] = []; + @tracked latestIndexCardSearch?: IndexCardSearchModel; @tracked firstPageCursor?: string; @tracked nextPageCursor?: string; @tracked prevPageCursor?: string; @@ -64,6 +66,7 @@ export default class IndexCardSearcher extends Component (property: RelatedPropertyPathModel) => property.suggestedFilterOperator !== SuggestedFilterOperators.IsPresent, // AnyOf or AtDate ); + this.latestIndexCardSearch = searchResult; this.firstPageCursor = searchResult.firstPageCursor; this.nextPageCursor = searchResult.nextPageCursor; this.prevPageCursor = searchResult.prevPageCursor; diff --git a/lib/osf-components/addon/components/index-card-searcher/template.hbs b/lib/osf-components/addon/components/index-card-searcher/template.hbs index 76d1db68bd9..2b04d5b9799 100644 --- a/lib/osf-components/addon/components/index-card-searcher/template.hbs +++ b/lib/osf-components/addon/components/index-card-searcher/template.hbs @@ -7,6 +7,7 @@ debouceSearchObjectsTask=this.debouceSearchObjectsTask searchObjectsTask=this.searchObjectsTask + latestIndexCardSearch=this.latestIndexCardSearch firstPageCursor=this.firstPageCursor nextPageCursor=this.nextPageCursor prevPageCursor=this.prevPageCursor diff --git a/mirage/views/search.ts b/mirage/views/search.ts index c0723c3b47e..d2db1a48d80 100644 --- a/mirage/views/search.ts +++ b/mirage/views/search.ts @@ -277,10 +277,11 @@ export function cardSearch(_: Schema, request: Request) { requestedResourceTypes = Object.keys(resourceMetadataByType) as OsfmapResourceTypes[]; } + const indexCardSearchId = faker.random.uuid(); const indexCardSearch = { data: { type: 'index-card-search', - id: faker.random.uuid(), + id:indexCardSearchId, attributes: { cardSearchText: 'hello', cardSearchFilter: [ @@ -325,6 +326,9 @@ export function cardSearch(_: Schema, request: Request) { }, searchResultPage: {}, }, + links: { + self: `https://share.osf.io/api/v2/index-card-search/${indexCardSearchId}`, + }, }, included: [ // Related properties