Skip to content

Commit

Permalink
- ADD: Added initial support for adding people to a trial. Currently …
Browse files Browse the repository at this point in the history
…there is no consequence to this.

- ADD: Added two more stats to statistics page: date range and active days.
  • Loading branch information
sebastian-raubach committed Apr 24, 2024
1 parent 35525d3 commit 986bdde
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/components/TrialCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<b-dropdown-divider v-if="trial.editable" />
<b-dropdown-item @click="$emit('showTrialEdit')" v-if="trial.editable && (trial.shareStatus === TRIAL_STATE_NOT_SHARED || trial.shareStatus === TRIAL_STATE_OWNER)"><BIconPencilSquare /> {{ $t('buttonEditTrial') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('addTrait')" v-if="trial.editable"><BIconTags /> {{ $t('buttonAddTrait') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('addPerson')" v-if="trial.editable"><BIconPersonPlus /> {{ $t('buttonAddPerson') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('addGermplasm')" v-if="trial.editable && trial.layout.columns === 1"><BIconNodePlus :rotate="90" /> {{ $t('buttonAddGermplasm') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('importData')" v-if="trial.editable"><BIconFileEarmarkArrowUp /> {{ $t('buttonUploadData') }}</b-dropdown-item>
<b-dropdown-divider />
Expand All @@ -44,12 +45,13 @@
<script>
import TrialInformation from '@/components/TrialInformation'
import { mapGetters } from 'vuex'
import { BIconCloudUploadFill, BIconCloudDownloadFill, BIconCalendar, BIconExclamationTriangleFill, BIconJournalArrowUp, BIconGear, BIconstack, BIconCloud, BIconArrowDownUp, BIconJournals, BIconPencilSquare, BIconTags, BIconNodePlus, BIconFileEarmarkArrowUp, BIconTrash } from 'bootstrap-vue'
import { BIconCloudUploadFill, BIconCloudDownloadFill, BIconPersonPlus, BIconCalendar, BIconExclamationTriangleFill, BIconJournalArrowUp, BIconGear, BIconstack, BIconCloud, BIconArrowDownUp, BIconJournals, BIconPencilSquare, BIconTags, BIconNodePlus, BIconFileEarmarkArrowUp, BIconTrash } from 'bootstrap-vue'
import { TRIAL_STATE_NOT_SHARED, TRIAL_STATE_OWNER } from '@/plugins/constants'
export default {
components: {
TrialInformation,
BIconPersonPlus,
BIconCloudUploadFill,
BIconCloudDownloadFill,
BIconCalendar,
Expand Down
4 changes: 3 additions & 1 deletion src/components/TrialListGroupItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<b-dropdown-divider v-if="trial.editable" />
<b-dropdown-item @click="$emit('showTrialEdit')" v-if="trial.editable && (trial.shareStatus === TRIAL_STATE_NOT_SHARED || trial.shareStatus === TRIAL_STATE_OWNER)"><BIconPencilSquare /> {{ $t('buttonEditTrial') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('addTrait')" v-if="trial.editable"><BIconTags /> {{ $t('buttonAddTrait') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('addPerson')" v-if="trial.editable"><BIconPersonPlus /> {{ $t('buttonAddPerson') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('addGermplasm')" v-if="trial.editable && trial.layout.columns === 1"><BIconNodePlus :rotate="90" /> {{ $t('buttonAddGermplasm') }}</b-dropdown-item>
<b-dropdown-item @click="$emit('importData')" v-if="trial.editable"><BIconFileEarmarkArrowUp /> {{ $t('buttonUploadData') }}</b-dropdown-item>
<b-dropdown-divider />
Expand All @@ -70,7 +71,7 @@

<script>
import { mapGetters } from 'vuex'
import { BIconCalendarDate, BIconJournalArrowUp, BIconGear, BIconCloud, BIconExclamationTriangleFill, BIconCloudUploadFill, BIconCloudDownloadFill, BIconArrowDownUp, BIconstack, BIconJournals, BIconPencilSquare, BIconTags, BIconNodePlus, BIconFileEarmarkArrowUp, BIconTrash, BIconCollection, BIconLayoutThreeColumns, BIconCalendarRange, BIconChatLeftText } from 'bootstrap-vue'
import { BIconCalendarDate, BIconJournalArrowUp, BIconGear, BIconCloud, BIconPersonPlus, BIconExclamationTriangleFill, BIconCloudUploadFill, BIconCloudDownloadFill, BIconArrowDownUp, BIconstack, BIconJournals, BIconPencilSquare, BIconTags, BIconNodePlus, BIconFileEarmarkArrowUp, BIconTrash, BIconCollection, BIconLayoutThreeColumns, BIconCalendarRange, BIconChatLeftText } from 'bootstrap-vue'
import { TRIAL_STATE_NOT_SHARED, TRIAL_STATE_OWNER } from '@/plugins/constants'
import TrialTraitTimeframeModal from '@/components/modals/TrialTraitTimeframeModal'
import TrialShareTypeIcon from '@/components/icons/TrialShareTypeIcon'
Expand All @@ -87,6 +88,7 @@ export default {
BIconGear,
BIconCloud,
BIconExclamationTriangleFill,
BIconPersonPlus,
BIconArrowDownUp,
BIconstack,
BIconJournals,
Expand Down
10 changes: 10 additions & 0 deletions src/components/TrialSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
@synchronize="synchronize(trial)"
@duplicateTrial="duplicateTrial(trial)"
@addTrait="addTrait(trial)"
@addPerson="addPerson(trial)"
@showTrialEdit="showTrialEdit(trial)"
@addGermplasm="addGermplasm(trial)"
@importData="importData(trial)"
Expand All @@ -73,6 +74,7 @@
@synchronize="synchronize(trial)"
@duplicateTrial="duplicateTrial(trial)"
@addTrait="addTrait(trial)"
@addPerson="addPerson(trial)"
@showTrialEdit="showTrialEdit(trial)"
@addGermplasm="addGermplasm(trial)"
@importData="importData(trial)"
Expand All @@ -93,6 +95,7 @@
<TrialCommentModal :trialId="selectedTrial.localId" @hidden="showTrialComments(null)" ref="trialCommentModal" v-if="selectedTrial" />
<TrialShareCodeModal :trial="selectedTrial" ref="trialShareCodeModal" v-if="selectedTrial" />
<AddTraitsModal :trial="selectedTrial" ref="addTraitsModal" v-if="selectedTrial && selectedTrial.editable" />
<EditPeopleModal :trialId="selectedTrial.localId" ref="addPersonModal" v-if="selectedTrial && selectedTrial.editable" />
<AddGermplasmModal :trialId="selectedTrial.localId" ref="addGermplasmModal" v-if="selectedTrial && selectedTrial.editable && selectedTrial.layout.columns === 1" />
<TrialSynchronizationModal :trial="selectedTrial" ref="traitSyncModal" v-if="selectedTrial && (selectedTrial.transactionCount > 0 || selectedTrial.hasRemoteUpdate)" />
<TrialDataImportModal :trial="selectedTrial" ref="trialDataImportModal" v-if="selectedTrial" />
Expand All @@ -107,6 +110,7 @@ import TrialListGroupItem from '@/components/TrialListGroupItem'
import TrialCommentModal from '@/components/modals/TrialCommentModal'
import TrialShareCodeModal from '@/components/modals/TrialShareCodeModal'
import AddTraitsModal from '@/components/modals/AddTraitsModal'
import EditPeopleModal from '@/components/modals/EditPeopleModal'
import TrialModificationModal from '@/components/modals/TrialModificationModal'
import TrialExpirationModal from '@/components/modals/TrialExpirationModal'
import TrialDataImportModal from '@/components/modals/TrialDataImportModal'
Expand Down Expand Up @@ -134,6 +138,7 @@ export default {
AddGermplasmModal,
TrialModificationModal,
TrialExpirationModal,
EditPeopleModal,
BIconSortDown,
BIconSortDownAlt,
BIconListTask,
Expand Down Expand Up @@ -335,6 +340,11 @@ export default {
this.$store.commit('ON_SELECTED_TRIAL_CHANGED', trial.localId)
this.$router.push({ name: 'data-entry' })
},
addPerson: function (trial) {
this.selectedTrial = trial
this.$nextTick(() => this.$refs.addPersonModal.show())
},
addTrait: function (trial) {
this.selectedTrial = trial
Expand Down
188 changes: 188 additions & 0 deletions src/components/modals/EditPeopleModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<template>
<b-modal :title="$t('modalTitleEditPeople')"
:ok-title="$t('buttonAdd')"
:cancel-title="$t('buttonCancel')"
no-fade
size="lg"
@ok.prevent="onSubmit"
@shown="$refs.name.focus()"
ref="editPeopleModal">
<p>{{ $t('modalTextEditPeople') }}</p>
<b-form @submit.prevent="onSubmit">
<!-- Person name -->
<b-form-group :label="$t('formLabelPersonName')" label-for="person-name" :description="$t('formDescriptionPersonName')">
<b-form-input id="person-name" v-model="name" required :state="state.name" ref="name" />
</b-form-group>
<!-- Person email -->
<b-form-group :label="$t('formLabelPersonEmail')" label-for="person-email" :description="$t('formDescriptionPersonEmail')">
<b-form-input id="person-email" type="email" v-model="email" :state="state.email" ref="email" />
</b-form-group>
<!-- Person role -->
<b-form-group :label="$t('formLabelPersonRole')" label-for="person-role" :description="$t('formDescriptionPersonRole')">
<b-row>
<b-col :cols=12 :md=3>
<b-button :variant="isCorrespondingAuthor ? 'dark' : 'outline-dark'" @click="toggle(PERSON_TYPE_CORRESPONDING_AUTHOR)" class="w-100 person-type-button d-flex flex-column align-items-center">
<h2 :style="{ color: storeTraitColors[0] }"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi b-icon bi-person-fill-exclamation" viewBox="0 0 16 16">
<path d="M11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0m-9 8c0 1 1 1 1 1h5.256A4.5 4.5 0 0 1 8 12.5a4.5 4.5 0 0 1 1.544-3.393Q8.844 9.002 8 9c-5 0-6 3-6 4"/>
<path d="M16 12.5a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0m-3.5-2a.5.5 0 0 0-.5.5v1.5a.5.5 0 0 0 1 0V11a.5.5 0 0 0-.5-.5m0 4a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1"/>
</svg></h2> <span>{{ $t('personTypeCorrespondingAuthor') }}</span>
</b-button>
</b-col>
<b-col :cols=12 :md=3>
<b-button :variant="isDataCollector ? 'dark' : 'outline-dark'" @click="toggle(PERSON_TYPE_DATA_COLLECTOR)" class="w-100 person-type-button d-flex flex-column align-items-center">
<h2 :style="{ color: storeTraitColors[1] }"><BIconPersonLinesFill /></h2> <span>{{ $t('personTypeDataCollector') }}</span>
</b-button>
</b-col>
<b-col :cols=12 :md=3>
<b-button :variant="isQualityChecker ? 'dark' : 'outline-dark'" @click="toggle(PERSON_TYPE_QUALITY_CHECKER)" class="w-100 person-type-button d-flex flex-column align-items-center">
<h2 :style="{ color: storeTraitColors[2] }"><BIconPersonCheckFill /></h2> <span>{{ $t('personTypeQualityChecker') }}</span>
</b-button>
</b-col>
<b-col :cols=12 :md=3>
<b-button :variant="isSubmitter ? 'dark' : 'outline-dark'" @click="toggle(PERSON_TYPE_DATA_SUBMITTER)" class="w-100 person-type-button d-flex flex-column align-items-center">
<h2 :style="{ color: storeTraitColors[3] }"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi b-icon bi-person-fill-up" viewBox="0 0 16 16">
<path d="M12.5 16a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7m.354-5.854 1.5 1.5a.5.5 0 0 1-.708.708L13 11.707V14.5a.5.5 0 0 1-1 0v-2.793l-.646.647a.5.5 0 0 1-.708-.708l1.5-1.5a.5.5 0 0 1 .708 0M11 5a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/>
<path d="M2 13c0 1 1 1 1 1h5.256A4.5 4.5 0 0 1 8 12.5a4.5 4.5 0 0 1 1.544-3.393Q8.844 9.002 8 9c-5 0-6 3-6 4"/>
</svg></h2> <span>{{ $t('personTypeDataSubmitter') }}</span>
</b-button>
</b-col>
</b-row>
</b-form-group>
</b-form>

<p class="text-danger my-3" v-if="error">{{ $t(error) }}</p>
</b-modal>
</template>

<script>
import { PERSON_TYPE_CORRESPONDING_AUTHOR, PERSON_TYPE_DATA_COLLECTOR, PERSON_TYPE_QUALITY_CHECKER, PERSON_TYPE_DATA_SUBMITTER } from '@/plugins/constants'
import { BIconPersonLinesFill, BIconPersonCheckFill } from 'bootstrap-vue'
import { getId } from '@/plugins/id'
import { mapGetters } from 'vuex'
import { addTrialPeople } from '@/plugins/idb'
export default {
components: {
BIconPersonLinesFill,
BIconPersonCheckFill
},
props: {
trialId: {
type: String,
default: null
}
},
data: function () {
return {
name: null,
email: null,
types: [PERSON_TYPE_DATA_COLLECTOR],
state: {
name: null
},
error: null,
PERSON_TYPE_CORRESPONDING_AUTHOR,
PERSON_TYPE_DATA_COLLECTOR,
PERSON_TYPE_QUALITY_CHECKER,
PERSON_TYPE_DATA_SUBMITTER
}
},
computed: {
...mapGetters([
'storeTraitColors'
]),
isCorrespondingAuthor: function () {
return this.types.includes(PERSON_TYPE_CORRESPONDING_AUTHOR)
},
isDataCollector: function () {
return this.types.includes(PERSON_TYPE_DATA_COLLECTOR)
},
isQualityChecker: function () {
return this.types.includes(PERSON_TYPE_QUALITY_CHECKER)
},
isSubmitter: function () {
return this.types.includes(PERSON_TYPE_DATA_SUBMITTER)
},
personTypeOptions: function () {
return [{
value: PERSON_TYPE_CORRESPONDING_AUTHOR,
text: this.$t('personTypeCorrespondingAuthor')
}, {
value: PERSON_TYPE_DATA_COLLECTOR,
text: this.$t('personTypeDataCollector')
}, {
value: PERSON_TYPE_QUALITY_CHECKER,
text: this.$t('personTypeQualityChecker')
}, {
value: PERSON_TYPE_DATA_SUBMITTER,
text: this.$t('personTypeDataSubmitter')
}]
}
},
watch: {
types: function () {
if (this.$refs.name) {
this.$refs.name.focus()
}
}
},
methods: {
toggle: function (toggleType) {
const s = new Set()
this.types.forEach(t => s.add(t))
if (s.has(toggleType)) {
s.delete(toggleType)
} else {
s.add(toggleType)
}
this.types = [...s]
},
/**
* Shows and resets modal dialog
*/
show: function () {
this.name = null
this.email = null
this.error = null
this.types = [PERSON_TYPE_DATA_COLLECTOR]
this.state = {
name: null
}
this.$nextTick(() => this.$refs.editPeopleModal.show())
},
/**
* Hides the modal dialog
*/
hide: function () {
this.$nextTick(() => this.$refs.editPeopleModal.hide())
},
onSubmit: function () {
if (!this.name) {
this.state.name = false
return
}
if (this.types.length < 1) {
this.error = 'errorMessagePersonTypeMissing'
return
}
if (this.trialId) {
addTrialPeople(this.trialId, [{ id: getId(), name: this.name, email: this.email, types: this.types }])
.then(() => this.hide())
} else {
this.$emit('person-added', { id: getId(), name: this.name, email: this.email, types: this.types })
this.hide()
}
}
}
}
</script>

<style scoped>
.person-type-button {
overflow-wrap: anywhere;
}
</style>
11 changes: 10 additions & 1 deletion src/plugins/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ const TRIAL_EVENT_TYPE_MANAGEMENT = 'MANAGEMENT'
const TRIAL_EVENT_TYPE_WEATHER = 'WEATHER'
const TRIAL_EVENT_TYPE_OTHER = 'OTHER'

const PERSON_TYPE_DATA_COLLECTOR = 'DATA_COLLECTOR'
const PERSON_TYPE_DATA_SUBMITTER = 'DATA_SUBMITTER'
const PERSON_TYPE_CORRESPONDING_AUTHOR = 'CORRESPONDING_AUTHOR'
const PERSON_TYPE_QUALITY_CHECKER = 'QUALITY_CHECKER'

const CELL_CATEGORY_CONTROL = 'control'

const CELL_CATEGORIES = {}
Expand Down Expand Up @@ -74,5 +79,9 @@ export {
TRIAL_EVENT_TYPE_WEATHER,
TRIAL_EVENT_TYPE_OTHER,
CELL_CATEGORY_CONTROL,
CELL_CATEGORIES
CELL_CATEGORIES,
PERSON_TYPE_DATA_COLLECTOR,
PERSON_TYPE_DATA_SUBMITTER,
PERSON_TYPE_CORRESPONDING_AUTHOR,
PERSON_TYPE_QUALITY_CHECKER
}
20 changes: 19 additions & 1 deletion src/plugins/i18n/de_DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"buttonStartGuidedWalk": "Gelenkter Ablauf",
"buttonStart": "Starten",
"buttonAddTrait": "Merkmal hinzufügen",
"buttonAddPerson": "Person hinzufügen",
"buttonAddTraits": "Merkmal hinzufügen|Merkmal hinzufügen|Merkmale hinzufügen",
"buttonSynchronize": "Synchronisieren",
"buttonNext": "Weiter",
Expand Down Expand Up @@ -105,6 +106,7 @@
"errorMessageDataImportInvalidSetSize": "Die folgenden Satz-Werte in Zeile {row} sind ungültig. Die Merkmal-Satzgröße ist {setSize}, es wurden aber {provided} Werte angegeben: {value}",
"errorMessageBrapiPermissionUnauthorized": "Der BrAPI-Endpunkt benötigt ein Token für diese Operation. Bitte das Token eingeben welches vom Endpunkt zur Verfügung gestellt wurde.",
"errorMessageBrapiPermissionForbidden": "Die angeforderte Operation ist mit dem angegebenen Token nicht erlaubt. Bitte mit dem Instandhalter des Endpunkts in Verbindung setzen.",
"errorMessagePersonTypeMissing": "Bitte mindestens eine Personenrolle auswählen.",
"formLabelSettingsLocale": "Sprache",
"formDescriptionSettingsLocale": "Die Sprache der Benutzeroberfläche",
"formLabelSettingsDarkMode": "Dark mode",
Expand Down Expand Up @@ -312,6 +314,14 @@
"formDescriptionEventImpact": "Beurteile die Auswirkung des Ereignisses auf den Versuch von niedrig (1) zu hoch (5).",
"formLabelEventDate": "Ereignisdatum",
"formDescriptionEventDate": "Wähle das Datum aus an dem das Eregnis stattfand. Dies ist standardmäßig Heute.",
"formLabelPersonName": "Name",
"formDescriptionPersonName": "Name der diese Person identifiziert.",
"formLabelPersonEmail": "E-Mail",
"formDescriptionPersonEmail": "Kontakt E-Mail-Adresse für diese Person.",
"formLabelPersonRole": "Rolle",
"formDescriptionPersonRole": "Eine Rolle die die Hauptfunktion dieser Person angibt. Es ist zu beachten, dass diese Rolle keinerlei Einfluss auf die Funktionsweise von GridScore hat.",
"formLabelTrialSetupTrialPeople": "Involvierte Personen",
"formDescriptionTrialSetupTrialPeople": "Optional können Personen definiert werden die am Versuch beteiligt sind.",
"menuHome": "Home",
"menuDataEntry": "Dateneingabe",
"menuDataExport": "Exportieren",
Expand Down Expand Up @@ -429,6 +439,8 @@
"modalTextImageTaggingIOSWarning": "Auf iOS, nach Klicken auf 'Speichern', bitte sicherstellen, dass das Bild komplett heruntergeladen wird durch Klicken auf 'Öffnen in...' bevor mit 'Fertig' abgeschlossen wird.",
"modalTitleVizPlotDataDetails": "Beetdatendetails",
"modalTextTrialImportNoValidQRCode": "<code>{code}</code> ist kein gültiger GridScore QR-Code. Bitte erneut versuchen.",
"modalTitleEditPeople": "Personen bearbeiten",
"modalTextEditPeople": "Nutze das Formular unten um neue Personen zum Versuch hinzuzufügen. Falls definiert müssen sich Nutzer durch Auswahl einer der definierten Person identifizieren bevor Daten aufgezeichnet werden können. Es ist zu beachten, dass die zugewiesenen Rollen keinerlei Einfluss auf die Funktionsweise von GridScore haben, sondern werden ausschließlich zum Ausfüllen der Export-Vorlagen genutzt.",
"pageAboutChangelog": "Changelog-Information anzeigen",
"pageAboutVersion": "Version {version}",
"pageAboutDocumentationLink": "Eine detaillierte Anleitung für GridScore und wie man es benutzt ist auf der <a href='https://cropgeeks.github.io/gridscore-next-client'>Dokumentationsseite<a/> verfügbar.",
Expand Down Expand Up @@ -801,6 +813,8 @@
"widgetTrialDataStatsMeasurements": "{count} Messungen aufgezeichnet",
"widgetTrialDataStatsArea": "{area} {unit} abgedeckt",
"widgetTrialDataStatsAreaUnknown": "Unbekannte Fläche",
"widgetTrialDataStatsDayRange": "{count} Tage Versuchslänge",
"widgetTrialDataStatsActiveDays": "{count} aktive Tage",
"areaUnitMeter": "Quadratmeter",
"areaUnitKilometer": "Quadratkilometer",
"areaUnitHectare": "Hektar",
Expand All @@ -813,5 +827,9 @@
"formLabelDataStatsTrial": "Versuch auswählen",
"formLabelDataStatsAreaUnit": "Flächeneinheit auswählen",
"widgetChartHeatmapAxisTitleMonth": "Monat",
"widgetChartHeatmapAxisTitleDay": "Tag"
"widgetChartHeatmapAxisTitleDay": "Tag",
"personTypeCorrespondingAuthor": "Korrespondenzautor",
"personTypeDataCollector": "Datensammler",
"personTypeQualityChecker": "Qualitätsprüfer",
"personTypeDataSubmitter": "Datenübermittler"
}
Loading

0 comments on commit 986bdde

Please sign in to comment.