Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
24 changes: 24 additions & 0 deletions app/institutions/dashboard/-components/object-list/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -73,6 +74,29 @@ export default class InstitutionalObjectList extends Component<InstitutionalObje
};
}

downloadUrl(cardSearch: IndexCardSearchModel, format: string) {
if (!cardSearch.links.self) {
return '';
}
const cardSearchUrl = new URL((cardSearch.links.self as string));
cardSearchUrl.searchParams.set('page[size]', '10000');
cardSearchUrl.searchParams.set('acceptMediatype', format);
cardSearchUrl.searchParams.set('withFileName', `${this.args.objectType}-search-results`);
return cardSearchUrl.toString();
}

downloadCsvUrl(cardSearch: IndexCardSearchModel) {
return this.downloadUrl(cardSearch, 'text/csv');
}

downloadTsvUrl(cardSearch: IndexCardSearchModel) {
return this.downloadUrl(cardSearch, 'text/tab-separated-values');
}

downloadJsonUrl(cardSearch: IndexCardSearchModel) {
return this.downloadUrl(cardSearch, 'application/json');
}

@action
updateVisibleColumns() {
this.visibleColumns = [...this.dirtyVisibleColumns];
Expand Down
12 changes: 12 additions & 0 deletions app/institutions/dashboard/-components/object-list/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,15 @@
display: inline-flex;
padding-left: 10px;
}

.download-dropdown-content {
display: flex;
flex-direction: column;
align-items: flex-start;
border: 1px solid $color-border-gray;
width: max-content;
}

.download-link {
padding: 4px 8px;
}
34 changes: 26 additions & 8 deletions app/institutions/dashboard/-components/object-list/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,36 @@ as |list|>
<FaIcon @icon='download' />
</dd.trigger>
<dd.content local-class='download-dropdown-content'>
<Button
local-class='download-option'
{{on 'click' (queue this.downloadCsv dd.close)}}
<OsfLink
data-test-download-csv-link
data-analytics-name='Download CSV'
local-class='download-link'
{{on 'click' dd.close}}
@href={{call (fn (action this.downloadCsvUrl list.latestIndexCardSearch))}}
@target='_blank'
>
{{t 'institutions.dashboard.format_labels.csv'}}
</Button>
<Button
local-class='download-option'
{{on 'click' (queue this.downloadTsv dd.close)}}
</OsfLink>
<OsfLink
data-test-download-tsv-link
data-analytics-name='Download TSV'
local-class='download-link'
{{on 'click' dd.close}}
@href={{call (fn (action this.downloadTsvUrl list.latestIndexCardSearch))}}
@target='_blank'
>
{{t 'institutions.dashboard.format_labels.tsv'}}
</Button>
</OsfLink>
<OsfLink
data-test-download-json-link
data-analytics-name='Download JSON'
local-class='download-link'
{{on 'click' dd.close}}
@href={{call (fn (action this.downloadJsonUrl list.latestIndexCardSearch))}}
@target='_blank'
>
{{t 'institutions.dashboard.format_labels.json'}}
</OsfLink>
</dd.content>
</ResponsiveDropdown>
</div>
Expand Down
2 changes: 2 additions & 0 deletions app/models/index-card-search.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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> & SearchResultModel[];
Expand Down
14 changes: 14 additions & 0 deletions app/serializers/index-card-search.ts
Original file line number Diff line number Diff line change
@@ -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<JSONAPI.ResourceObject> {
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' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, any>;
Expand All @@ -27,6 +28,7 @@ export default class IndexCardSearcher extends Component<IndexCardSearcherArgs>
@tracked relatedProperties?: RelatedPropertyPathModel[] = [];
@tracked booleanFilters?: RelatedPropertyPathModel[] = [];

@tracked latestIndexCardSearch?: IndexCardSearchModel;
@tracked firstPageCursor?: string;
@tracked nextPageCursor?: string;
@tracked prevPageCursor?: string;
Expand Down Expand Up @@ -64,6 +66,7 @@ export default class IndexCardSearcher extends Component<IndexCardSearcherArgs>
(property: RelatedPropertyPathModel) =>
property.suggestedFilterOperator !== SuggestedFilterOperators.IsPresent, // AnyOf or AtDate
);
this.latestIndexCardSearch = searchResult;
this.firstPageCursor = searchResult.firstPageCursor;
this.nextPageCursor = searchResult.nextPageCursor;
this.prevPageCursor = searchResult.prevPageCursor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
debouceSearchObjectsTask=this.debouceSearchObjectsTask
searchObjectsTask=this.searchObjectsTask

latestIndexCardSearch=this.latestIndexCardSearch
firstPageCursor=this.firstPageCursor
nextPageCursor=this.nextPageCursor
prevPageCursor=this.prevPageCursor
Expand Down
6 changes: 5 additions & 1 deletion mirage/views/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
Expand Down Expand Up @@ -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
Expand Down
Loading