forked from verdnatura/salix-front
Merge pull request '4075-ticket_boxing' (#20) from 4075-ticket_boxing into dev
Reviewed-on: verdnatura/salix-front#20
This commit is contained in:
commit
c346ce30e6
|
@ -56,6 +56,16 @@ export default {
|
|||
list: 'List',
|
||||
createTicket: 'Create ticket',
|
||||
basicData: 'Basic Data'
|
||||
},
|
||||
boxing: {
|
||||
expedition: 'Expedition',
|
||||
item: 'Item',
|
||||
created: 'Created',
|
||||
worker: 'Worker',
|
||||
selectTime: 'Select time:',
|
||||
selectVideo: 'Select video:',
|
||||
notFound: 'No videos available'
|
||||
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -56,6 +56,15 @@ export default {
|
|||
list: 'Listado',
|
||||
createTicket: 'Crear ticket',
|
||||
basicData: 'Datos básicos'
|
||||
},
|
||||
boxing: {
|
||||
expedition: 'Expedición',
|
||||
item: 'Artículo',
|
||||
created: 'Creado',
|
||||
worker: 'Trabajador',
|
||||
selectTime: 'Seleccionar hora:',
|
||||
selectVideo: 'Seleccionar vídeo:',
|
||||
notFound: 'No hay vídeos disponibles'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import LeftMenu from 'src/components/LeftMenu.vue';
|
||||
//import LeftMenu from 'src/components/LeftMenu.vue';
|
||||
|
||||
const state = useState();
|
||||
const miniState = ref(true);
|
||||
|
|
|
@ -33,7 +33,7 @@ describe('Login', () => {
|
|||
}
|
||||
jest.spyOn(axios, 'post').mockResolvedValue({ data: { token: 'token' } });
|
||||
jest.spyOn(axios, 'get').mockResolvedValue({ data: { roles: [], user: expectedUser } });
|
||||
jest.spyOn(vm.quasar, 'notify')
|
||||
jest.spyOn(vm.quasar, 'notify');
|
||||
|
||||
expect(vm.session.getToken()).toEqual('');
|
||||
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { computed, ref, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import axios from 'axios';
|
||||
import { date, useQuasar } from 'quasar';
|
||||
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const quasar = useQuasar();
|
||||
|
||||
onMounted(async () => {
|
||||
await fetch();
|
||||
});
|
||||
|
||||
const entityId = computed(function () {
|
||||
return router.currentRoute.value.params.id;
|
||||
});
|
||||
|
||||
const expeditions = ref({});
|
||||
const lastExpedition = ref();
|
||||
const slide = ref(null);
|
||||
const videoList = ref([]);
|
||||
const time = ref({
|
||||
min: 0,
|
||||
max: 24,
|
||||
});
|
||||
|
||||
async function fetch() {
|
||||
const filter = {
|
||||
where: {
|
||||
ticketFk: entityId.value,
|
||||
},
|
||||
};
|
||||
const { data } = await axios.get(`/Expeditions/filter`, {
|
||||
params: { filter },
|
||||
});
|
||||
|
||||
if (data) expeditions.value = data;
|
||||
}
|
||||
|
||||
async function getVideoList(expeditionId, timed) {
|
||||
lastExpedition.value = expeditionId;
|
||||
const params = {
|
||||
id: expeditionId,
|
||||
};
|
||||
|
||||
if (timed) {
|
||||
Object.assign(params, { from: timed.min, to: timed.max });
|
||||
}
|
||||
const { data } = await axios.get(`/Boxings/getVideoList`, { params: params });
|
||||
|
||||
const list = [];
|
||||
for (const video of data) {
|
||||
const videName = video.split('.')[0].split('T')[1].replaceAll('-', ':');
|
||||
list.push({
|
||||
label: videName,
|
||||
value: video,
|
||||
url: `api/Boxings/getVideo?id=${expeditionId}&filename=${video}`,
|
||||
});
|
||||
}
|
||||
|
||||
videoList.value = list.reverse();
|
||||
if (list[0]) {
|
||||
slide.value = list[0].value;
|
||||
time.value = {
|
||||
min: parseInt(list[0].label.split(':')[0]),
|
||||
max: parseInt(list[list.length - 1].label.split(':')[0]),
|
||||
};
|
||||
}
|
||||
|
||||
if (!data.length) {
|
||||
return quasar.notify({
|
||||
message: t('ticket.boxing.notFound'),
|
||||
type: 'negative',
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-layout view="hhh lpr ffr" class="fit">
|
||||
<q-drawer show-if-above side="right" bordered>
|
||||
<q-scroll-area class="fit">
|
||||
<q-list bordered separator style="max-width: 318px">
|
||||
<q-item v-if="lastExpedition && videoList.length">
|
||||
<q-item-section>
|
||||
<q-item-label class="text-h6">
|
||||
{{ t('ticket.boxing.selectTime') }} ({{ time.min }}-{{ time.max }})
|
||||
</q-item-label>
|
||||
<q-range
|
||||
v-model="time"
|
||||
@change="getVideoList(lastExpedition, time)"
|
||||
:min="0"
|
||||
:max="24"
|
||||
:step="1"
|
||||
:left-label-value="time.min + ':00'"
|
||||
:right-label-value="time.max + ':00'"
|
||||
label
|
||||
markers
|
||||
snap
|
||||
color="orange"
|
||||
/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="lastExpedition && videoList.length">
|
||||
<q-item-section>
|
||||
<q-select
|
||||
color="orange"
|
||||
v-model="slide"
|
||||
:options="videoList"
|
||||
:label="t('ticket.boxing.selectVideo')"
|
||||
emit-value
|
||||
map-options
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="schedule" />
|
||||
</template>
|
||||
</q-select>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
v-for="expedition in expeditions"
|
||||
:key="expedition.id"
|
||||
@click="getVideoList(expedition.id)"
|
||||
clickable
|
||||
v-ripple
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label class="text-h6">#{{ expedition.id }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ t('ticket.boxing.created') }}</q-item-label>
|
||||
<q-item-label>
|
||||
{{ date.formatDate(expedition.created, 'YYYY-MM-DD HH:mm:ss') }}
|
||||
</q-item-label>
|
||||
<q-item-label caption>{{ t('ticket.boxing.item') }}</q-item-label>
|
||||
<q-item-label>{{ expedition.packagingItemFk }}</q-item-label>
|
||||
<q-item-label caption>{{ t('ticket.boxing.worker') }}</q-item-label>
|
||||
<q-item-label>{{ expedition.userName }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
|
||||
<q-page-container>
|
||||
<q-page>
|
||||
<q-card>
|
||||
<q-carousel animated v-model="slide" height="max-content">
|
||||
<q-carousel-slide v-for="video in videoList" :key="video.value" :name="video.value">
|
||||
<q-video :src="video.url" :ratio="16 / 9" />
|
||||
</q-carousel-slide>
|
||||
</q-carousel>
|
||||
</q-card>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
</q-layout>
|
||||
</template>
|
|
@ -1,23 +1,23 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { useRouter } from 'vue-router';
|
||||
//import { computed } from 'vue';
|
||||
//import { useState } from 'src/composables/useState';
|
||||
//import { useRouter } from 'vue-router';
|
||||
|
||||
const state = useState();
|
||||
const router = useRouter();
|
||||
const entityId = computed(function () {
|
||||
//const state = useState();
|
||||
//const router = useRouter();
|
||||
/*const entityId = computed(function () {
|
||||
return router.currentRoute.value.params.id;
|
||||
});
|
||||
});*/
|
||||
</script>
|
||||
<template>
|
||||
<q-drawer v-model="state.drawer.value" show-if-above :width="200" :breakpoint="500">
|
||||
<!--<q-drawer v-model="state.drawer.value" show-if-above :width="200" :breakpoint="500">
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<router-link :to="{ path: '/customer/list' }">
|
||||
<q-icon name="arrow_back" size="md" color="primary" />
|
||||
</router-link>
|
||||
<div>Customer ID: {{ entityId }}</div>
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
</q-drawer>-->
|
||||
<q-page-container>
|
||||
<router-view></router-view>
|
||||
</q-page-container>
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { jest, describe, expect, it, beforeAll } from '@jest/globals';
|
||||
import { createWrapper, axios } from 'app/tests/jest/jestHelpers';
|
||||
import TicketBoxing from '../TicketBoxing.vue';
|
||||
|
||||
const mockPush = jest.fn();
|
||||
|
||||
jest.mock('vue-router', () => ({
|
||||
useRouter: () => ({
|
||||
push: mockPush,
|
||||
currentRoute: {
|
||||
value: {
|
||||
params: {
|
||||
id: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('TicketBoxing', () => {
|
||||
let vm;
|
||||
beforeAll(() => {
|
||||
vm = createWrapper(TicketBoxing).vm;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('getVideoList()', () => {
|
||||
it('should when response videoList use to list', async () => {
|
||||
const expeditionId = 1;
|
||||
const timed = {
|
||||
min: 1,
|
||||
max: 2
|
||||
}
|
||||
const videoList = [
|
||||
"2022-01-01T01-01-00.mp4",
|
||||
"2022-02-02T02-02-00.mp4",
|
||||
"2022-03-03T03-03-00.mp4",
|
||||
]
|
||||
|
||||
jest.spyOn(axios, 'get').mockResolvedValue({ data: videoList });
|
||||
jest.spyOn(vm.quasar, 'notify');
|
||||
|
||||
await vm.getVideoList(expeditionId, timed);
|
||||
|
||||
expect(vm.videoList.length).toEqual(videoList.length);
|
||||
expect(vm.slide).toEqual(videoList.reverse()[0]);
|
||||
});
|
||||
|
||||
it('should if not have video show notify', async () => {
|
||||
const expeditionId = 1;
|
||||
const timed = {
|
||||
min: 1,
|
||||
max: 2
|
||||
}
|
||||
|
||||
jest.spyOn(axios, 'get').mockResolvedValue({ data: [] });
|
||||
jest.spyOn(vm.quasar, 'notify')
|
||||
|
||||
await vm.getVideoList(expeditionId, timed);
|
||||
|
||||
expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining(
|
||||
{ 'type': 'negative' }
|
||||
));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import LeftMenu from 'src/components/LeftMenu.vue';
|
||||
//import LeftMenu from 'src/components/LeftMenu.vue';
|
||||
|
||||
const state = useState();
|
||||
const miniState = ref(true);
|
||||
|
@ -18,9 +18,9 @@ const miniState = ref(true);
|
|||
:width="256"
|
||||
:breakpoint="500"
|
||||
>
|
||||
<q-scroll-area class="fit text-grey-8">
|
||||
<!--<q-scroll-area class="fit text-grey-8">
|
||||
<LeftMenu />
|
||||
</q-scroll-area>
|
||||
</q-scroll-area>-->
|
||||
</q-drawer>
|
||||
<q-page-container>
|
||||
<router-view></router-view>
|
||||
|
|
|
@ -51,8 +51,16 @@ export default {
|
|||
title: 'basicData'
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketBasicData.vue'),
|
||||
},
|
||||
{
|
||||
path: 'boxing',
|
||||
name: 'TicketBoxing',
|
||||
meta: {
|
||||
title: 'boxing'
|
||||
},
|
||||
component: () => import('src/pages/Ticket/Card/TicketBoxing.vue'),
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
describe('TicketBoxing', () => {
|
||||
beforeEach(() => {
|
||||
const ticketId = 1;
|
||||
cy.viewport(1280, 720)
|
||||
cy.login('developer')
|
||||
cy.visit(`/#/ticket/${ticketId}/boxing`);
|
||||
});
|
||||
|
||||
it('should load expeditions of ticket', () => {
|
||||
cy.get('div[class="q-item__label text-h6"]').eq(0).should('have.text', '#1');
|
||||
cy.get('div[class="q-item__label text-h6"]').eq(1).should('have.text', '#2');
|
||||
cy.get('div[class="q-item__label text-h6"]').eq(2).should('have.text', '#3');
|
||||
});
|
||||
|
||||
it('should show error if not have video list', () => {
|
||||
cy.get('div[class="q-item__label text-h6"]').eq(0).click();
|
||||
cy.get('.q-notification__message').should('have.text', 'No videos available');
|
||||
});
|
||||
|
||||
it('should show select time and video if have video list', () => {
|
||||
cy.intercept(
|
||||
{
|
||||
method: 'GET',
|
||||
url: '/api/Boxings/*',
|
||||
},
|
||||
[
|
||||
"2022-01-01T01-01-00.mp4",
|
||||
"2022-02-02T02-02-00.mp4",
|
||||
"2022-03-03T03-03-00.mp4",
|
||||
]
|
||||
).as('getVideoList');
|
||||
cy.get('.q-list > :nth-child(3)').click();
|
||||
|
||||
cy.get('.q-list > :nth-child(1)').should('be.visible');
|
||||
cy.get('.q-list > :nth-child(2)').should('be.visible');
|
||||
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue