diff --git a/src/assets/scss/main.scss b/src/assets/scss/main.scss index 261b33b63..90521267c 100644 --- a/src/assets/scss/main.scss +++ b/src/assets/scss/main.scss @@ -84,6 +84,8 @@ $table-striped-row-even-hover-background-color:$link-light; $medium-modal-content-width: $modal-content-width * 1.4; $medium-modal-body-padding: 0 3em 2em 3em; +$large-modal-content-width: $modal-content-width * 1.8; + //$margin-right: 2 rem; // Import buefy before bulma @@ -904,7 +906,7 @@ tr:nth-child(odd) td.db-filled { } } -.experiment-observations-download-button { +.sub-entity-dataset-modal, .experiment-observations-download-button { .modal { .modal-card { width: $medium-modal-content-width; @@ -915,6 +917,17 @@ tr:nth-child(odd) td.db-filled { } } +.sub-entity-dataset-modal { + .modal { + .modal-card { + width: $large-modal-content-width; + .modal-card-body { + padding: $medium-modal-body-padding; + } + } + } +} + .content { .pagination-list { margin-top: 0; diff --git a/src/breeding-insight/dao/ExperimentDAO.ts b/src/breeding-insight/dao/ExperimentDAO.ts index 83468197e..f937c5f2e 100644 --- a/src/breeding-insight/dao/ExperimentDAO.ts +++ b/src/breeding-insight/dao/ExperimentDAO.ts @@ -20,6 +20,7 @@ import * as api from "@/util/api"; import {Result, ResultGenerator} from "@/breeding-insight/model/Result"; import {Trial} from "@/breeding-insight/model/Trial.ts"; import {DatasetModel} from "@/breeding-insight/model/DatasetModel"; +import {DatasetMetadata} from "@/breeding-insight/model/DatasetMetadata"; export class ExperimentDAO { @@ -38,6 +39,22 @@ export class ExperimentDAO { return ResultGenerator.err(error); } } + + static async getDatasetMetadata(programId: string, experimentId: string): Promise> { + const config: any = {}; + config.url = `${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/experiments/${experimentId}/datasets`; + config.method = 'get'; + config.programId = programId; + config.experimentId = experimentId; + try { + const res = await api.call(config) as Response; + let { result } = res.data; + return ResultGenerator.success(result); + } catch (error) { + return ResultGenerator.err(error); + } + } + static async getDatasetById(programId: string, experimentId: string, datasetId: string, stats: boolean): Promise> { const config: any = {}; config.url = `${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/experiments/${experimentId}/dataset/${datasetId}`; @@ -57,4 +74,19 @@ export class ExperimentDAO { } } + static async createSubEntityDataset(programId: string, experimentId: string, name: string, repeatedMeasures: number): Promise> { + const config: any = {}; + config.url = `${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/experiments/${experimentId}/dataset`; + config.method = 'post'; + config.programId = programId; + config.experimentId = experimentId; + config.data = {name: name, repeatedMeasures: repeatedMeasures} // Corresponds to SubEntityDatasetRequest in bi-api. + try { + const res = await api.call(config) as Response; + let { result } = res.data; + return ResultGenerator.success(result); + } catch (error) { + return ResultGenerator.err(error); + } + } } diff --git a/src/breeding-insight/model/ExperimentDatasetOption.ts b/src/breeding-insight/model/DatasetMetadata.ts similarity index 65% rename from src/breeding-insight/model/ExperimentDatasetOption.ts rename to src/breeding-insight/model/DatasetMetadata.ts index 048b4e301..932e55935 100644 --- a/src/breeding-insight/model/ExperimentDatasetOption.ts +++ b/src/breeding-insight/model/DatasetMetadata.ts @@ -15,16 +15,21 @@ * limitations under the License. */ -import {SelectOption} from "@/breeding-insight/model/SelectOption"; +import {Observation} from "@/breeding-insight/model/Observation"; +import {ObservationUnit} from "@/breeding-insight/model/ObservationUnit"; +import {ObservationVariable} from "@/breeding-insight/model/ObservationVariable"; -export class ExperimentDatasetOption implements SelectOption { - static observations = new ExperimentDatasetOption("Observation Dataset", "observations"); - - name: string; +export class DatasetMetadata { id: string; + name: string; + level: number; - constructor(name: string, id: string) { - this.name = name; + constructor(id: string, + name: string, + level: number + ) { this.id = id; + this.name = name; + this.level = level; } } \ No newline at end of file diff --git a/src/breeding-insight/model/DatasetModel.ts b/src/breeding-insight/model/DatasetModel.ts index 1acd5016b..37d5abe82 100644 --- a/src/breeding-insight/model/DatasetModel.ts +++ b/src/breeding-insight/model/DatasetModel.ts @@ -28,7 +28,6 @@ export class DatasetModel { additionalInfo?: any; - constructor(id: string, experimentId: string, data: Observation[], diff --git a/src/breeding-insight/model/ExperimentExportOptions.ts b/src/breeding-insight/model/ExperimentExportOptions.ts index 6476c079a..41a9f3c2b 100644 --- a/src/breeding-insight/model/ExperimentExportOptions.ts +++ b/src/breeding-insight/model/ExperimentExportOptions.ts @@ -22,7 +22,7 @@ import {ExperimentDatasetOption} from "@/breeding-insight/model/ExperimentDatase export class ExperimentExportOptions { public fileExtension: string = FileTypeOption.xls.id; - public dataset: string = ExperimentDatasetOption.observations.id; + public datasetId: string; public environments: string[] = []; public allEnvironments: boolean = false; public includeTimestamps: string = 'No'; diff --git a/src/breeding-insight/model/SubEntityDatasetNewRequest.ts b/src/breeding-insight/model/SubEntityDatasetNewRequest.ts new file mode 100644 index 000000000..4f5c384d1 --- /dev/null +++ b/src/breeding-insight/model/SubEntityDatasetNewRequest.ts @@ -0,0 +1,31 @@ +/* + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {Observation} from "@/breeding-insight/model/Observation"; +import {ObservationUnit} from "@/breeding-insight/model/ObservationUnit"; +import {ObservationVariable} from "@/breeding-insight/model/ObservationVariable"; + +export class SubEntityDatasetNewRequest { + name: string; + repeatedMeasures: number; + + + constructor(name: string, repeatedMeasures: string) { + this.name = name; + this.repeatedMeasures = repeatedMeasures; + } +} \ No newline at end of file diff --git a/src/breeding-insight/service/ExperimentService.ts b/src/breeding-insight/service/ExperimentService.ts index 8de5d4f59..f0fe083cb 100644 --- a/src/breeding-insight/service/ExperimentService.ts +++ b/src/breeding-insight/service/ExperimentService.ts @@ -16,9 +16,12 @@ */ import {ExperimentDAO} from "@/breeding-insight/dao/ExperimentDAO"; -import {Trial} from "@/breeding-insight/model/Trial.ts"; +import {Trial} from "@/breeding-insight/model/Trial"; import {Result, ResultGenerator} from "@/breeding-insight/model/Result"; import {DatasetModel} from "@/breeding-insight/model/DatasetModel"; +import {DatasetMetadata} from "@/breeding-insight/model/DatasetMetadata"; +import {SubEntityDatasetNewRequest} from "@/breeding-insight/model/SubEntityDatasetNewRequest"; +import {BrAPIUtils} from "@/breeding-insight/utils/BrAPIUtils"; export class ExperimentService { @@ -36,4 +39,36 @@ export class ExperimentService { return await ExperimentDAO.getDatasetById(programId,experimentId, datasetId, true); } + static async createSubEntityDataset(programId: string, experimentId: string, subEntityRequest: SubEntityDatasetNewRequest): Promise> { + if (!programId) { + return ResultGenerator.err(new Error('Missing or invalid program id')); + } + return await ExperimentDAO.createSubEntityDataset(programId, experimentId, subEntityRequest.name, subEntityRequest.repeatedMeasures); + } + + static async getDatasetMetadata(programId: string, experimentId: string): Promise> { + if (!programId) { + return ResultGenerator.err(new Error('Missing or invalid program id')); + } + return await ExperimentDAO.getDatasetMetadata(programId, experimentId); + } + + static async getDatasetMetadataByTrial(programId: string, trial: Trial): Promise> { + if (!programId) { + return ResultGenerator.err(new Error('Missing or invalid program id')); + } + if (!trial) { + return ResultGenerator.err(new Error('Missing or invalid trial')); + } + if (!trial.externalReferences) { + return ResultGenerator.err(new Error('Trial is missing external references')); + } + // Try to get the /trials external reference. + let externalReferenceId = BrAPIUtils.getBreedingInsightId(trial.externalReferences, '/trials'); + // Throw if trial is missing ExternalReferenceId. + if (!externalReferenceId) { + return ResultGenerator.err(new Error("Trial is missing external reference.")); + } + return await ExperimentDAO.getDatasetMetadata(programId, externalReferenceId); + } } diff --git a/src/components/experiments/ExperimentObservationsDownloadModal.vue b/src/components/experiments/ExperimentObservationsDownloadModal.vue index 18591e0df..653204d8d 100644 --- a/src/components/experiments/ExperimentObservationsDownloadModal.vue +++ b/src/components/experiments/ExperimentObservationsDownloadModal.vue @@ -20,7 +20,7 @@ v-bind:unique-id="trialId" v-bind:modal-title="modalTitle" v-bind:download="downloadList" - v-bind:active="active && loadingStudyOptionsComplete" + v-bind:active="active && loadingStudyOptionsComplete && loadingDatasetOptionsComplete" modal-class="experiment-observations-download-button" v-on:deactivate="resetExportOptions" > @@ -37,7 +37,7 @@