diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue index 5e7c89326..976469476 100644 --- a/src/pages/Worker/Card/WorkerPda.vue +++ b/src/pages/Worker/Card/WorkerPda.vue @@ -1,140 +1,212 @@ <script setup> import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; -import { onMounted, ref, computed } from 'vue'; -import FetchData from 'components/FetchData.vue'; -import FormModel from 'components/FormModel.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import useNotify from 'src/composables/useNotify.js'; -import axios from 'axios'; -import { useRole } from 'src/composables/useRole'; +import { ref, computed } from 'vue'; + +import axios from 'axios'; +import useNotify from 'src/composables/useNotify.js'; +import FetchData from 'components/FetchData.vue'; +import FormModelPopup from 'src/components/FormModelPopup.vue'; +import { useVnConfirm } from 'composables/useVnConfirm'; + +import VnPaginate from 'src/components/ui/VnPaginate.vue'; +import VnRow from 'components/ui/VnRow.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import VnInput from 'src/components/common/VnInput.vue'; -const route = useRoute(); const { t } = useI18n(); const { notify } = useNotify(); -const { hasAny } = useRole(); -const fetchCurrentDeviceRef = ref(null); -const deviceProductionsFilter = { - fields: ['id', 'serialNumber', 'modelFk'], - where: { stateFk: 'idle' }, - order: 'id', -}; -const deviceProductionsOptions = ref([]); -const newPDA = ref({}); -const currentPDA = ref(null); +const paginate = ref(); +const dialog = ref(); +const route = useRoute(); +const { openConfirmationModal } = useVnConfirm(); +const routeId = computed(() => route.params.id); -const isAllowedToEdit = computed(() => hasAny(['hr', 'productionAssi'])); +const initialData = computed(() => { + return { + userFk: routeId.value, + deviceProductionFk: null, + simSerialNumber: null, + }; +}); -const setCurrentPDA = (data) => { - currentPDA.value = data; - currentPDA.value.description = `ID: ${currentPDA.value.deviceProductionFk} ${t( - 'worker.pda.model' - )}: ${currentPDA.value.deviceProduction.modelFk} ${t('worker.pda.serialNumber')}: ${ - currentPDA.value.deviceProduction.serialNumber - }`; -}; - -const deallocatePDA = async (data) => { +const deallocatePDA = async (deviceProductionFk) => { try { await axios.post(`Workers/${route.params.id}/deallocatePDA`, { - pda: currentPDA.value.deviceProductionFk, + pda: deviceProductionFk, }); - data.pda = null; - currentPDA.value = null; - await fetchCurrentDeviceRef.value.fetch(); notify(t('PDA deallocated'), 'positive'); } catch (err) { console.error('Error deallocating PDA'); } + paginate.value.fetch(); }; -onMounted(async () => await fetchCurrentDeviceRef.value.fetch()); +function reloadData() { + initialData.value.deviceProductionFk = null; + initialData.value.simSerialNumber = null; + paginate.value.fetch(); +} </script> <template> - <FetchData - url="DeviceProductions" - :filter="deviceProductionsFilter" - auto-load - @on-fetch="(data) => (deviceProductionsOptions = data)" - /> - <FetchData - ref="fetchCurrentDeviceRef" - url="DeviceProductionUsers" - :filter="{ - where: { userFk: route.params.id }, - include: { relation: 'deviceProduction' }, - }" - auto-load - @on-fetch="(data) => setCurrentPDA(data[0])" - /> - <QPage class="column items-center q-pa-md"> - <FormModel - url="DeviceProductionUsers" - :url-create="`Workers/${route.params.id}/allocatePDA`" - model="DeviceProductionUser" - :form-initial-data="newPDA" + <QPage class="column items-center q-pa-md centerCard"> + <FetchData + url="workers/getAvailablePda" + @on-fetch="(data) => (deviceProductions = data)" + auto-load + /> + <VnPaginate + ref="paginate" + data-key="WorkerPda" + url="DeviceProductionUsers" + :filter="{ where: { userFk: routeId } }" + order="id" auto-load - :default-buttons="{ save: { label: 'globals.assign', color: 'primary' } }" - @on-data-saved="(_, data) => setCurrentPDA(data)" > - <template #form="{ data }"> - <QField - v-if="currentPDA && currentPDA.description" - :label="t('worker.pda.currentPDA')" - :model-value="currentPDA.description" - :editable="false" - class="full-width" + <template #body="{ rows }"> + <QCard + flat + bordered + :key="row.id" + v-for="row of rows" + class="card q-pt-xs q-mb-sm" > - <template #control> - <div tabindex="0"> - {{ currentPDA.description }} - </div> - </template> - <template v-if="isAllowedToEdit" #append> - <QIcon - name="delete" - size="sm" - class="cursor-pointer" - color="primary" - @click="deallocatePDA(data)" - > - <QTooltip> - {{ t('worker.pda.removePDA') }} - </QTooltip> - </QIcon> - </template> - </QField> - - <VnSelect - v-else - :label="t('worker.pda.newPDA')" - v-model="data.pda" - :options="deviceProductionsOptions" - option-label="serialNumber" - option-value="id" - hide-selected - :disable="!isAllowedToEdit" - > - <template #option="scope"> - <QItem v-bind="scope.itemProps"> - <QItemSection> - <QItemLabel>ID: {{ scope.opt?.id }}</QItemLabel> - <QItemLabel caption> - {{ scope.opt?.modelFk }}, - {{ scope.opt?.serialNumber }} - </QItemLabel> - </QItemSection> - </QItem> - </template> - </VnSelect> + <QItem> + <QItemSection side-left> + <VnRow> + <QField + :label="t('worker.pda.currentPDA')" + :model-value="row?.deviceProductionFk" + disable + > + <template #control> + <div tabindex="0" style="padding: none"> + <span>Id: </span> + <span> + {{ row?.deviceProductionFk }} + </span> + <span>{{ t('Model') }}: </span> + <span> + {{ row?.deviceProduction?.modelFk }} + </span> + <span>{{ t('SIM serial number') }}: </span> + <span> + {{ + row?.deviceProduction?.serialNumber + }} + </span> + </div> + </template> + </QField> + <QField + :label="t('Current SIM')" + :model-value="row?.simSerialNumber" + disable + > + <template #control> + <div tabindex="0">{{ row?.simSerialNumber }}</div> + </template> + </QField> + </VnRow> + </QItemSection> + <QItemSection side> + <QIcon + name="delete" + size="sm" + class="cursor-pointer" + color="primary" + @click=" + openConfirmationModal( + t(`Remove PDA`), + t('Do you want to remove this PDA?'), + () => deallocatePDA(row.deviceProductionFk) + ) + " + > + <QTooltip> + {{ t('worker.pda.removePDA') }} + </QTooltip> + </QIcon> + </QItemSection> + </QItem> + </QCard> </template> - </FormModel> + </VnPaginate> + <QPageSticky :offset="[18, 18]"> + <QBtn @click.stop="dialog.show()" color="primary" fab icon="add"> + <QDialog ref="dialog"> + <FormModelPopup + :title="t('Add new device')" + url-create="DeviceProductionUsers" + model="DeviceProductionUser" + :form-initial-data="initialData" + @on-data-saved="reloadData()" + > + <template #form-inputs="{ data }"> + <VnRow class="row q-gutter-md q-mb-md"> + <VnSelect + :label="t('worker.pda.newPDA')" + v-model="data.deviceProductionFk" + :options="deviceProductions" + option-label="id" + option-value="id" + id="deviceProductionFk" + hide-selected + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel + >ID: {{ scope.opt?.id }}</QItemLabel + > + <QItemLabel caption> + {{ scope.opt?.modelFk }}, + {{ scope.opt?.serialNumber }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> + <VnInput + v-model="data.simSerialNumber" + :label="t('SIM serial number')" + id="simSerialNumber" + use-input + /> + </VnRow> + </template> + </FormModelPopup> + </QDialog> + </QBtn> + <QTooltip> + {{ t('globals.new') }} + </QTooltip> + </QPageSticky> </QPage> </template> - +<style lang="scss" scoped> +.centerCard { + padding: 5%; + width: 100%; + max-width: 70%; + margin: 0 auto; +} +.label { + color: red; +} +.q-field { + height: 65px; +} +</style> <i18n> es: + Remove PDA: Eliminar PDA + Do you want to remove this PDA?: ¿Desea eliminar este PDA? PDA deallocated: PDA desasignada + SIM serial number: Número de serie de la SIM + Model: Modelo + This PDA is already assigned to another user: Este PDA ya está asignado a otro usuario + Add new device: Añadir nuevo dispositivo </i18n> diff --git a/test/cypress/integration/worker/workerPda.spec.js b/test/cypress/integration/worker/workerPda.spec.js new file mode 100644 index 000000000..9af994a70 --- /dev/null +++ b/test/cypress/integration/worker/workerPda.spec.js @@ -0,0 +1,24 @@ +describe('WorkerPda', () => { + const deviceProductionField = + '.vn-row > .q-field > .q-field__inner > .q-field__control > .q-field__control-container'; + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit(`/#/worker/1110/pda`); + }); + + it('assign pda', () => { + cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click(); + cy.get(deviceProductionField).type('{downArrow}{enter}'); + cy.get('.vn-row > #simSerialNumber').type('123{enter}'); + cy.get('.q-notification__message').should('have.text', 'Data created'); + }); + + it('delete pda', () => { + cy.get('.q-card > .q-item > .q-item__section--side > .q-icon').click(); + cy.get( + '.q-card__actions > .q-btn--unelevated > .q-btn__content > .block' + ).click(); + cy.get('.q-notification__message').should('have.text', 'PDA deallocated'); + }); +});