Skip to content

Commit

Permalink
[BI-1198] All Experiments Table
Browse files Browse the repository at this point in the history
  • Loading branch information
HMS17 committed Aug 3, 2022
1 parent b768a47 commit 85a4efc
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 33 deletions.
4 changes: 4 additions & 0 deletions src/assets/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ table tr.is-edited + .detail {
}
}

.table td.fixed-width-wrapped {
word-break: break-word;
width: 25%;
}

.table.is-striped tbody tr:not(.is-edited):nth-child(2n).is-new {
background-color: $success-light;
Expand Down
4 changes: 2 additions & 2 deletions src/breeding-insight/dao/TrialDAO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ import { Result, Err, Success, ResultGenerator } from "@/breeding-insight/model/

export class TrialDAO {

static async getAll(programId: string, paginationQuery: PaginationQuery, full : boolean): Promise<Result<Error, BiResponse>> {
static async getAll(programId: string, paginationQuery: PaginationQuery, full : boolean, metadata: boolean): Promise<Result<Error, BiResponse>> {
try {
// TODO: update pageSize setting when we can do backend brapi sorting
const { data } = await api.call({
url: `${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/brapi/v2/trials`,
method: 'get',
params: { full, pageSize: 1000000 }
params: { full, pageSize: 1000000, metadata: true }
}) as Response;

return ResultGenerator.success(new BiResponse(data));
Expand Down
10 changes: 7 additions & 3 deletions src/breeding-insight/service/TrialService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {Result, Err, Success, ResultGenerator } from "@/breeding-insight/model/R

export class TrialService {

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

if (paginationQuery === undefined){
paginationQuery = new PaginationQuery(0, 0, true);
Expand All @@ -34,10 +34,14 @@ export class TrialService {
full = false;
}

if (metadata === undefined) {
metadata = true;
}

try {
if(!programId) throw new Error('missing or invalid program id');

let response = await TrialDAO.getAll(programId, paginationQuery, full) as Result<Error, BiResponse>;
let response = await TrialDAO.getAll(programId, paginationQuery, full, metadata) as Result<Error, BiResponse>;
if(response.isErr()) throw response.value;

const frontendModel = (res: BiResponse): [Trial[], Metadata] => {
Expand All @@ -46,7 +50,7 @@ export class TrialService {

data = PaginationController.mockSortRecords(data);
trials = data.map((trial: any) => {
return new Trial(trial.trialDbId, trial.trialName, trial.active);
return trial as Trial;
});

let newPagination;
Expand Down
163 changes: 163 additions & 0 deletions src/components/experiments/ExperimentsObservationsTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<!--
- 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.
-->

<template>
<section id="experimentsObservationsTableLabel">

<div class="is-clearfix"></div>

<ExpandableTable
v-bind:records.sync="experiments"
v-bind:loading="this.experimentsLoading"
v-bind:pagination="experimentsPagination"
v-on:show-error-notification="$emit('show-error-notification', $event)"
v-on:paginate="paginationController.updatePage($event)"
v-on:paginate-toggle-all="paginationController.toggleShowAll()"
v-on:paginate-page-size="paginationController.updatePageSize($event)"
>
<b-table-column label="Title" cell-class="fixed-width-wrapped" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
{{ props.row.data.trialName }}
</b-table-column>
<b-table-column label="Status" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
{{ getStatus(props.row.data.active) }}
</b-table-column>
<b-table-column label="Date Created" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
{{ }}
</b-table-column>
<b-table-column label="Created By" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
{{ }}
</b-table-column>
<b-table-column label="Datasets" cell-class="fixed-width-wrapped" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
<template v-for="dataset in props.row.data.additionalInfo.datasets">
<span v-bind:key="dataset" class="tag is-info is-normal mr-1">{{ dataset }}</span>
</template>
</b-table-column>
<b-table-column field="data.listDbId" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
<a href="#" v-on:click="activateExtensionSelect(props.row.data.listDbId)">
Download
</a>
</b-table-column>

<template v-slot:emptyMessage>
<p class="has-text-weight-bold">
No experiments and observations are currently defined for this program.
</p>
</template>
</ExpandableTable>
</section>
</template>

<script lang="ts">
import {Component, Prop, Vue, Watch} from 'vue-property-decorator'
import {validationMixin} from 'vuelidate';
import { mapGetters } from 'vuex'
import {Program} from "@/breeding-insight/model/Program";
import {TrialService} from "@/breeding-insight/service/TrialService";
import EmptyTableMessage from "@/components/tables/EmtpyTableMessage.vue";
import TableColumn from "@/components/tables/TableColumn.vue";
import {Metadata, Pagination} from "@/breeding-insight/model/BiResponse";
import {PaginationController} from "@/breeding-insight/model/view_models/PaginationController";
import {PaginationQuery} from "@/breeding-insight/model/PaginationQuery";
import {Trial} from '@/breeding-insight/model/Trial'
import {Result, Err, Success, ResultGenerator } from "@/breeding-insight/model/Result";
import ExpandableTable from '@/components/tables/expandableTable/ExpandableTable.vue';
import {FileType} from "@/breeding-insight/model/FileType";
import SelectModal from "@/components/modals/SelectModal.vue";

@Component({
mixins: [validationMixin],
components: { ExpandableTable, EmptyTableMessage, TableColumn, SelectModal},
computed: {
...mapGetters([
'activeProgram'
])
}
})
export default class ExperimentsObservationsTable extends Vue {

private activeProgram?: Program;
private experiments: Trial[] = [];
private experimentsPagination?: Pagination = new Pagination();
private programName: string = "Program Name";

private experimentsLoading = true;

private paginationController: PaginationController = new PaginationController();

private experimentDownloadTitle = 'Download Experiment';
private experimentDownloadSubtitle = 'File Format';
private modalActive: boolean = false;
//private fileExtension: string;
//private selectedExperimentDbId: string;
private fileOptions = Object.values(FileType);

mounted() {
this.getExperiments();
}

@Watch('paginationController', { deep: true})
async getExperiments() {
let paginationQuery: PaginationQuery = PaginationController.getPaginationSelections(
this.paginationController.currentPage,
this.paginationController.pageSize,
this.paginationController.showAll);

this.paginationController.setCurrentCall(paginationQuery);

try {
const response: Result<Error, [Trial[], Metadata]> = await TrialService.getAll(this.activeProgram!.id!, paginationQuery);
if(response.isErr()) throw response.value;
let [experiments, metadata] = response.value;

if (this.paginationController.matchesCurrentRequest(metadata.pagination)) {
this.experiments = experiments;
this.experimentsPagination = metadata.pagination;
}
} catch (err) {
// Display error that experiments cannot be loaded
this.$emit('show-error-notification', 'Error while trying to load experiments');
} finally {
this.experimentsLoading=false;
}
}

activateExtensionSelect(experimentDbId: string){
this.modalActive = true;
this.selectedExperimentDbId = experimentDbId;
}

cancelDownload(){
this.modalActive = false;
this.selectedExperimentDbId = "";
this.fileExtension = "";
}

setFileExtension(value){
this.fileExtension = value;
}

getStatus(active){
if (active) {
return "active";
} else {
return "archived";
}
}

}

</script>
4 changes: 2 additions & 2 deletions src/components/layouts/UserSideBarLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@
</li>
<li>
<router-link
v-bind:to="{name: 'trials-studies', params: {programId: activeProgram.id}}"
v-bind:to="{name: 'experiments-observations', params: {programId: activeProgram.id}}"
>
Trials and Studies <span class="ml-2 tag is-warning">Beta</span>
Experiments & Observations
</router-link>
</li>
</ul>
Expand Down
32 changes: 6 additions & 26 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import ProgramConfiguration from "@/views/program/ProgramConfiguration.vue";
import JobManagement from '@/views/program/JobManagement.vue';
import GermplasmPedigreesView from "@/components/germplasm/GermplasmPedigreesView.vue";
import ImportExperiment from "@/views/import/ImportExperiment.vue";
import ExperimentsAndObservations from "@/views/experiments-and-observations/ExperimentsAndObservations.vue";

Vue.use(VueRouter);

Expand Down Expand Up @@ -171,35 +172,14 @@ const routes = [
component: StudiesList
},
{
path: '/programs/:programId/trials-studies',
name: 'trials-studies',
path: '/programs/:programId/experiments-observations',
name: 'experiments-observations',
meta: {
title: 'Trials and Studies',
title: 'Experiments & Observations',
layout: layouts.userSideBar
},
component: TrialsAndStudies,
redirect: {name: 'trials-list'},
beforeEnter: processProgramNavigation,
children: [
{
path: 'studies',
name: 'studies-list',
meta: {
title: 'Studies',
layout: layouts.userSideBar
},
component: StudiesList
},
{
path: 'trials',
name: 'trials-list',
meta: {
title: 'Trials',
layout: layouts.userSideBar
},
component: Trials
}
]
component: ExperimentsAndObservations,
beforeEnter: processProgramNavigation
},
{
path: '/programs/:programId/program-management',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!--
- 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.
-->

<template>
<div class="experiments-observations">
<h1 class="title">
Experiments & Observations
</h1>
<button
v-if="$ability.can('create', 'Import')"
class="button is-primary is-pulled-right has-text-weight-bold"
v-on:click="$router.push({name: 'experiment-import', params: {programId: activeProgram.id}})"
>
<span class="icon is-small">
<PlusCircleIcon
size="1.5x"
aria-hidden="true"
/>
</span>
<span>
Import Experiments & Observations
</span>
</button>
<ExperimentsObservationsTable
v-on:show-success-notification="$emit('show-success-notification', $event)"
v-on:show-error-notification="$emit('show-error-notification', $event)"
>
</ExperimentsObservationsTable>
</div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import ExperimentsObservationsTable from '@/components/experiments/ExperimentsObservationsTable.vue';
import {PlusCircleIcon} from 'vue-feather-icons'
import {mapGetters} from "vuex";
import {Program} from "@/breeding-insight/model/Program";
import TrialsAndStudiesBase from "@/components/trials/TrialsAndStudiesBase.vue";

@Component({
components: {
ExperimentsObservationsTable, PlusCircleIcon
},
computed: {
...mapGetters([
'activeProgram'
])
}
})
export default class ExperimentsAndObservations extends TrialsAndStudiesBase {
//todo check use of base

private activeProgram?: Program;

}
</script>

0 comments on commit 85a4efc

Please sign in to comment.