Skip to content

Commit 0de4fec

Browse files
committed
Merge 0.8 code in future/1.0 into develop
2 parents 5e29135 + c1eef5b commit 0de4fec

File tree

7 files changed

+253
-33
lines changed

7 files changed

+253
-33
lines changed

src/assets/scss/main.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,10 @@ table tr.is-edited + .detail {
322322
}
323323
}
324324

325+
.table td.fixed-width-wrapped {
326+
word-break: break-word;
327+
width: 25%;
328+
}
325329

326330
.table.is-striped tbody tr:not(.is-edited):nth-child(2n).is-new {
327331
background-color: $success-light;

src/breeding-insight/dao/TrialDAO.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ import { Result, Err, Success, ResultGenerator } from "@/breeding-insight/model/
2323

2424
export class TrialDAO {
2525

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

3535
return ResultGenerator.success(new BiResponse(data));

src/breeding-insight/service/TrialService.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {Result, Err, Success, ResultGenerator } from "@/breeding-insight/model/R
2424

2525
export class TrialService {
2626

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

2929
if (paginationQuery === undefined){
3030
paginationQuery = new PaginationQuery(0, 0, true);
@@ -34,10 +34,14 @@ export class TrialService {
3434
full = false;
3535
}
3636

37+
if (metadata === undefined) {
38+
metadata = true;
39+
}
40+
3741
try {
3842
if(!programId) throw new Error('missing or invalid program id');
3943

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

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

4751
data = PaginationController.mockSortRecords(data);
4852
trials = data.map((trial: any) => {
49-
return new Trial(trial.trialDbId, trial.trialName, trial.active);
53+
return trial as Trial;
5054
});
5155

5256
let newPagination;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<!--
2+
- See the NOTICE file distributed with this work for additional information
3+
- regarding copyright ownership.
4+
-
5+
- Licensed under the Apache License, Version 2.0 (the "License");
6+
- you may not use this file except in compliance with the License.
7+
- You may obtain a copy of the License at
8+
-
9+
- http://www.apache.org/licenses/LICENSE-2.0
10+
-
11+
- Unless required by applicable law or agreed to in writing, software
12+
- distributed under the License is distributed on an "AS IS" BASIS,
13+
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
- See the License for the specific language governing permissions and
15+
- limitations under the License.
16+
-->
17+
18+
<template>
19+
<section id="experimentsObservationsTableLabel">
20+
21+
<div class="is-clearfix"></div>
22+
23+
<ExpandableTable
24+
v-bind:records.sync="experiments"
25+
v-bind:loading="this.experimentsLoading"
26+
v-bind:pagination="experimentsPagination"
27+
v-on:show-error-notification="$emit('show-error-notification', $event)"
28+
v-on:paginate="paginationController.updatePage($event)"
29+
v-on:paginate-toggle-all="paginationController.toggleShowAll()"
30+
v-on:paginate-page-size="paginationController.updatePageSize($event)"
31+
>
32+
<b-table-column label="Title" cell-class="fixed-width-wrapped" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
33+
{{ props.row.data.trialName }}
34+
</b-table-column>
35+
<b-table-column label="Status" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
36+
{{ getStatus(props.row.data.active) }}
37+
</b-table-column>
38+
<b-table-column label="Date Created" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
39+
{{ }}
40+
</b-table-column>
41+
<b-table-column label="Created By" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
42+
{{ }}
43+
</b-table-column>
44+
<b-table-column label="Datasets" cell-class="fixed-width-wrapped" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
45+
<template v-for="dataset in props.row.data.additionalInfo.datasets">
46+
<span v-bind:key="dataset" class="tag is-info is-normal mr-1">{{ dataset }}</span>
47+
</template>
48+
</b-table-column>
49+
<b-table-column field="data.listDbId" sortable v-slot="props" :th-attrs="(column) => ({scope:'col'})">
50+
<a href="#" v-on:click="activateExtensionSelect(props.row.data.listDbId)">
51+
Download
52+
</a>
53+
</b-table-column>
54+
55+
<template v-slot:emptyMessage>
56+
<p class="has-text-weight-bold">
57+
No experiments and observations are currently defined for this program.
58+
</p>
59+
</template>
60+
</ExpandableTable>
61+
</section>
62+
</template>
63+
64+
<script lang="ts">
65+
import {Component, Prop, Vue, Watch} from 'vue-property-decorator'
66+
import {validationMixin} from 'vuelidate';
67+
import { mapGetters } from 'vuex'
68+
import {Program} from "@/breeding-insight/model/Program";
69+
import {TrialService} from "@/breeding-insight/service/TrialService";
70+
import EmptyTableMessage from "@/components/tables/EmtpyTableMessage.vue";
71+
import TableColumn from "@/components/tables/TableColumn.vue";
72+
import {Metadata, Pagination} from "@/breeding-insight/model/BiResponse";
73+
import {PaginationController} from "@/breeding-insight/model/view_models/PaginationController";
74+
import {PaginationQuery} from "@/breeding-insight/model/PaginationQuery";
75+
import {Trial} from '@/breeding-insight/model/Trial'
76+
import {Result, Err, Success, ResultGenerator } from "@/breeding-insight/model/Result";
77+
import ExpandableTable from '@/components/tables/expandableTable/ExpandableTable.vue';
78+
import {FileType} from "@/breeding-insight/model/FileType";
79+
import SelectModal from "@/components/modals/SelectModal.vue";
80+
81+
@Component({
82+
mixins: [validationMixin],
83+
components: { ExpandableTable, EmptyTableMessage, TableColumn, SelectModal},
84+
computed: {
85+
...mapGetters([
86+
'activeProgram'
87+
])
88+
}
89+
})
90+
export default class ExperimentsObservationsTable extends Vue {
91+
92+
private activeProgram?: Program;
93+
private experiments: Trial[] = [];
94+
private experimentsPagination?: Pagination = new Pagination();
95+
private programName: string = "Program Name";
96+
97+
private experimentsLoading = true;
98+
99+
private paginationController: PaginationController = new PaginationController();
100+
101+
private experimentDownloadTitle = 'Download Experiment';
102+
private experimentDownloadSubtitle = 'File Format';
103+
private modalActive: boolean = false;
104+
//private fileExtension: string;
105+
//private selectedExperimentDbId: string;
106+
private fileOptions = Object.values(FileType);
107+
108+
mounted() {
109+
this.getExperiments();
110+
}
111+
112+
@Watch('paginationController', { deep: true})
113+
async getExperiments() {
114+
let paginationQuery: PaginationQuery = PaginationController.getPaginationSelections(
115+
this.paginationController.currentPage,
116+
this.paginationController.pageSize,
117+
this.paginationController.showAll);
118+
119+
this.paginationController.setCurrentCall(paginationQuery);
120+
121+
try {
122+
const response: Result<Error, [Trial[], Metadata]> = await TrialService.getAll(this.activeProgram!.id!, paginationQuery);
123+
if(response.isErr()) throw response.value;
124+
let [experiments, metadata] = response.value;
125+
126+
if (this.paginationController.matchesCurrentRequest(metadata.pagination)) {
127+
this.experiments = experiments;
128+
this.experimentsPagination = metadata.pagination;
129+
}
130+
} catch (err) {
131+
// Display error that experiments cannot be loaded
132+
this.$emit('show-error-notification', 'Error while trying to load experiments');
133+
} finally {
134+
this.experimentsLoading=false;
135+
}
136+
}
137+
138+
activateExtensionSelect(experimentDbId: string){
139+
this.modalActive = true;
140+
this.selectedExperimentDbId = experimentDbId;
141+
}
142+
143+
cancelDownload(){
144+
this.modalActive = false;
145+
this.selectedExperimentDbId = "";
146+
this.fileExtension = "";
147+
}
148+
149+
setFileExtension(value){
150+
this.fileExtension = value;
151+
}
152+
153+
getStatus(active){
154+
if (active) {
155+
return "active";
156+
} else {
157+
return "archived";
158+
}
159+
}
160+
161+
}
162+
163+
</script>

src/components/layouts/UserSideBarLayout.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@
138138
</li>
139139
<li>
140140
<router-link
141-
v-bind:to="{name: 'trials-studies', params: {programId: activeProgram.id}}"
141+
v-bind:to="{name: 'experiments-observations', params: {programId: activeProgram.id}}"
142142
>
143-
Trials and Studies <span class="ml-2 tag is-warning">Beta</span>
143+
Experiments & Observations
144144
</router-link>
145145
</li>
146146
</ul>

src/router/index.ts

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import ProgramConfiguration from "@/views/program/ProgramConfiguration.vue";
6767
import JobManagement from '@/views/program/JobManagement.vue';
6868
import GermplasmPedigreesView from "@/components/germplasm/GermplasmPedigreesView.vue";
6969
import ImportExperiment from "@/views/import/ImportExperiment.vue";
70+
import ExperimentsAndObservations from "@/views/experiments-and-observations/ExperimentsAndObservations.vue";
7071

7172
Vue.use(VueRouter);
7273

@@ -171,35 +172,14 @@ const routes = [
171172
component: StudiesList
172173
},
173174
{
174-
path: '/programs/:programId/trials-studies',
175-
name: 'trials-studies',
175+
path: '/programs/:programId/experiments-observations',
176+
name: 'experiments-observations',
176177
meta: {
177-
title: 'Trials and Studies',
178+
title: 'Experiments & Observations',
178179
layout: layouts.userSideBar
179180
},
180-
component: TrialsAndStudies,
181-
redirect: {name: 'trials-list'},
182-
beforeEnter: processProgramNavigation,
183-
children: [
184-
{
185-
path: 'studies',
186-
name: 'studies-list',
187-
meta: {
188-
title: 'Studies',
189-
layout: layouts.userSideBar
190-
},
191-
component: StudiesList
192-
},
193-
{
194-
path: 'trials',
195-
name: 'trials-list',
196-
meta: {
197-
title: 'Trials',
198-
layout: layouts.userSideBar
199-
},
200-
component: Trials
201-
}
202-
]
181+
component: ExperimentsAndObservations,
182+
beforeEnter: processProgramNavigation
203183
},
204184
{
205185
path: '/programs/:programId/program-management',
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<!--
2+
- See the NOTICE file distributed with this work for additional information
3+
- regarding copyright ownership.
4+
-
5+
- Licensed under the Apache License, Version 2.0 (the "License");
6+
- you may not use this file except in compliance with the License.
7+
- You may obtain a copy of the License at
8+
-
9+
- http://www.apache.org/licenses/LICENSE-2.0
10+
-
11+
- Unless required by applicable law or agreed to in writing, software
12+
- distributed under the License is distributed on an "AS IS" BASIS,
13+
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
- See the License for the specific language governing permissions and
15+
- limitations under the License.
16+
-->
17+
18+
<template>
19+
<div class="experiments-observations">
20+
<h1 class="title">
21+
Experiments & Observations
22+
</h1>
23+
<button
24+
v-if="$ability.can('create', 'Import')"
25+
class="button is-primary is-pulled-right has-text-weight-bold"
26+
v-on:click="$router.push({name: 'experiment-import', params: {programId: activeProgram.id}})"
27+
>
28+
<span class="icon is-small">
29+
<PlusCircleIcon
30+
size="1.5x"
31+
aria-hidden="true"
32+
/>
33+
</span>
34+
<span>
35+
Import Experiments & Observations
36+
</span>
37+
</button>
38+
<ExperimentsObservationsTable
39+
v-on:show-success-notification="$emit('show-success-notification', $event)"
40+
v-on:show-error-notification="$emit('show-error-notification', $event)"
41+
>
42+
</ExperimentsObservationsTable>
43+
</div>
44+
</template>
45+
46+
<script lang="ts">
47+
import { Component, Prop, Vue } from 'vue-property-decorator'
48+
import ExperimentsObservationsTable from '@/components/experiments/ExperimentsObservationsTable.vue';
49+
import {PlusCircleIcon} from 'vue-feather-icons'
50+
import {mapGetters} from "vuex";
51+
import {Program} from "@/breeding-insight/model/Program";
52+
import TrialsAndStudiesBase from "@/components/trials/TrialsAndStudiesBase.vue";
53+
54+
@Component({
55+
components: {
56+
ExperimentsObservationsTable, PlusCircleIcon
57+
},
58+
computed: {
59+
...mapGetters([
60+
'activeProgram'
61+
])
62+
}
63+
})
64+
export default class ExperimentsAndObservations extends TrialsAndStudiesBase {
65+
66+
private activeProgram?: Program;
67+
68+
}
69+
</script>

0 commit comments

Comments
 (0)