mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2026-01-07 00:36:08 +08:00
Clean up stock management modal [SCI-10422]
This commit is contained in:
parent
8407361083
commit
763c741662
4 changed files with 66 additions and 58 deletions
|
|
@ -4,6 +4,10 @@
|
|||
@apply text-sm font-medium text-sn-dark-grey;
|
||||
}
|
||||
|
||||
.sci-label.error {
|
||||
@apply text-sn-coral;
|
||||
}
|
||||
|
||||
.sci-input-container-v2 {
|
||||
@apply relative h-[2.75rem] flex items-center;
|
||||
}
|
||||
|
|
@ -24,6 +28,18 @@
|
|||
@apply !border-sn-coral;
|
||||
}
|
||||
|
||||
.sci-input-container-v2.error::before {
|
||||
@apply !text-sn-coral;
|
||||
@apply !text-xs;
|
||||
|
||||
bottom: -1rem;
|
||||
content: attr(data-error-text);
|
||||
left: 0;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sci-input-container-v2 input:focus {
|
||||
@apply border-sn-science-blue shadow-none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<form class="flex flex-col gap-6" @submit.prevent novalidate>
|
||||
<fieldset class="w-full flex justify-between">
|
||||
<div class="flex flex-col w-40">
|
||||
<label class="text-sn-grey text-sm font-normal" for="operations">{{ i18n.t('repository_stock_values.manage_modal.operation') }}</label>
|
||||
<label class="sci-label" for="operations">{{ i18n.t('repository_stock_values.manage_modal.operation') }}</label>
|
||||
<Select
|
||||
:disabled="!stockValue?.id"
|
||||
:value="operation"
|
||||
|
|
@ -39,21 +39,18 @@
|
|||
@update="value => amount = value"
|
||||
name="stock_amount"
|
||||
id="stock-amount"
|
||||
:inputClass="`sci-input-container-v2 ${errors.amount ? 'error' : ''}`"
|
||||
:labelClass="`text-sm font-normal ${errors.amount ? 'text-sn-delete-red' : 'text-sn-grey'}`"
|
||||
type="number"
|
||||
:value="amount"
|
||||
:decimals="stockValue.decimals"
|
||||
:placeholder="i18n.t('repository_stock_values.manage_modal.amount_placeholder_new')"
|
||||
required
|
||||
:label="i18n.t('repository_stock_values.manage_modal.amount')"
|
||||
showLabel
|
||||
autoFocus
|
||||
:required="true"
|
||||
:min="0"
|
||||
:error="errors.amount"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col w-40">
|
||||
<label :class="`text-sm font-normal ${errors.unit ? 'text-sn-delete-red' : 'text-sn-grey'}`" for="stock-unit">
|
||||
<label class="sci-label" :class="{ 'error': !!errors.unit }" for="stock-unit">
|
||||
{{ i18n.t('repository_stock_values.manage_modal.unit') }}
|
||||
</label>
|
||||
<Select
|
||||
|
|
@ -93,24 +90,21 @@
|
|||
</div>
|
||||
<span class="ml-2">{{ i18n.t('repository_stock_values.manage_modal.create_reminder') }}</span>
|
||||
</div>
|
||||
<div v-if="reminderEnabled" class="stock-reminder-value flex gap-2 items-center">
|
||||
<div v-if="reminderEnabled" class="stock-reminder-value flex gap-2 items-center w-40">
|
||||
<Input
|
||||
@update="value => lowStockTreshold = value"
|
||||
name="treshold_amount"
|
||||
id="treshold-amount"
|
||||
fieldClass="flex gap-2"
|
||||
inputClass="sci-input-container-v2 w-40"
|
||||
labelClass="text-sm font-normal flex items-center"
|
||||
type="number"
|
||||
:value="lowStockTreshold"
|
||||
:decimals="stockValue.decimals"
|
||||
:placeholder="i18n.t('repository_stock_values.manage_modal.amount_placeholder_new')"
|
||||
required
|
||||
:required="true"
|
||||
:label="i18n.t('repository_stock_values.manage_modal.reminder_at')"
|
||||
showLabel
|
||||
:min="0"
|
||||
:error="errors.tresholdAmount"
|
||||
/>
|
||||
<span class="text-sm font-normal">
|
||||
<span class="text-sm font-normal mt-5">
|
||||
{{ unitLabel }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -155,7 +149,7 @@ export default {
|
|||
operation: null,
|
||||
operations: [],
|
||||
stockValue: null,
|
||||
amount: '',
|
||||
amount: null,
|
||||
repositoryRowName: null,
|
||||
stockUrl: null,
|
||||
units: null,
|
||||
|
|
@ -177,7 +171,7 @@ export default {
|
|||
return unit ? unit[1] : '';
|
||||
},
|
||||
newAmount() {
|
||||
const currentAmount = new Decimal(this.stockValue?.amount || 0);
|
||||
const currentAmount = this.stockValue?.amount ? new Decimal(this.stockValue?.amount || 0) : null;
|
||||
const amount = new Decimal(this.amount || 0);
|
||||
let value;
|
||||
switch (this.operation) {
|
||||
|
|
@ -227,7 +221,7 @@ export default {
|
|||
success: (result) => {
|
||||
this.repositoryRowName = result.repository_row_name;
|
||||
this.stockValue = result.stock_value;
|
||||
this.amount = Number(new Decimal(result.stock_value.amount || 0));
|
||||
this.amount = this.stockValue?.amount && Number(new Decimal(this.stockValue.amount));
|
||||
this.units = result.stock_value.units;
|
||||
this.unit = result.stock_value.unit;
|
||||
this.reminderEnabled = result.stock_value.reminder_enabled;
|
||||
|
|
|
|||
|
|
@ -1,75 +1,69 @@
|
|||
<template>
|
||||
<div class="relative" :class="fieldClass">
|
||||
<label v-if="showLabel" :class="labelClass" :for="id">{{ label }}</label>
|
||||
<div :class="inputClass">
|
||||
<div class="relative w-full">
|
||||
<label v-if="label" class="sci-label" :class="{ 'error': !!inputError }" :for="id">{{ label }}</label>
|
||||
<div class="sci-input-container-v2" :class="{ 'error': !!inputError }" :data-error-text="inputError">
|
||||
<input ref="input"
|
||||
:type="type"
|
||||
:id="id"
|
||||
:name="name"
|
||||
:value="inputValue"
|
||||
:class="`${error ? 'error' : ''}`"
|
||||
:value="value"
|
||||
:class="{ 'error': !!inputError }"
|
||||
:placeholder="placeholder"
|
||||
:required="required"
|
||||
inputmode="numeric"
|
||||
:min="min"
|
||||
:max="max"
|
||||
:step="1/Math.pow(10, decimals)"
|
||||
@input="updateValue"
|
||||
/>
|
||||
<div
|
||||
class="mt-2 text-sn-delete-red whitespace-nowrap truncate text-xs font-normal absolute bottom-[-1rem] w-full"
|
||||
:title="error"
|
||||
:class="{ visible: error, invisible: !error}"
|
||||
>
|
||||
{{ error }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Input',
|
||||
props: {
|
||||
id: { type: String, required: false },
|
||||
fieldClass: { type: String, default: '' },
|
||||
inputClass: { type: String, default: '' },
|
||||
labelClass: { type: String, default: '' },
|
||||
type: { type: String, default: 'text' },
|
||||
name: { type: String, required: true },
|
||||
value: { type: [String, Number], required: false },
|
||||
decimals: { type: [Number, String], default: 0 },
|
||||
placeholder: { type: String, default: '' },
|
||||
required: { type: Boolean, default: false },
|
||||
showLabel: { type: Boolean, default: false },
|
||||
label: { type: String, required: false },
|
||||
autoFocus: { type: Boolean, default: false },
|
||||
error: { type: String, required: false }
|
||||
error: { type: String, required: false },
|
||||
min: { type: String },
|
||||
max: { type: String },
|
||||
blockInvalidInput: { type: Boolean, default: true }
|
||||
},
|
||||
computed: {
|
||||
inputValue() {
|
||||
if (this.type === 'text') return this.value;
|
||||
|
||||
return isNaN(this.value) ? '' : this.value;
|
||||
data() {
|
||||
return {
|
||||
inputError: false,
|
||||
lastValue: this.value
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value() {
|
||||
this.lastValue = this.value;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateValue($event) {
|
||||
switch (this.type) {
|
||||
case 'text':
|
||||
this.$emit('update', $event.target.value);
|
||||
break;
|
||||
case 'number':
|
||||
const newValue = this.formatDecimalValue($event.target.value);
|
||||
this.$refs.input.value = newValue;
|
||||
if (!isNaN(newValue)) this.$emit('update', newValue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.checkInputError($event);
|
||||
this.$emit('update', $event.target.value);
|
||||
},
|
||||
formatDecimalValue(value) {
|
||||
const decimalValue = value.replace(/[^-0-9.]/g, '');
|
||||
if (this.decimals === '0') {
|
||||
return decimalValue.split('.')[0];
|
||||
checkInputError() {
|
||||
const isValid = this.$refs.input.checkValidity();
|
||||
|
||||
if (isValid) {
|
||||
this.lastValue = this.$refs.input.value;
|
||||
} else if (this.blockInvalidInput) {
|
||||
this.$refs.input.value = this.lastValue;
|
||||
return;
|
||||
}
|
||||
return decimalValue.match(new RegExp(`^-?\\d*(\\.\\d{0,${this.decimals}})?`))[0];
|
||||
|
||||
this.inputError = this.error || (!isValid && this.i18n.t('input.errors.invalid_value'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4008,6 +4008,10 @@ en:
|
|||
From: 'From'
|
||||
To: 'To'
|
||||
|
||||
input:
|
||||
errors:
|
||||
invalid_value: 'Invalid value'
|
||||
|
||||
marvinjs:
|
||||
new_sketch: "New chemical drawing"
|
||||
new_button: "New chemical drawing"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue