Skip to content
14 changes: 14 additions & 0 deletions src/breeding-insight/dao/SampleSubmissionDAO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ export class SampleSubmissionDAO {
}
}

static async deleteSubmission(programId: string, submissionId: string): Promise<Result<Error, Void>> {
const config: any = {};
config.url = `${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/submissions/${submissionId}`;
config.method = 'delete';
config.programId = programId;
config.submissionId = submissionId;
try {
await api.call(config);
return ResultGenerator.success();
} catch (error) {
return ResultGenerator.err(error);
}
}

static async submitToDArT(programId: string, submissionId: string): Promise<Result<Error, VendorOrderSubmission>> {
const config: any = {};
config.url = `${process.env.VUE_APP_BI_API_V1_PATH}/programs/${programId}/submissions/${submissionId}/submit?vendor=dart`;
Expand Down
36 changes: 21 additions & 15 deletions src/breeding-insight/service/SampleSubmissionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,30 @@ export class SampleSubmissionService {
return await SampleSubmissionDAO.getSubmissionById(programId, submissionId, true);
}

static async submitToDArT(programId: string, submissionId: string): Promise<Result<Error, VendorOrderSubmission>> {
if (!programId) {
return ResultGenerator.err(new Error('Missing or invalid program id'));
}
return await SampleSubmissionDAO.submitToDArT(programId, submissionId);
static async submitToDArT(programId: string, submissionId: string): Promise<Result<Error, VendorOrderSubmission>> {
if (!programId) {
return ResultGenerator.err(new Error('Missing or invalid program id'));
}
return await SampleSubmissionDAO.submitToDArT(programId, submissionId);
}

static async checkVendorStatus(programId: string, submissionId: string): Promise<Result<Error, SampleSubmission>> {
if (!programId) {
return ResultGenerator.err(new Error('Missing or invalid program id'));
}
return await SampleSubmissionDAO.checkVendorStatus(programId, submissionId);
static async checkVendorStatus(programId: string, submissionId: string): Promise<Result<Error, SampleSubmission>> {
if (!programId) {
return ResultGenerator.err(new Error('Missing or invalid program id'));
}
return await SampleSubmissionDAO.checkVendorStatus(programId, submissionId);
}

static async updateSubmissionStatus(programId: string, submissionId: string, status: string): Promise<Result<Error, SampleSubmission>> {
if (!programId) {
return ResultGenerator.err(new Error('Missing or invalid program id'));
}
return await SampleSubmissionDAO.updateSubmissionStatus(programId, submissionId, status);
static async updateSubmissionStatus(programId: string, submissionId: string, status: string): Promise<Result<Error, SampleSubmission>> {
if (!programId) {
return ResultGenerator.err(new Error('Missing or invalid program id'));
}
return await SampleSubmissionDAO.updateSubmissionStatus(programId, submissionId, status);
}

static async deleteSubmission(programId: string, submissionId: string) : Promise<Result<Error, Void>> {
return await SampleSubmissionDAO.deleteSubmission(programId, submissionId);
}


}
2 changes: 2 additions & 0 deletions src/config/ability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const rolePermissions: Record<string, DefinePermissions> = {
can('access', 'Ontology');
can('access', 'Germplasm');
can('access', 'SampleManagement');
can('delete', 'Submission');
can('access', 'ProgramAdministration');
can('access', 'BrAPI');
can('access', 'JobManagement');
Expand All @@ -73,6 +74,7 @@ const rolePermissions: Record<string, DefinePermissions> = {
can('manage', 'User');
can('access', 'AdminSection');
can('submit', 'Submission');
can('delete', 'Submission');
can('access', 'Experiment');
can('access', 'Ontology');
can('access', 'Germplasm');
Expand Down
12 changes: 0 additions & 12 deletions src/views/sample-mgmt/SampleManagement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,6 @@
</ExpandableTable>
</div>
</div>
<GenericModal
v-bind:active.sync="showGenerateFileModal"
v-bind:msg-title="'Generate Sample Management File'"
v-on:deactivate="closeModal()"
v-bind:modalClass="'generate-sample-file'"
>
<h2>Visible!</h2>
<template v-slot:footer>
<button class="button is-success" v-on:click="closeModal()">Generate</button>
<button class="button" v-on:click="closeModal()">Cancel</button>
</template>
</GenericModal>
</div>
</template>

Expand Down
67 changes: 66 additions & 1 deletion src/views/sample-mgmt/SubmissionDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@
<router-link v-bind:to="{name: 'sample-management', params: {programId: activeProgram.id}}">
&lt; Sample Management
</router-link>

<template v-if="!submissionDetailsLoading">
<ConfirmationModal
v-bind:unique-id="submissionId"
v-bind:modal-title="`Delete Submission ${submission.name}`"
v-bind:confirmedAction="deleteSampleSubmission"
v-bind:active="deleteModalActive"
modal-class="germplasm-list-deletion-button"
v-on:deactivate="deleteModalActive = false"
v-on:show-error-notification="$emit('show-error-notification', $event)"
>
<template #form>
<p><strong>{{submission.samples.length}} samples</strong> will be deleted. Are you sure you want to delete the sample submission?</p>
</template>
<slot />
</ConfirmationModal>
</template>

<div class="mb-4"/>
<template v-if="submissionLoading">
<div class="loading-indicator"></div>
Expand Down Expand Up @@ -62,6 +80,7 @@
v-on:submit="startOrderSubmission()"
v-on:manual-update-status="startManualUpdate()"
v-on:check-status="checkVendorStatus()"
v-on:delete="deleteSubmission()"
/>
</article>
</div>
Expand Down Expand Up @@ -358,15 +377,17 @@ import StatusEnum = VendorOrderStatusResponseResult.StatusEnum;
import {Plate} from "@/breeding-insight/brapi/model/geno/plate";
import * as XLSX from "xlsx";
import {WorkBook} from "xlsx";
import ConfirmationModal from "@/components/modals/ConfirmationModal.vue";

@Component({
components: {
ConfirmationModal,
GenericModal,
ExpandableTable,
GermplasmLink,
PlusCircleIcon,
ExperimentObservationsDownloadModal,
ActionMenu
ActionMenu,
},
computed: {
...mapGetters([
Expand All @@ -392,6 +413,7 @@ export default class SubmissionDetails extends ProgramsBase {
private showUpdateModal = false;
private updateStarted = false;
private statusEdit?: string = 'NOT SUBMITTED';
private deleteModalActive: boolean = false;

private collator = new Intl.Collator('en', {numeric: true, sensitivity: 'base'});

Expand All @@ -406,6 +428,12 @@ export default class SubmissionDetails extends ProgramsBase {
return this.$route.params.submissionId;
}

private deleteSuccess() {
// Navigate to the submissions table since this submission no longer exists
this.$router.push({ name: "sample-management" });
this.$emit('show-success-notification', `Successfully deleted sample submission`);
}

async getSubmission(showLoading: boolean = true) {
this.submissionLoading = showLoading;

Expand Down Expand Up @@ -447,6 +475,12 @@ export default class SubmissionDetails extends ProgramsBase {
}
}

if (this.$ability.can('delete', 'Submission')) {
const enabled = !this.submission!.submitted && this.submission!.vendorStatus !== StatusEnum.Completed.toUpperCase();

actionsMenuItems.push(new ActionMenuItem('submission-delete', 'delete', 'Delete submission', enabled));
}

this.actions = actionsMenuItems;
}

Expand Down Expand Up @@ -717,5 +751,36 @@ export default class SubmissionDetails extends ProgramsBase {
let value = props.data.additionalInfo.gid;
return Number(value) === (Number(input));
}

deleteSubmission() {
this.deleteModalActive = true;
}

async deleteSampleSubmission(): Promise<void> {
if (this.activeProgram) {
try {
const result: Result<Error, Void> = await SampleSubmissionService.deleteSubmission(this.activeProgram.id, this.submissionId);
if (result.isErr()) {
const response = result.value.response;

if (response && response.status === 405) {
this.$emit('show-error-notification', `Cannot delete a submission with submitted or completed status`);
return;
}
this.$emit('show-error-notification', `Unknown error deleting submission`);

} else {
this.deleteSuccess();
}

} catch (error) {
this.$emit('show-error-notification', `Error while trying to delete the sample submission`);
}
}
}

cancelDelete(){
this.$emit('deactivate');
}
}
</script>