Skip to content

Commit

Permalink
Add a new way of handling hazard information inside starting_material…
Browse files Browse the repository at this point in the history
… editpage

Fix update GHS Codes in db

Fix component if no selected codes

Fix css for GHS pictogram

Temp commit

New version for selecting GHS Hazard pictogram
  • Loading branch information
BenjaminCharmes committed Oct 10, 2024
1 parent ec5d977 commit 3fa7500
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 1 deletion.
67 changes: 67 additions & 0 deletions webapp/src/components/AddHazardInformationModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template>
<form class="modal-enclosure" data-testid="add-h-codes-form" @submit.prevent="submitForm">
<Modal :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)">
<template #header> Add Hazard information </template>
<template #body>
<div class="form-row">
<div class="form-group col-md-8">
<label for="items-selected" class="col-form-label">Item:</label>
<div id="items-selected" class="dynamic-input">
<FormattedItemName :item_id="item_id" :item-type="type" enable-click />
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-12 form-group">
<label id="addToCollectionLabel">Hazard information:</label>
<input
id="h-codes-input"
v-model="hazardInformation"
type="text"
class="form-control"
placeholder="Enter hazard information (H codes included)"
/>
</div>
</div>
</template>
</Modal>
</form>
</template>

<script>
import Modal from "@/components/Modal.vue";
import FormattedItemName from "@/components/FormattedItemName";
export default {
name: "AddHazardInformationModal",
components: {
Modal,
FormattedItemName,
},
props: {
modelValue: Boolean,
ghs: { type: String, default: "" },
item_id: { type: String, required: true },
type: { type: String, required: true },
},
emits: ["update:modelValue", "submitHazardInformation"],
data() {
return {
hazardInformation: this.ghs || "",
};
},
watch: {
ghs(newVal) {
this.hazardInformation = newVal;
},
},
methods: {
async submitForm() {
this.$emit("submitHazardInformation", this.hazardInformation);
this.$emit("update:modelValue", false);
},
},
};
</script>

<style scoped></style>
101 changes: 101 additions & 0 deletions webapp/src/components/GHSHazardInformation.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<template>
<div class="ghs-display form-control">
<div v-for="pictogram in selectedPictograms" :key="pictogram.label" class="ghs-chip">
<img :alt="pictogram.label" :src="pictogram.pictogram" class="ghs-icon" />
<span>{{ pictogram.label }}</span>
</div>
<font-awesome-icon
class="plus-icon"
:icon="['fa', 'plus']"
@click="AddHazardInformationModalIsOpen = true"
/>
</div>
<AddHazardInformationModal
v-model="AddHazardInformationModalIsOpen"
:ghs="modelValue"
:item_id="item_id"
:type="type"
@submit-hazard-information="updateGHS"
/>
</template>

<script>
import { getPictogramsFromHazardInformation } from "@/resources.js";
import AddHazardInformationModal from "@/components/AddHazardInformationModal.vue";
export default {
components: {
AddHazardInformationModal,
},
props: {
modelValue: { type: String, required: true },
item_id: { type: String, required: true },
type: { type: String, required: true },
},
emits: ["update:modelValue"],
data() {
return {
AddHazardInformationModalIsOpen: false,
selectedPictograms: [],
};
},
watch: {
modelValue(newVal) {
this.updateSelectedPictograms(newVal);
},
},
mounted() {
this.updateSelectedPictograms(this.modelValue);
},
methods: {
updateSelectedPictograms() {
if (!this.modelValue) {
this.selectedPictograms = [];
return;
}
this.selectedPictograms = getPictogramsFromHazardInformation(this.modelValue);
},
updateGHS(newGHS) {
this.$emit("update:modelValue", newGHS);
this.updateSelectedPictograms(newGHS);
},
},
};
</script>

<style scoped>
.ghs-display {
display: flex;
flex-direction: column;
position: relative;
min-height: calc(1.5em + 0.75rem + 2px);
height: auto;
gap: 0.3rem;
}
.ghs-content {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.ghs-chip {
display: flex;
align-items: center;
}
.ghs-icon {
width: 1.6rem;
height: 1.6rem;
margin-right: 8px;
}
.plus-icon {
position: absolute;
color: black;
top: 0.6rem;
right: 0.6rem;
}
</style>
83 changes: 83 additions & 0 deletions webapp/src/components/MultiselectHazardPictogram.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<template>
<div>
<MultiSelect
v-model="selectedGhsCodes"
:options="ghsOptions"
class="form-control"
option-label="label"
option-value="value"
placeholder="Select GHS codes"
display="chip"
:include-select-all-option="false"
>
<template #option="slotProps">
<div class="ghs-option">
<img :alt="slotProps.option.label" :src="slotProps.option.pictogram" class="ghs-icon" />
<div>{{ slotProps.option.value + ": " + slotProps.option.label }}</div>
</div>
</template>

<template #chip="chipProps">
<div class="chip-content">
<img :alt="chipProps.value" :src="getPictogram(chipProps.value)" class="ghs-icon" />
</div>
</template>
</MultiSelect>
</div>
</template>

<script>
import MultiSelect from "primevue/multiselect";
import { HazardPictograms } from "@/resources.js";
export default {
components: {
MultiSelect,
},
props: {
modelValue: { type: String, required: true },
},
emits: ["update:modelValue"],
data() {
return {
selectedGhsCodes: this.modelValue ? this.modelValue.split(",") : [],
ghsOptions: Object.entries(HazardPictograms).map(([code, { label, pictogram }]) => ({
value: code,
label,
pictogram,
})),
};
},
watch: {
modelValue(newVal) {
this.selectedGhsCodes = newVal.split(",");
},
selectedGhsCodes(newVal) {
this.$emit("update:modelValue", newVal.join(","));
},
},
methods: {
getPictogram(value) {
const option = this.ghsOptions.find((opt) => opt.value === value);
return option ? option.pictogram : "";
},
},
};
</script>

<style scoped>
.ghs-option {
display: flex;
align-items: center;
}
.ghs-icon {
width: 1.6rem;
height: 1.6rem;
margin-right: 8px;
}
:deep(.p-multiselect-label) {
padding: 0 !important;
}
</style>
5 changes: 4 additions & 1 deletion webapp/src/components/StartingMaterialInformation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
</div>
<div class="form-group col-lg-3 col-sm-4">
<label for="startmat-hazards">GHS Hazard Codes</label>
<StyledInput id="startmat-hazards" v-model="GHS" :readonly="!isEditable" />
<!-- <StyledInput id="startmat-hazards" v-model="GHS" :readonly="!isEditable" /> -->
<GHSHazardInformation v-model="GHS" :item_id="item.item_id" :type="item.type" />
</div>
<div class="col-lg-3 col-sm-4">
<ToggleableCollectionFormGroup v-model="Collections" />
Expand All @@ -91,6 +92,7 @@ import TableOfContents from "@/components/TableOfContents";
import ToggleableCollectionFormGroup from "@/components/ToggleableCollectionFormGroup";
import FormattedRefcode from "@/components/FormattedRefcode";
import StyledInput from "@/components/StyledInput";
import GHSHazardInformation from "@/components/GHSHazardInformation";
import { EDITABLE_INVENTORY } from "@/resources.js";
Expand All @@ -103,6 +105,7 @@ export default {
ToggleableCollectionFormGroup,
TableOfContents,
FormattedRefcode,
GHSHazardInformation,
},
props: {
item_id: { type: String, required: true },
Expand Down
2 changes: 2 additions & 0 deletions webapp/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
faEllipsisH,
faCopy,
faInfoCircle,
faPlus,
} from "@fortawesome/free-solid-svg-icons";
import { faPlusSquare } from "@fortawesome/free-regular-svg-icons";
import { faGithub, faOrcid } from "@fortawesome/free-brands-svg-icons";
Expand Down Expand Up @@ -81,6 +82,7 @@ library.add(
faListOl,
faSearch,
faPlusSquare,
faPlus,
faSpinner,
faEllipsisH,
faCopy,
Expand Down
Loading

0 comments on commit 3fa7500

Please sign in to comment.