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
6 changes: 6 additions & 0 deletions src/assets/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -900,3 +900,9 @@ tr:nth-child(odd) td.db-filled {
display: block;
}
}

label.environment-option-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
2 changes: 0 additions & 2 deletions src/breeding-insight/dao/ExperimentDAO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import {BiResponse, Response} from "@/breeding-insight/model/BiResponse";
import * as api from "@/util/api";
import {Result, ResultGenerator} from "@/breeding-insight/model/Result";
import {Trial} from "@/breeding-insight/model/Trial.ts";
import * as UUID from "uuid";
import {PaginationQuery} from "@/breeding-insight/model/PaginationQuery";
import {DatasetModel} from "@/breeding-insight/model/DatasetModel";

export class ExperimentDAO {
Expand Down
19 changes: 11 additions & 8 deletions src/breeding-insight/dao/StudyDAO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ import {BrAPIDAOUtil} from "@/breeding-insight/dao/BrAPIDAOUtil";

export class StudyDAO {

static async getAllForTrial(programId: string, trialId: string): Promise<Result<Error, BiResponse>> {
static async getAllForTrial(programId: string, externalReferenceId: string): Promise<Result<Error, BiResponse>> {
// Use GET endpoint to get all Studies for a single Trial by external reference.
const { data } = await api.call({
url: `${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/brapi/v2/studies`,
method: 'get',
params: {
externalReferenceId: externalReferenceId,
externalReferenceSource: `${process.env.VUE_APP_BI_REFERENCE_SOURCE}/trials`,
pageSize: 1000000 }
}) as Response;

const body = {
trialDbIds: [
trialId
]
};

return await BrAPIDAOUtil.search(`${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/brapi/v2/search/studies`, body);
return ResultGenerator.success(new BiResponse(data));
}

static async getAll(programId: string, paginationQuery: PaginationQuery, full : boolean): Promise<Result<Error, BiResponse>> {
Expand Down
30 changes: 0 additions & 30 deletions src/breeding-insight/model/EnvironmentOption.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/breeding-insight/model/ExperimentExportOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@

import {FileTypeOption} from "@/breeding-insight/model/FileTypeOption";
import {ExperimentDatasetOption} from "@/breeding-insight/model/ExperimentDatasetOption";
import {EnvironmentOption} from "@/breeding-insight/model/EnvironmentOption";

// Stores the user selected options for Experiment Observation file export.
export class ExperimentExportOptions {

public fileExtension: string = FileTypeOption.xls.id;
public dataset: string = ExperimentDatasetOption.observations.id;
public environments: string[] = [EnvironmentOption.all.id];
public includeTimestamps: string = 'Yes';
public environments: string[] = [];
public allEnvironments: boolean = false;
public includeTimestamps: string = 'No';

public timestampsTrueFalseString(): string {
if (this.includeTimestamps.toLowerCase() === 'yes')
Expand Down
10 changes: 8 additions & 2 deletions src/breeding-insight/model/Study.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* limitations under the License.
*/

import {ExternalReferences} from "@/breeding-insight/brapi/model/externalReferences";

export class Study {
id?: string;
name?: string;
Expand All @@ -24,6 +26,8 @@ export class Study {
endDate?: Date | null;
location?: string;
active?: boolean;
externalReferences?: ExternalReferences;


constructor(id?: string,
name?: string,
Expand All @@ -32,7 +36,8 @@ export class Study {
startDate?: string,
endDate?: string,
location?: string,
active?: boolean
active?: boolean,
externalReferences?: ExternalReferences
) {
this.id = id;
this.name = name;
Expand All @@ -50,13 +55,14 @@ export class Study {
} else {
this.active = true;
}
this.externalReferences = externalReferences;
}

static assign(study: Study): Study {
const start: string | undefined = study.startDate ? study.startDate.toISOString() : undefined;
const end: string | undefined = study.endDate ? study.endDate.toISOString() : undefined;

return new Study(study.id, study.name, study.description, study.type, start, end, study.location, study.active);
return new Study(study.id, study.name, study.description, study.type, start, end, study.location, study.active, study.externalReferences);
}

equals(study?: Study): boolean {
Expand Down
2 changes: 1 addition & 1 deletion src/breeding-insight/service/BrAPIService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class BrAPIService {
params['sortOrder'] = sort.order;
}
if (pagination.page || pagination.page == 0) { //have to account for 0-index pagination since 0 falsy
params ['page'] = pagination.page;
params['page'] = pagination.page;
}
if (pagination.pageSize) {
params['pageSize'] = pagination.pageSize;
Expand Down
6 changes: 3 additions & 3 deletions src/breeding-insight/service/ProgramService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class ProgramService {
if (program.id === undefined) {
ProgramDAO.create(program).then((biResponse) => {
const result: any = biResponse.result;
const newProgram = new Program(result.id, result.name, result.species.id, result.numUsers, result.brapiUrl);
const newProgram = new Program(result.id, result.name, result.species.id, result.numUsers, result.brapiUrl, result.key);
resolve(newProgram);

}).catch((error) => {
Expand Down Expand Up @@ -68,7 +68,7 @@ export class ProgramService {
if (program.id) {
ProgramDAO.update(program.id, program).then((biResponse) => {
const result: any = biResponse.result;
const newProgram = new Program(result.id, result.name, result.species.id, result.numUsers, result.brapiUrl);
const newProgram = new Program(result.id, result.name, result.species.id, result.numUsers, result.brapiUrl, result.key);
resolve(newProgram);

}).catch((error) => reject(error));
Expand Down Expand Up @@ -125,7 +125,7 @@ export class ProgramService {

ProgramDAO.getOne(programId).then((biResponse) => {
const result = biResponse.result;
const program = new Program(result.id, result.name, result.species.id, result.numUsers, result.brapiUrl);
const program = new Program(result.id, result.name, result.species.id, result.numUsers, result.brapiUrl, result.key);
resolve(program);
}).catch((error) => reject(error));

Expand Down
14 changes: 9 additions & 5 deletions src/breeding-insight/service/StudyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import {BiResponse, Metadata} from "@/breeding-insight/model/BiResponse";
import {PaginationQuery} from "@/breeding-insight/model/PaginationQuery";
import {PaginationUtilities} from "@/breeding-insight/model/view_models/PaginationUtilities";
import {Result, ResultGenerator } from "@/breeding-insight/model/Result";
import {Trial} from "@/breeding-insight/model/Trial";
import {BrAPIUtils} from "@/breeding-insight/utils/BrAPIUtils";

export class StudyService {

static async getAll(programId: string, trialId?: string, paginationQuery?: PaginationQuery, full?: boolean): Promise<Result<Error, [Study[], Metadata]>> {
static async getAll(programId: string, trial?: Trial, paginationQuery?: PaginationQuery, full?: boolean): Promise<Result<Error, [Study[], Metadata]>> {

if (paginationQuery === undefined){
paginationQuery = new PaginationQuery(0, 0, true);
Expand All @@ -38,8 +39,11 @@ export class StudyService {
if(!programId) throw new Error('missing or invalid program id');

let response: Result<Error, BiResponse>;
if (trialId) {
response = await StudyDAO.getAllForTrial(programId, trialId) as Result<Error, BiResponse>;
if (trial !== undefined && trial.externalReferences !== undefined) {
let externalReferenceId = BrAPIUtils.getBreedingInsightId(trial.externalReferences, '/trials');
// Throw if trial is missing ExternalReferenceId.
if (externalReferenceId === undefined) throw new Error("Trial is missing external reference.");
response = await StudyDAO.getAllForTrial(programId, externalReferenceId) as Result<Error, BiResponse>;
} else {
response = await StudyDAO.getAll(programId, paginationQuery, full) as Result<Error, BiResponse>;
}
Expand All @@ -52,7 +56,7 @@ export class StudyService {

data = PaginationUtilities.mockSortRecords(data);
studies = data.map((study: any) => {
return new Study(study.studyDbId, study.studyName, study.studyDescription, study.studyType, study.startDate, study.endDate, study.locationName, study.active);
return new Study(study.studyDbId, study.studyName, study.studyDescription, study.studyType, study.startDate, study.endDate, study.locationName, study.active, study.externalReferences);
});

let newPagination;
Expand Down
66 changes: 50 additions & 16 deletions src/components/experiments/ExperimentObservationsDownloadButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<template>
<DownloadButton
v-bind:unique-id="trialDbId"
v-bind:unique-id="trialId"
v-bind:modal-title="modalTitle"
v-bind:download="downloadList"
v-bind:anchor-class="anchorClass"
Expand All @@ -26,17 +26,17 @@
>
<template #form>
<div class="columns mb-4">
<!-- DatasetModel Select -->
<!-- Dataset Select -->
<div class="column control">
<div class="field">
<label
class="label"
v-bind:for="`dataset-select-${trialDbId}`"
><span>DatasetModel</span></label>
v-bind:for="`dataset-select-${trialId}`"
><span>Dataset</span></label>
<div class="control">
<div class="select">
<select
v-bind:id="`dataset-select-${trialDbId}`"
v-bind:id="`dataset-select-${trialId}`"
v-model="fileOptions.dataset"
>
<option
Expand All @@ -57,16 +57,29 @@
<legend class="label required">
<span class="required">Environment(s)</span>
</legend>
<div class="control">
<label
class="checkbox environment-option-label"
>
<input
v-model="fileOptions.allEnvironments"
type="checkbox"
value="all"
>
All Environments
</label>
</div>
<div
v-for="option in environmentOptions"
v-bind:key="option.id"
class="control"
>
<label class="checkbox">
<label class="checkbox environment-option-label">
<input
v-model="fileOptions.environments"
type="checkbox"
v-bind:value="option.id"
v-bind:disabled="fileOptions.allEnvironments"
>
{{ option.name }}
</label>
Expand All @@ -92,7 +105,7 @@
</legend>
<div class="field">
<input
v-bind:id="`timestamps-switch-${trialDbId}`"
v-bind:id="`timestamps-switch-${trialId}`"
v-model="fileOptions.includeTimestamps"
type="checkbox"
true-value="Yes"
Expand All @@ -101,8 +114,8 @@
class="switch is-info is-rounded"
>
<label
v-bind:id="`timestamps-label-${trialDbId}`"
v-bind:for="`timestamps-switch-${trialDbId}`"
v-bind:id="`timestamps-label-${trialId}`"
v-bind:for="`timestamps-switch-${trialId}`"
>{{ fileOptions.includeTimestamps }}</label>
</div>
</fieldset>
Expand Down Expand Up @@ -145,9 +158,14 @@ import {Program} from "@/breeding-insight/model/Program";
import {ExperimentExportOptions} from "@/breeding-insight/model/ExperimentExportOptions";
import {FileTypeOption} from "@/breeding-insight/model/FileTypeOption";
import {ExperimentDatasetOption} from "@/breeding-insight/model/ExperimentDatasetOption";
import {EnvironmentOption} from "@/breeding-insight/model/EnvironmentOption";
import {AlertTriangleIcon} from 'vue-feather-icons';
import DownloadButton from "@/components/DownloadButton.vue";
import {Trial} from "@/breeding-insight/model/Trial";
import {Metadata} from "@/breeding-insight/model/BiResponse";
import {Study} from "@/breeding-insight/model/Study";
import {StudyService} from "@/breeding-insight/service/StudyService";
import {Result} from "@/breeding-insight/model/Result";
import {BrAPIUtils} from "@/breeding-insight/utils/BrAPIUtils";

@Component({
mixins: [validationMixin],
Expand All @@ -163,7 +181,9 @@ export default class ExperimentObservationsDownloadButton extends Vue {
@Prop()
active!: boolean;
@Prop()
trialDbId!: string;
trialId!: string;
@Prop()
experiment!: Trial;
@Prop()
modalTitle?: string;
@Prop()
Expand All @@ -174,7 +194,21 @@ export default class ExperimentObservationsDownloadButton extends Vue {
private showEnvironmentsValidationError: boolean = false;
private fileExtensionOptions: object[] = Object.values(FileTypeOption);
private datasetOptions: object[] = Object.values(ExperimentDatasetOption);
private environmentOptions: object[] = Object.values(EnvironmentOption);
private environmentOptions: object[] = [];

async mounted() {
// Fetch all environments (studies) for this experiment.
try {
const response: Result<Error, [Study[], Metadata]> = await StudyService.getAll(this.activeProgram!.id!, this.experiment);
if(response.isErr()) throw response.value;
let [studies, metadata] = response.value;
// Set environment options.
this.environmentOptions = studies.map((s) => ({id: BrAPIUtils.getBreedingInsightId(s.externalReferences!, '/studies'), name: s.name}));
} catch (error) {
// Display error that studies cannot be loaded
this.$emit('show-error-notification', 'Error while trying to load studies');
}
}

downloadList(): boolean {
// Validate selected options.
Expand All @@ -185,13 +219,12 @@ export default class ExperimentObservationsDownloadButton extends Vue {
+ '/v1/programs/'
+ this.activeProgram.id
+ '/experiments/'
+ this.trialDbId
+ this.trialId
+ '/export?fileExtension='
+ this.fileOptions.fileExtension
+ '&dataset='
+ this.fileOptions.dataset
// + '&environments='
// + this.fileOptions.environments
+ (this.fileOptions.allEnvironments ? '' : ('&environments=' + this.fileOptions.environments))
+ '&includeTimestamps='
+ this.fileOptions.timestampsTrueFalseString(),
'_blank');
Expand All @@ -209,7 +242,8 @@ export default class ExperimentObservationsDownloadButton extends Vue {
}

validateOptions(): boolean {
if (this.fileOptions.environments.length === 0){
// Either "All environments" or one or more specific environments must be selected.
if (this.fileOptions.environments.length === 0 && !this.fileOptions.allEnvironments){
this.$emit('show-error-notification', 'One or more environments must be selected.');
this.showEnvironmentsValidationError = true;
return false;
Expand Down
3 changes: 2 additions & 1 deletion src/components/experiments/ExperimentsObservationsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@
</b-table-column>
<b-table-column field="data.listDbId" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
<ExperimentObservationsDownloadButton
v-bind:experiment="props.row.data"
v-bind:modal-title="`Download ${props.row.data.trialName}`"
v-bind:trial-db-id="BrAPIUtils.getBreedingInsightId(props.row.data.externalReferences, '/trials')"
v-bind:trial-id="BrAPIUtils.getBreedingInsightId(props.row.data.externalReferences, '/trials')"
v-on:show-error-notification="$emit('show-error-notification', $event)"
>
Download
Expand Down
Loading