mirror of
https://github.com/pcvolkmer/grz-metadata-processor.git
synced 2025-07-01 20:12:54 +00:00
feat: add lab data profiles
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
package dev.pcvolkmer.onco.grzmetadataprocessor.data
|
package dev.pcvolkmer.onco.grzmetadataprocessor.data
|
||||||
|
|
||||||
import org.springframework.data.annotation.Id
|
import org.springframework.data.annotation.Id
|
||||||
|
import org.springframework.data.annotation.Transient
|
||||||
import org.springframework.data.relational.core.mapping.Table
|
import org.springframework.data.relational.core.mapping.Table
|
||||||
import org.springframework.data.repository.CrudRepository
|
import org.springframework.data.repository.CrudRepository
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ data class LabData(
|
|||||||
val sequenceType: SequenceType? = null,
|
val sequenceType: SequenceType? = null,
|
||||||
val sequenceSubtype: SequenceSubtype? = null,
|
val sequenceSubtype: SequenceSubtype? = null,
|
||||||
val fragmentationMethod: FragmentationMethod? = null,
|
val fragmentationMethod: FragmentationMethod? = null,
|
||||||
|
val profile: Long? = null,
|
||||||
val libraryType: LibraryType? = null,
|
val libraryType: LibraryType? = null,
|
||||||
val libraryPrepKit: String = "",
|
val libraryPrepKit: String = "",
|
||||||
val libraryPrepKitManufacturer: String = "",
|
val libraryPrepKitManufacturer: String = "",
|
||||||
@ -30,7 +32,10 @@ data class LabData(
|
|||||||
val bioinformaticsPipelineName: String = "",
|
val bioinformaticsPipelineName: String = "",
|
||||||
val bioinformaticsPipelineVersion: String = "",
|
val bioinformaticsPipelineVersion: String = "",
|
||||||
val referenceGenome: ReferenceGenome? = null,
|
val referenceGenome: ReferenceGenome? = null,
|
||||||
)
|
) {
|
||||||
|
@Transient
|
||||||
|
var profileData: LabDataProfile? = null
|
||||||
|
}
|
||||||
|
|
||||||
enum class SampleConservation(val value: String) {
|
enum class SampleConservation(val value: String) {
|
||||||
FRESH_TISSUE("fresh-tissue"),
|
FRESH_TISSUE("fresh-tissue"),
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package dev.pcvolkmer.onco.grzmetadataprocessor.data
|
||||||
|
|
||||||
|
import org.springframework.data.annotation.Id
|
||||||
|
import org.springframework.data.relational.core.mapping.Table
|
||||||
|
import org.springframework.data.repository.CrudRepository
|
||||||
|
|
||||||
|
@Table("tbl_lab_data_profile")
|
||||||
|
data class LabDataProfile(
|
||||||
|
@Id val id: Long? = null,
|
||||||
|
val profileName: String = "",
|
||||||
|
val libraryType: LibraryType? = null,
|
||||||
|
val libraryPrepKit: String = "",
|
||||||
|
val libraryPrepKitManufacturer: String = "",
|
||||||
|
val sequencerModel: String = "",
|
||||||
|
val sequencerManufacturer: String = "",
|
||||||
|
val kitName: String = "",
|
||||||
|
val kitManufacturer: String = "",
|
||||||
|
val enrichmentKit: String = "",
|
||||||
|
val enrichmentKitManufacturer: EnrichmentKitManufacturer? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
interface LabDataProfileRepository : CrudRepository<LabDataProfile, Long>
|
@ -1,6 +1,7 @@
|
|||||||
package dev.pcvolkmer.onco.grzmetadataprocessor.web
|
package dev.pcvolkmer.onco.grzmetadataprocessor.web
|
||||||
|
|
||||||
import dev.pcvolkmer.onco.grzmetadataprocessor.data.LabData
|
import dev.pcvolkmer.onco.grzmetadataprocessor.data.LabData
|
||||||
|
import dev.pcvolkmer.onco.grzmetadataprocessor.data.LabDataProfileRepository
|
||||||
import dev.pcvolkmer.onco.grzmetadataprocessor.data.LabDataRepository
|
import dev.pcvolkmer.onco.grzmetadataprocessor.data.LabDataRepository
|
||||||
import org.springframework.stereotype.Controller
|
import org.springframework.stereotype.Controller
|
||||||
import org.springframework.ui.Model
|
import org.springframework.ui.Model
|
||||||
@ -9,34 +10,44 @@ import org.springframework.web.bind.annotation.*
|
|||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/donors/{donorId}/labdatas")
|
@RequestMapping("/donors/{donorId}/labdatas")
|
||||||
class LabDataController(
|
class LabDataController(
|
||||||
private val repository: LabDataRepository
|
private val labDataRepository: LabDataRepository,
|
||||||
|
private val labDataProfileRepository: LabDataProfileRepository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
fun getAllLabData(@PathVariable donorId: Long, model: Model): String {
|
fun getAllLabData(@PathVariable donorId: Long, model: Model): String {
|
||||||
model.addAttribute("labdatas", repository.findByDonorId(donorId))
|
model.addAttribute("labdatas", allLabDatasByDonorId(donorId))
|
||||||
|
model.addAttribute("labdataprofiles", labDataProfileRepository.findAll())
|
||||||
return "labdatas"
|
return "labdatas"
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
fun postLabData(@PathVariable donorId: Long, model: Model): String {
|
fun postLabData(@PathVariable donorId: Long, model: Model): String {
|
||||||
repository.save(LabData(donorId = donorId))
|
labDataRepository.save(LabData(donorId = donorId))
|
||||||
model.addAttribute("labdatas", repository.findByDonorId(donorId))
|
model.addAttribute("labdatas", allLabDatasByDonorId(donorId))
|
||||||
|
model.addAttribute("labdataprofiles", labDataProfileRepository.findAll())
|
||||||
return "labdatas"
|
return "labdatas"
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(path = ["{labdataId}"])
|
@PutMapping(path = ["{labdataId}"])
|
||||||
fun putLabData(@PathVariable donorId: Long, labData: LabData, model: Model): String {
|
fun putLabData(@PathVariable donorId: Long, labData: LabData, model: Model): String {
|
||||||
repository.save(labData)
|
labDataRepository.save(labData)
|
||||||
model.addAttribute("labdatas", repository.findByDonorId(donorId))
|
model.addAttribute("labdatas", allLabDatasByDonorId(donorId))
|
||||||
|
model.addAttribute("labdataprofiles", labDataProfileRepository.findAll())
|
||||||
return "labdatas"
|
return "labdatas"
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = ["{labdataId}"])
|
@DeleteMapping(path = ["{labdataId}"])
|
||||||
fun deleteLabData(@PathVariable donorId: Long, @PathVariable labdataId: Long, model: Model): String {
|
fun deleteLabData(@PathVariable donorId: Long, @PathVariable labdataId: Long, model: Model): String {
|
||||||
repository.deleteById(labdataId)
|
labDataRepository.deleteById(labdataId)
|
||||||
model.addAttribute("labdatas", repository.findByDonorId(donorId))
|
model.addAttribute("labdatas", allLabDatasByDonorId(donorId))
|
||||||
|
model.addAttribute("labdataprofiles", labDataProfileRepository.findAll())
|
||||||
return "labdatas"
|
return "labdatas"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun allLabDatasByDonorId(donorId: Long): List<LabData> {
|
||||||
|
return labDataRepository.findByDonorId(donorId)
|
||||||
|
.map { it.apply { labDataProfileRepository.findById(this.profile ?: 0).ifPresent { profileData = it } } }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package dev.pcvolkmer.onco.grzmetadataprocessor.web
|
||||||
|
|
||||||
|
import dev.pcvolkmer.onco.grzmetadataprocessor.data.LabDataProfile
|
||||||
|
import dev.pcvolkmer.onco.grzmetadataprocessor.data.LabDataProfileRepository
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.ui.Model
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/labdataprofiles")
|
||||||
|
class LabDataProfileController(
|
||||||
|
private val repository: LabDataProfileRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
fun getAllLabDataProfiles(model: Model): String {
|
||||||
|
println(repository.findAll().sortedByDescending { it.id })
|
||||||
|
model.addAttribute("labdataprofiles", repository.findAll().sortedByDescending { it.id })
|
||||||
|
return "labdataprofiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
fun postLabDataProfile(model: Model): String {
|
||||||
|
repository.save(LabDataProfile(profileName = "Neues Sequenzierprofil"))
|
||||||
|
model.addAttribute("labdataprofiles", repository.findAll().sortedByDescending { it.id })
|
||||||
|
return "labdataprofiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping(path = ["{labdataProfileId}"])
|
||||||
|
fun putLabData(@PathVariable labdataProfileId: Long, labDataProfile: LabDataProfile, model: Model): String {
|
||||||
|
repository.save(labDataProfile)
|
||||||
|
model.addAttribute("labdataprofiles", repository.findAll().sortedByDescending { it.id })
|
||||||
|
return "labdataprofiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping(path = ["{labdataProfileId}"])
|
||||||
|
fun deleteLabData(@PathVariable labdataProfileId: Long, model: Model): String {
|
||||||
|
repository.deleteById(labdataProfileId)
|
||||||
|
model.addAttribute("labdataprofiles", repository.findAll().sortedByDescending { it.id })
|
||||||
|
return "labdataprofiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS tbl_lab_data_profile
|
||||||
|
(
|
||||||
|
id int auto_increment primary key,
|
||||||
|
profile_name varchar(255),
|
||||||
|
library_type varchar(255),
|
||||||
|
library_prep_kit varchar(255) not null,
|
||||||
|
library_prep_kit_manufacturer varchar(255) not null,
|
||||||
|
sequencer_model varchar(255) not null,
|
||||||
|
sequencer_manufacturer varchar(255) not null,
|
||||||
|
kit_name varchar(255) not null,
|
||||||
|
kit_manufacturer varchar(255) not null,
|
||||||
|
enrichment_kit varchar(255) not null,
|
||||||
|
enrichment_kit_manufacturer varchar(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE tbl_lab_data ADD COLUMN profile int;
|
@ -1,6 +1,7 @@
|
|||||||
<div class="title">GRZ-Metadaten</div>
|
<div class="title">GRZ-Metadaten</div>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
|
<b>Falldaten</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a th:href="@{/}">
|
<a th:href="@{/}">
|
||||||
@ -21,5 +22,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<b>Profile</b>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a th:href="@{/labdataprofiles}">
|
||||||
|
<span>Sequenzierprofile</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
126
src/main/resources/templates/labdataprofiles.html
Normal file
126
src/main/resources/templates/labdataprofiles.html
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de" xmlns="http://www.w3.org/1999/html" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
<link th:href="@{/main.css}" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<aside th:hx-get="@{/cases/menu}" hx-trigger="load"></aside>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div>
|
||||||
|
<div th:if="${labdataprofiles.isEmpty()}">
|
||||||
|
<h3>Probe</h3>
|
||||||
|
<form class="lab-data" th:hx-post="@{/labdataprofiles}">
|
||||||
|
<div>Keine Sequenzierprofile gefunden</div>
|
||||||
|
<button>Neues Sequenzierprofil hinzufügen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div th:each="profile : ${labdataprofiles}">
|
||||||
|
<h3>
|
||||||
|
Sequenzierprofil
|
||||||
|
<tt>"[[ ${ profile.profileName } ]]"</tt>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<form class="lab-data">
|
||||||
|
<input type="hidden" name="id" th:value="${profile.id}" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
Profilname
|
||||||
|
<input type="text" name="profileName" th:value="${profile.profileName}" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
Library Type
|
||||||
|
<select name="libraryType">
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'panel'}" value="PANEL">panel</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'panel_lr'}" value="PANEL_LR">panel_lr</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'wes'}" value="WES">wes</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'wes_lr'}" value="WES_LR">wes_lr</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'wgs'}" value="WGS">wgs</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'wgs_lr'}" value="WGS_LR">wgs_lr</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'wxs'}" value="WXS">wxs</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'wxs_lr'}" value="WXS_LR">wxs_lr</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'other'}" value="OTHER">other</option>
|
||||||
|
<option th:selected="${profile.libraryType != null and profile.libraryType.value == 'unknown'}" value="UNKNOWN">unknown</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
Preparation Kit - Name
|
||||||
|
<input type="text" name="libraryPrepKit" th:value="${profile.libraryPrepKit}" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
Hersteller
|
||||||
|
<input type="text" name="libraryPrepKitManufacturer" th:value="${profile.libraryPrepKitManufacturer}" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
Sequencer - Modell
|
||||||
|
<input type="text" name="sequencerModel" th:value="${profile.sequencerModel}" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
Hersteller
|
||||||
|
<input type="text" name="sequencerManufacturer" th:value="${profile.sequencerManufacturer}" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
Kit - Name/Version
|
||||||
|
<input type="text" name="kitName" th:value="${profile.kitName}" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
Hersteller
|
||||||
|
<input type="text" name="kitManufacturer" th:value="${profile.kitManufacturer}" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
Enrichment Kit - Name und Version
|
||||||
|
<input type="text" name="enrichmentKit" th:value="${profile.enrichmentKit}" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
Hersteller
|
||||||
|
<select name="enrichmentKitManufacturer">
|
||||||
|
<option th:selected="${profile.enrichmentKitManufacturer != null and profile.enrichmentKitManufacturer.value == 'Illumuna'}" value="ILLUMINA">Illumina</option>
|
||||||
|
<option th:selected="${profile.enrichmentKitManufacturer != null and profile.enrichmentKitManufacturer.value == 'Agilent'}" value="AGILENT">Agilent</option>
|
||||||
|
<option th:selected="${profile.enrichmentKitManufacturer != null and profile.enrichmentKitManufacturer.value == 'Twist'}" value="TIST">Twist</option>
|
||||||
|
<option th:selected="${profile.enrichmentKitManufacturer != null and profile.enrichmentKitManufacturer.value == 'NEB'}" value="NEB">NEB</option>
|
||||||
|
<option th:selected="${profile.enrichmentKitManufacturer != null and profile.enrichmentKitManufacturer.value == 'other'}" value="OTHER">other</option>
|
||||||
|
<option th:selected="${profile.enrichmentKitManufacturer != null and profile.enrichmentKitManufacturer.value == 'unknown'}" value="UNKNOWN">unknown</option>
|
||||||
|
<option th:selected="${profile.enrichmentKitManufacturer != null and profile.enrichmentKitManufacturer.value == 'none'}" value="NONE">none</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button class="save" th:hx-put="@{/labdataprofiles/{profileId}(profileId=${profile.id})}" hx-target="body">Änderungen übernehmen</button>
|
||||||
|
<button class="new" th:hx-post="@{/labdataprofiles}" hx-target="body">Neu</button>
|
||||||
|
<button class="delete" th:hx-delete="@{/labdataprofiles/{profileId}(profileId=${profile.id})}" hx-target="body">Löschen</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script th:src="@{/main.js}"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue
Block a user