Nouvelle interface

This commit is contained in:
2023-06-19 17:38:49 +02:00
parent 97c2175e7b
commit ebbd1de1eb
10 changed files with 162 additions and 28 deletions

56
package-lock.json generated
View File

@@ -14,6 +14,7 @@
"date-fns": "^2.30.0",
"gridjs": "^6.0.6",
"gridjs-vue": "^5.0.4",
"pinia": "^2.1.4",
"vue": "^3.2.47"
},
"devDependencies": {
@@ -478,6 +479,11 @@
"@vue/shared": "3.3.4"
}
},
"node_modules/@vue/devtools-api": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
},
"node_modules/@vue/reactivity": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
@@ -828,6 +834,56 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pinia": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.4.tgz",
"integrity": "sha512-vYlnDu+Y/FXxv1ABo1vhjC+IbqvzUdiUC3sfDRrRyY2CQSrqqaa+iiHmqtARFxJVqWQMCJfXx1PBvFs9aJVLXQ==",
"dependencies": {
"@vue/devtools-api": "^6.5.0",
"vue-demi": ">=0.14.5"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.0",
"typescript": ">=4.4.4",
"vue": "^2.6.14 || ^3.3.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.5.tgz",
"integrity": "sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/postcss": {
"version": "8.4.23",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",

View File

@@ -15,6 +15,7 @@
"date-fns": "^2.30.0",
"gridjs": "^6.0.6",
"gridjs-vue": "^5.0.4",
"pinia": "^2.1.4",
"vue": "^3.2.47"
},
"devDependencies": {

View File

@@ -1,15 +1,33 @@
<script setup>
import TicketList from '@/components/TicketList.vue'
import {computed, onMounted, ref, watch} from 'vue';
import {computed, nextTick, onMounted, ref, watch} from 'vue';
import {Tab} from 'bootstrap'
import TicketApi from "@/services/TicketApi.js";
import {useGlobalStore} from "@/stores/global";
import {storeToRefs} from "pinia";
const store = useGlobalStore()
const filter = ref('ALL');
const tickets = ref({});
const apiCounter = ref(0)
const waitingPromise = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve([]);
}, 100000);
});
}
const openExternalPage = async (script, params = null, features = null) => {
if (store.gulliver === null) {
await store.registerSession()
}
window.open(store.url + script + '?NUMC=' + store.numc + (params !== null ? '&' + params : ''), '_blank', features);
}
const newTickets = computed(() => {
return tickets.value.hasOwnProperty('new_tickets') ? mapListOfTickets(tickets.value.new_tickets.list, filter.value) : []
return tickets.value.hasOwnProperty('new_tickets') ? mapListOfTickets(tickets.value.new_tickets.list, filter.value) : waitingPromise
})
const pendingTickets = computed(() => {
@@ -27,11 +45,12 @@ const mapListOfTickets = (tickets, originFilter) => {
onMounted(async () => {
tickets.value = await TicketApi.getTickets()
apiCounter.value++
const myInterval = setInterval(async function () {
tickets.value = await TicketApi.getTickets()
apiCounter.value++
}, 180000);
})
@@ -58,13 +77,14 @@ onMounted(async () => {
fiches</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" onclick="alert('Non disponible dans cette version beta')"> <i
<a class="nav-link" href="#"
@click="openExternalPage('/php-client/pharma/ordo_manager.php', null, 'width=500,height=750')"> <i
class="fa-solid fa-file-medical"
></i> Livraisons
ordonnances</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" onclick="alert('Non disponible dans cette version beta')"><i
<a class="nav-link" href="#" @click="openExternalPage('/php/parameters.php', 'SEE=CUSTOMERS3&APPLI=1')"><i
class="fa-solid fa-bell-concierge"
></i> Accueil
Comptoir</a>
@@ -75,7 +95,8 @@ onMounted(async () => {
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/interface/ase_home.php?prj=pharmamp&config=TA&lang=fr_FR"><i class="fa-solid fa-shuffle"></i> Retourner sur la version de production
<a class="nav-link" href="/interface/ase_home.php?prj=pharmamp&config=TA&lang=fr_FR"><i
class="fa-solid fa-shuffle"></i> Retourner sur la version de production
</a>
</li>
@@ -114,16 +135,13 @@ onMounted(async () => {
</div>
</div>
<div class="tab-pane show active" id="new" role="tabpanel" tabindex="0">
<ticket-list :rows="newTickets" v-if="newTickets.length >0" :key="'new_'+filter"></ticket-list>
<div class="alert alert-success" v-else>Aucune fiche</div>
<ticket-list :rows="newTickets" :key="'new_'+filter+'_'+apiCounter"></ticket-list>
</div>
<div class="tab-pane" id="pending" role="tabpanel" tabindex="0">
<ticket-list :rows="pendingTickets" v-if="pendingTickets.length >0" :key="'pending_'+filter"></ticket-list>
<div class="alert alert-success" v-else>Aucune fiche</div>
<ticket-list :rows="pendingTickets" :key="'new_'+filter+'_'+apiCounter"></ticket-list>
</div>
<div class="tab-pane" id="my" role="tabpanel" tabindex="0">
<ticket-list :rows="myTickets" v-if="myTickets.length >0" :key="'my_'+filter"></ticket-list>
<div class="alert alert-success" v-else>Aucune fiche</div>
<ticket-list :rows="myTickets" :key="'new_'+filter+'_'+apiCounter"></ticket-list>
</div>
</div>
</div>

View File

@@ -7,6 +7,8 @@
$font-size-root : '16px';
$body-bg: #f6f9ff;
$tooltip-max-width: 400px;
$tooltip-opacity: 1;
@import "bootstrap/scss/variables";
@import "bootstrap/scss/maps";
@@ -50,6 +52,14 @@ $body-bg: #f6f9ff;
}
@import "bootstrap/scss/tooltip";
.custom-tooltip {
--bs-tooltip-bg: var(--bs-primary);
.tooltip-inner{
text-align: left;
}
}
// Helpers
@import "bootstrap/scss/helpers";

View File

@@ -7,7 +7,7 @@ import {Grid, html} from "gridjs";
import {Tooltip} from 'bootstrap'
const props = defineProps({
rows: Array,
rows: { type : [Array, Function]},
})
const gridWrapper = ref(null)
@@ -49,13 +49,21 @@ const grid = new Grid({
}, {
name: 'Derniers messages',
formatter: (cell, row) => {
return html('<span data-bs-toggle="tooltip" data-bs-html="true" title="<strong>'+row.cells[4].data.txt1+'</strong>'+ ( (row.cells[4].data.txt2 !== null) ? '<hr/>'+row.cells[4].data.txt2 : '')+'">' + cell + '</span>')
return html('<span style="cursor: pointer" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" data-bs-html="true" title="<strong>'+row.cells[4].data.txt1.replaceAll('"', '')+'</strong>'+ ( (row.cells[4].data.txt2 !== null) ? '<hr/>'+row.cells[4].data.txt2.replaceAll("\n", "<br\>").replaceAll('"', '') : '')+'"><i class="fa-regular fa-comment-dots fa-flip-horizontal text-primary"></i> ' + cell + '</span>')
}
}, 'Interlocuteur', {name: 'Client', width: '120px'}],
}, 'Interlocuteur',
{
name: 'Client',
width: '120px',
formatter: (cell) => {
return html(cell === 'oui' ? '<i class="fa-regular fa-circle-check text-success"></i>' : '<i class="fa-regular fa-circle-xmark text-danger"></i>')
}
}],
data: props.rows,
sort: true,
pagination: {
limit: 100,
limit: 15,
summary: false
},
language: {
@@ -87,11 +95,11 @@ const grid = new Grid({
onMounted(() => {
grid.render(gridWrapper.value)
setTimeout(function () {
let tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
let tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new Tooltip(tooltipTriggerEl)
})
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new Tooltip(tooltipTriggerEl))
}, 1000);
})

View File

@@ -1,6 +1,7 @@
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
import './assets/style.scss'
import './style.css'
@@ -11,4 +12,12 @@ import '@fortawesome/fontawesome-free/css/solid.css'
import '@fortawesome/fontawesome-free/css/regular.css'
import "gridjs/dist/theme/mermaid.css";
createApp(App).mount('#app')
const pinia = createPinia()
const app = createApp(App)
//app.use(router);
app.use(pinia)
//app.component('Datepicker', Datepicker);
app.mount("#app");

17
src/services/Api.js Normal file
View File

@@ -0,0 +1,17 @@
export default {
async call(controller, method) {
const apiUrl = '/App/api.php?prj=pharmamp&controller='+controller+'&method='+method
if (import.meta.env.DEV) {
console.log(apiUrl)
}
const response = await fetch(apiUrl)
if (import.meta.env.DEV) {
console.log(response.clone().text())
}
return response.json();
}
}

View File

@@ -1,7 +1,6 @@
export default {
async getNew() {
const apiUrl = '/App/api.php?prj=pharmamp';
async getSessionData() {
const apiUrl = '/App/api.php?prj=pharmamp&controller=AdminController&method=getSession'
if (import.meta.env.DEV) {
console.log(apiUrl)
@@ -14,6 +13,5 @@ export default {
}
return response.json();
},
}
}

View File

@@ -1,6 +1,6 @@
export default {
async getTickets() {
const apiUrl = '/App/api.php?prj=pharmamp'
const apiUrl = '/App/api.php?prj=pharmamp&controller=TicketingController&method=getTickets'
if (import.meta.env.DEV) {
console.log(apiUrl)

17
src/stores/global.js Normal file
View File

@@ -0,0 +1,17 @@
import {defineStore} from 'pinia'
import Api from "@/services/Api.js";
export const useGlobalStore = defineStore('global', {
state: () => ({
gulliver: null
}),
getters: {
numc: (state) => state.gulliver.numc,
url : (state) => state.gulliver.url,
},
actions: {
async registerSession(){
this.gulliver = await Api.call('AdminController', 'getSession')
}
},
})