Archivage fiches
This commit is contained in:
44
src/App.vue
44
src/App.vue
@@ -9,6 +9,8 @@ import Messenger from "@/components/Messenger.vue";
|
|||||||
import TicketList from '@/components/TicketList.vue'
|
import TicketList from '@/components/TicketList.vue'
|
||||||
import Modal from '@/components/base/Modal.vue'
|
import Modal from '@/components/base/Modal.vue'
|
||||||
import FormReply from "@/components/FormReply.vue";
|
import FormReply from "@/components/FormReply.vue";
|
||||||
|
import TicketApi from "@/services/TicketApi.js";
|
||||||
|
import FetchIcon from "@/components/base/FetchIcon.vue";
|
||||||
|
|
||||||
const store = useGlobalStore()
|
const store = useGlobalStore()
|
||||||
const storeTicket = useTicketStore();
|
const storeTicket = useTicketStore();
|
||||||
@@ -22,7 +24,11 @@ const {
|
|||||||
} = storeToRefs(storeTicket)
|
} = storeToRefs(storeTicket)
|
||||||
|
|
||||||
const apiCounter = ref(0)
|
const apiCounter = ref(0)
|
||||||
|
const archivePeriod = ref('ALL')
|
||||||
|
const archiveFetching = ref(false)
|
||||||
|
|
||||||
|
const showModal2 = ref(0)
|
||||||
|
const hideModal2 = ref(0)
|
||||||
const openExternalPage = async (script, params = null, features = null) => {
|
const openExternalPage = async (script, params = null, features = null) => {
|
||||||
if (store.gulliver === null) {
|
if (store.gulliver === null) {
|
||||||
await store.registerSession()
|
await store.registerSession()
|
||||||
@@ -44,6 +50,16 @@ const mapListOfTickets = (tickets) => {
|
|||||||
[ticket.code, ticket.datetime, ticket.filter1, ticket.filter2, ticket, ticket.advisor, ticket.datetime, ticket.state2, ticket.first_name + ' ' + ticket.last_name, ticket.is_customer]);
|
[ticket.code, ticket.datetime, ticket.filter1, ticket.filter2, ticket, ticket.advisor, ticket.datetime, ticket.state2, ticket.first_name + ' ' + ticket.last_name, ticket.is_customer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const archiveStart = async () => {
|
||||||
|
archiveFetching.value = true
|
||||||
|
await TicketApi.archiveTickets(archivePeriod.value)
|
||||||
|
archiveFetching.value = false
|
||||||
|
hideModal2.value++
|
||||||
|
await storeTicket.registerTicketList()
|
||||||
|
apiCounter.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await store.registerUserSession();
|
await store.registerUserSession();
|
||||||
await storeTicket.registerTicketList()
|
await storeTicket.registerTicketList()
|
||||||
@@ -74,6 +90,32 @@ onMounted(async () => {
|
|||||||
</template>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<Modal :show="showModal2" :hide="hideModal2" class="modal-lg">
|
||||||
|
<template v-slot:modal-title>Archiver les fiches
|
||||||
|
</template>
|
||||||
|
<template v-slot:modal-body>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="archivePeriod" class="form-label">Archiver les fiches en cours :</label>
|
||||||
|
<select class="form-select" id="archivePeriod" v-model="archivePeriod">
|
||||||
|
<option value="ALL">Toutes les fiches</option>
|
||||||
|
<option value="MONTH:1">Les fiches de plus d'un mois</option>
|
||||||
|
<option value="MONTH:6">Les fiches de plus de six mois</option>
|
||||||
|
<option value="MONTH:12">Les fiches de plus d'un an</option>
|
||||||
|
<option value="MONTH:24">Les fiches de plus de deux ans</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-text text-end">Une fois archivées, vous pourrez retrouver les fiches par une "Recherche
|
||||||
|
avancée"
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-slot:modal-footer>
|
||||||
|
<button type="button" class="btn btn-secondary" @click="showModal2 += 1;"><i class="fas fa-close"></i> Fermer</button>
|
||||||
|
<button type="button" value="Lancer l'archivage" class="btn btn-primary" @click="archiveStart"><fetch-icon :is-fetching="archiveFetching"></fetch-icon> Lancer
|
||||||
|
l'archivage
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div id="notification" class="alert d-none" style="position: absolute; top:5px; right:28px;z-index:1"></div>
|
<div id="notification" class="alert d-none" style="position: absolute; top:5px; right:28px;z-index:1"></div>
|
||||||
<div class="pagetitle">
|
<div class="pagetitle">
|
||||||
@@ -101,7 +143,7 @@ onMounted(async () => {
|
|||||||
Comptoir</a>
|
Comptoir</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#" onclick="alert('Non disponible dans cette version beta')"><i
|
<a class="nav-link" href="#" @click="showModal2++"><i
|
||||||
class="fa-solid fa-box-archive"></i> Archiver les fiches en cours ?
|
class="fa-solid fa-box-archive"></i> Archiver les fiches en cours ?
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
26
src/components/BaseElements/BaseAlert.vue
Normal file
26
src/components/BaseElements/BaseAlert.vue
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
default: 'Opération réussie'
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="status ? 'alert-success' : 'alert-danger'" class="alert fade show animated animate__bounceIn"
|
||||||
|
role="alert">
|
||||||
|
<i :class="status ? 'fa-check' : 'fa-xmark'" class="fas fa-sm fa-fw mr-2"></i> {{ message }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
27
src/components/BaseElements/BaseCheckbox.vue
Normal file
27
src/components/BaseElements/BaseCheckbox.vue
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:checked="modelValue"
|
||||||
|
@change="$emit('update:modelValue', $event.target.checked)"
|
||||||
|
class="form-check-input"
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" v-if="label" :for="$attrs.hasOwnProperty('id') ? $attrs.id : null">{{ label }}</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
24
src/components/BaseElements/BaseGrid.vue
Normal file
24
src/components/BaseElements/BaseGrid.vue
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<script setup>
|
||||||
|
import {Grid} from "gridjs";
|
||||||
|
import {onMounted, ref} from "vue";
|
||||||
|
|
||||||
|
const gridWrapper = ref(null)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
gridConfig: {type: Object},
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const grid = new Grid(props.gridConfig)
|
||||||
|
grid.render(gridWrapper.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="gridWrapper"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
74
src/components/BaseElements/BaseInput.vue
Normal file
74
src/components/BaseElements/BaseInput.vue
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<script setup>
|
||||||
|
import {nextTick, onMounted, ref, watch} from "vue";
|
||||||
|
|
||||||
|
import {useShipmentStore} from '@/stores/shipment.js'
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
|
||||||
|
const store = useShipmentStore();
|
||||||
|
const {currentFocus} = storeToRefs(store);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
classLabel: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
autoFocus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
insideModal: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const inputRef = ref(null)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
|
||||||
|
if (props.autoFocus) {
|
||||||
|
|
||||||
|
if (props.insideModal) {
|
||||||
|
setTimeout(function () {
|
||||||
|
inputRef.value.focus()
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
inputRef.value.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(currentFocus, async (to, from) => {
|
||||||
|
if (to === props.name && from !== props.name) {
|
||||||
|
await nextTick()
|
||||||
|
inputRef.value.focus()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input
|
||||||
|
ref="inputRef"
|
||||||
|
:value="modelValue"
|
||||||
|
v-bind="{
|
||||||
|
...$attrs,
|
||||||
|
onInput: ($event) => { $emit('update:modelValue', $event.target.value) }
|
||||||
|
}"
|
||||||
|
class="form-control"
|
||||||
|
>
|
||||||
|
<label :class="classLabel" :for="$attrs.hasOwnProperty('id') ? $attrs.id : null" v-if="label">{{ label }}</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
32
src/components/BaseElements/BaseRadio.vue
Normal file
32
src/components/BaseElements/BaseRadio.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
:checked="modelValue === value"
|
||||||
|
:value="value"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@change="$emit('update:modelValue', value)"
|
||||||
|
/>
|
||||||
|
<label v-if="label">{{ label }}</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
46
src/components/BaseElements/BaseRadioGroup.vue
Normal file
46
src/components/BaseElements/BaseRadioGroup.vue
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
vertical: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component
|
||||||
|
v-for="option in options"
|
||||||
|
:key="option.value"
|
||||||
|
:is="vertical ? 'div' : 'span'"
|
||||||
|
:class="{
|
||||||
|
horizontal: !vertical
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<BaseRadio
|
||||||
|
:label="option.label"
|
||||||
|
:value="option.value"
|
||||||
|
:modelValue="modelValue"
|
||||||
|
:name="name"
|
||||||
|
@update:modelValue="$emit('update:modelValue', $event)"
|
||||||
|
/>
|
||||||
|
</component>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.horizontal {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
55
src/components/BaseElements/BaseSelect.vue
Normal file
55
src/components/BaseElements/BaseSelect.vue
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true,
|
||||||
|
validator(value, props) {
|
||||||
|
return props.options.includes(value) || props.options.some(option => option.code === value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// onMounted(() => {
|
||||||
|
// // on vérifie que modelValue est dans la liste des options
|
||||||
|
// if (!props.options.some(option => option.code === props.modelValue)) {
|
||||||
|
// // console.log('modelValue not found');
|
||||||
|
// // emit('update:modelValue', props.options[0].code);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<select
|
||||||
|
class="form-select"
|
||||||
|
:value="modelValue"
|
||||||
|
v-bind="{
|
||||||
|
...$attrs,
|
||||||
|
onChange: ($event) => { $emit('update:modelValue', $event.target.value) }
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="option in options"
|
||||||
|
:key="option.hasOwnProperty('code') ? option.code : option"
|
||||||
|
:value="option.hasOwnProperty('code') ? option.code : option"
|
||||||
|
:disabled="option.hasOwnProperty('disabled') ? option.disabled : false"
|
||||||
|
>
|
||||||
|
{{ option.hasOwnProperty('label') ? option.label : option }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<label v-if="label">{{ label }}</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
21
src/components/base/FetchIcon.vue
Normal file
21
src/components/base/FetchIcon.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
isFetching: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: 'fa-solid fa-check',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<i v-if="isFetching" class="fa-solid fa-circle-notch fa-spin fa-fw"></i>
|
||||||
|
<i v-else :class="icon"></i>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
|
import {useGlobalStore} from "@/stores/global";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async call(controller, method) {
|
buildUrl(controller, method, param = null) {
|
||||||
const apiUrl = '/App/api.php?prj=pharmamp&controller='+controller+'&method='+method
|
const store = useGlobalStore()
|
||||||
|
return '/App/api.php?prj=' + store.projectName + '&controller=' + controller + '&method=' + method + ((param !== null) ? param : '')
|
||||||
|
},
|
||||||
|
async get(controller, method, param = null) {
|
||||||
|
|
||||||
|
const apiUrl = this.buildUrl(controller, method, param)
|
||||||
|
|
||||||
if (import.meta.env.DEV) {
|
if (import.meta.env.DEV) {
|
||||||
console.log(apiUrl)
|
console.log(apiUrl)
|
||||||
@@ -12,6 +19,23 @@ export default {
|
|||||||
console.log(response.clone().text())
|
console.log(response.clone().text())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
},
|
||||||
|
async post(url, FormData) {
|
||||||
|
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
console.log(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: FormData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
console.log(response.clone().text())
|
||||||
|
}
|
||||||
|
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import Api from '@/services/Api.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async getTickets() {
|
async getTickets() {
|
||||||
const apiUrl = '/App/api.php?prj=pharmamp&controller=TicketingController&method=getTickets'
|
const apiUrl = '/App/api.php?prj=pharmamp&controller=TicketingController&method=getTickets'
|
||||||
@@ -150,4 +152,7 @@ export default {
|
|||||||
|
|
||||||
return response.json();
|
return response.json();
|
||||||
},
|
},
|
||||||
|
async archiveTickets(archivePeriod) {
|
||||||
|
return Api.get('TicketingController', 'archiveTickets', '&archivage_from='+archivePeriod)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Api from "@/services/Api.js";
|
|||||||
export const useGlobalStore = defineStore('global', {
|
export const useGlobalStore = defineStore('global', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
gulliver: null,
|
gulliver: null,
|
||||||
gta: {idProject: null, projectName: null, projectUrl:null},
|
gta: {idProject: null, projectName: 'pharmamp', projectUrl:null},
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
numc: (state) => state.gulliver.numc,
|
numc: (state) => state.gulliver.numc,
|
||||||
@@ -15,10 +15,10 @@ export const useGlobalStore = defineStore('global', {
|
|||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async registerSession() {
|
async registerSession() {
|
||||||
this.gulliver = await Api.call('AdminController', 'getSession')
|
this.gulliver = await Api.get('AdminController', 'getSession')
|
||||||
},
|
},
|
||||||
async registerUserSession() {
|
async registerUserSession() {
|
||||||
this.gta = {...await Api.call('AdminController', 'getUserSession')}
|
this.gta = {...await Api.get('AdminController', 'getUserSession')}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user