Compare commits
8 Commits
v0.0.31
...
1cfdc061f7
| Author | SHA1 | Date | |
|---|---|---|---|
| 1cfdc061f7 | |||
| 2db4215131 | |||
|
|
d3af654858 | ||
| 168d8c78eb | |||
|
|
338d903cef | ||
| 42ce1e2d08 | |||
|
|
0d0aa788db | ||
| c010bdc262 |
99
.idea/workspace.xml
generated
99
.idea/workspace.xml
generated
@@ -4,7 +4,12 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="fix : auto-tag-develop.yml" />
|
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="fix : panel scrollable plus interface revue">
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/config/reference.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/reference.php" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/frontend/pages/admin/carrier/carrier-list.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/admin/carrier/carrier-list.vue" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/frontend/pages/admin/supplier/supplier-list.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/admin/supplier/supplier-list.vue" afterDir="false" />
|
||||||
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
@@ -215,43 +220,43 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||||
"git-widget-placeholder": "develop",
|
"git-widget-placeholder": "feat/312-creation-d-une-page-d-administration-listing-des-fournisseurs",
|
||||||
"last_opened_file_path": "/home/sroy/Documents/test/Ferme",
|
"last_opened_file_path": "/home/sroy/Documents/test/Ferme",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"settings.editor.selected.configurable": "configurable.tailwindcss",
|
"settings.editor.selected.configurable": "configurable.tailwindcss",
|
||||||
"ts.external.directory.path": "/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external",
|
"ts.external.directory.path": "/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
},
|
},
|
||||||
"keyToStringList": {
|
"keyToStringList": {
|
||||||
"DatabaseDriversLRU": [
|
"DatabaseDriversLRU": [
|
||||||
"postgresql"
|
"postgresql"
|
||||||
],
|
],
|
||||||
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [
|
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [
|
||||||
"TEXT"
|
"TEXT"
|
||||||
],
|
],
|
||||||
"vue.recent.templates": [
|
"vue.recent.templates": [
|
||||||
"Vue Composition API Component"
|
"Vue Composition API Component"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
|
<recent name="\\wsl.localhost\Ubuntu-24.04\home\matte\Ferme\frontend\pages\admin\supplier" />
|
||||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\m-tristan\workspace\Ferme" />
|
<recent name="\\wsl.localhost\Ubuntu-24.04\home\m-tristan\workspace\Ferme" />
|
||||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\tristan\workspace\ferme\templates" />
|
<recent name="\\wsl.localhost\Ubuntu-24.04\home\tristan\workspace\ferme\templates" />
|
||||||
<recent name="C:\Users\autin\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches" />
|
<recent name="C:\Users\autin\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches" />
|
||||||
<recent name="C:\Users\autin\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches\Ferme_MCD\MCD_DOC" />
|
<recent name="C:\Users\autin\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches\Ferme_MCD\MCD_DOC" />
|
||||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\tristan\workspace\ferme\frontend\pages\reception" />
|
|
||||||
</key>
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="SharedIndexes">
|
<component name="SharedIndexes">
|
||||||
@@ -292,22 +297,6 @@
|
|||||||
<workItem from="1770195959162" duration="18915000" />
|
<workItem from="1770195959162" duration="18915000" />
|
||||||
<workItem from="1770274844804" duration="3940000" />
|
<workItem from="1770274844804" duration="3940000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00008" summary="feat : ajout de la génération du bon de reception, correction de la base du formulaire multi-etape de reception et ajout d'une gestion d'erreur global">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1768498751836</created>
|
|
||||||
<option name="number" value="00008" />
|
|
||||||
<option name="presentableId" value="LOCAL-00008" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1768498751836</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00009" summary="feat : ajout d'une gestion d'erreur au global côté front avec la lib toaster et I18n pour centraliser les messages d'erreur">
|
|
||||||
<option name="closed" value="true" />
|
|
||||||
<created>1768555180530</created>
|
|
||||||
<option name="number" value="00009" />
|
|
||||||
<option name="presentableId" value="LOCAL-00009" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1768555180530</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00010" summary="feat : ajout de l'authentification avec lexik">
|
<task id="LOCAL-00010" summary="feat : ajout de l'authentification avec lexik">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
<created>1768832208350</created>
|
<created>1768832208350</created>
|
||||||
@@ -684,7 +673,23 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1770370919043</updated>
|
<updated>1770370919043</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="57" />
|
<task id="LOCAL-00057" summary="feat : test auto-tag-develop.yml (auto incrément version)">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1770371073055</created>
|
||||||
|
<option name="number" value="00057" />
|
||||||
|
<option name="presentableId" value="LOCAL-00057" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1770371073055</updated>
|
||||||
|
</task>
|
||||||
|
<task id="LOCAL-00058" summary="fix : nom page fournisseur">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1770632525875</created>
|
||||||
|
<option name="number" value="00058" />
|
||||||
|
<option name="presentableId" value="LOCAL-00058" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1770632525875</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="59" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@@ -734,8 +739,6 @@
|
|||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="VcsManagerConfiguration">
|
<component name="VcsManagerConfiguration">
|
||||||
<MESSAGE value="fix : doc et script de déploiement" />
|
|
||||||
<MESSAGE value="fix : gitea workflow" />
|
|
||||||
<MESSAGE value="fix : script de déploiement" />
|
<MESSAGE value="fix : script de déploiement" />
|
||||||
<MESSAGE value="feat : ajout plus d'information sur la liste des réceptions côté front sur la page d'accueil" />
|
<MESSAGE value="feat : ajout plus d'information sur la liste des réceptions côté front sur la page d'accueil" />
|
||||||
<MESSAGE value="fix : redirige sur le login sur une 401 et reset du auth state + doc + timeout du toaster" />
|
<MESSAGE value="fix : redirige sur le login sur une 401 et reset du auth state + doc + timeout du toaster" />
|
||||||
@@ -759,7 +762,9 @@
|
|||||||
<MESSAGE value="feat : ajout d'un numéro de version automatique via la CI" />
|
<MESSAGE value="feat : ajout d'un numéro de version automatique via la CI" />
|
||||||
<MESSAGE value="feat : update numéro de version" />
|
<MESSAGE value="feat : update numéro de version" />
|
||||||
<MESSAGE value="fix : auto-tag-develop.yml" />
|
<MESSAGE value="fix : auto-tag-develop.yml" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="fix : auto-tag-develop.yml" />
|
<MESSAGE value="feat : test auto-tag-develop.yml (auto incrément version)" />
|
||||||
|
<MESSAGE value="fix : nom page fournisseur" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="fix : nom page fournisseur" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XSLT-Support.FileAssociations.UIState">
|
<component name="XSLT-Support.FileAssociations.UIState">
|
||||||
<expand />
|
<expand />
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ Ajouter dans le fichier .env du frontend
|
|||||||
* Finalisation de la partie réception de marchandise
|
* Finalisation de la partie réception de marchandise
|
||||||
* [#267] Lister les réceptions en attente
|
* [#267] Lister les réceptions en attente
|
||||||
* [#268] Lister les réceptions terminées
|
* [#268] Lister les réceptions terminées
|
||||||
|
* [#316] Admin liste des transporteurs
|
||||||
|
* [#312] Creation administration listing fournisseurs
|
||||||
|
* [#317] Admin modification creation transporteur
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ security:
|
|||||||
- { path: ^/api/users, roles: PUBLIC_ACCESS, methods: [GET] }
|
- { path: ^/api/users, roles: PUBLIC_ACCESS, methods: [GET] }
|
||||||
# Doc API (swagger) en public
|
# Doc API (swagger) en public
|
||||||
- { path: ^/api/docs, roles: PUBLIC_ACCESS }
|
- { path: ^/api/docs, roles: PUBLIC_ACCESS }
|
||||||
|
# Version de l'application en public
|
||||||
|
- { path: ^/api/version, roles: PUBLIC_ACCESS, methods: [GET] }
|
||||||
# Tout le reste nécessite un JWT
|
# Tout le reste nécessite un JWT
|
||||||
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
|
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
parameters:
|
parameters:
|
||||||
app.version: '0.0.31'
|
app.version: '0.0.34'
|
||||||
|
|||||||
@@ -3,3 +3,11 @@
|
|||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const { load } = useAppVersion()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
load()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|||||||
17
frontend/composables/useAppVersion.ts
Normal file
17
frontend/composables/useAppVersion.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export const useAppVersion = () => {
|
||||||
|
const api = useApi()
|
||||||
|
const version = useState<string | null>('app-version', () => null)
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
if (version.value) {
|
||||||
|
return version.value
|
||||||
|
}
|
||||||
|
const response = await api.get<{ version: string }>('version', {}, {
|
||||||
|
toast: false
|
||||||
|
})
|
||||||
|
version.value = response.version
|
||||||
|
return version.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return { version, load }
|
||||||
|
}
|
||||||
@@ -46,7 +46,11 @@
|
|||||||
"list": "Impossible de récupérer la liste des races de bovins."
|
"list": "Impossible de récupérer la liste des races de bovins."
|
||||||
},
|
},
|
||||||
"carrier": {
|
"carrier": {
|
||||||
"list": "Impossible de récupérer la liste des transporteurs."
|
"list": "Impossible de récupérer la liste des transporteurs.",
|
||||||
|
"fetch": "Impossible de récupérer les données du transporteur",
|
||||||
|
"update": "Impossible de mettre à jour le transporteur",
|
||||||
|
"create": "Impossible de créer le transporteur"
|
||||||
|
|
||||||
},
|
},
|
||||||
"driver": {
|
"driver": {
|
||||||
"list": "Impossible de récupérer la liste des chauffeurs."
|
"list": "Impossible de récupérer la liste des chauffeurs."
|
||||||
@@ -67,6 +71,10 @@
|
|||||||
"auth": {
|
"auth": {
|
||||||
"login": "Connexion réussie.",
|
"login": "Connexion réussie.",
|
||||||
"logout": "Déconnexion réussie."
|
"logout": "Déconnexion réussie."
|
||||||
|
},
|
||||||
|
"carrier": {
|
||||||
|
"update": "Transporteur mis à jour",
|
||||||
|
"create": "Transporteur créé"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,18 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="grid grid-cols-[16rem,1fr] h-[calc(100vh-85px)] min-h-0">
|
<div class="grid grid-cols-[16rem,1fr] h-[calc(100vh-85px)] min-h-0">
|
||||||
<aside class="bg-primary-500 text-white min-h-0 grid grid-rows-[auto,1fr,auto]">
|
<aside class="bg-primary-500 text-white min-h-0 flex flex-col justify-between">
|
||||||
<div class="p-4 font-semibold">Tableau de bord</div>
|
<div class="flex flex-col gap-4 p-4 font-bold text-xl">
|
||||||
|
|
||||||
<div class="overflow-y-auto min-h-0 p-4 space-y-3">
|
|
||||||
<!-- Liste des liens à ajouter ci-dessous -->
|
<!-- Liste des liens à ajouter ci-dessous -->
|
||||||
|
<NuxtLink to="/admin/dashboard">
|
||||||
|
Tableau de bord
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/admin/supplier/supplier-list">
|
||||||
|
Fournisseur
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/admin/carrier/carrier-list">
|
||||||
|
Transporteur
|
||||||
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
|
|||||||
@@ -100,6 +100,9 @@
|
|||||||
<main class="mx-auto w-full max-w-[1280px] pb-0">
|
<main class="mx-auto w-full max-w-[1280px] pb-0">
|
||||||
<slot/>
|
<slot/>
|
||||||
</main>
|
</main>
|
||||||
|
<footer class="w-full mt-8 bg-primary-500 p-6">
|
||||||
|
<p class="font-bold text-white text-right">v{{ version }}</p>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -109,6 +112,7 @@ import { useAuthStore } from '~/stores/auth'
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
const isMenuOpen = ref(false)
|
const isMenuOpen = ref(false)
|
||||||
|
const { version } = useAppVersion()
|
||||||
|
|
||||||
const closeMenu = () => {
|
const closeMenu = () => {
|
||||||
isMenuOpen.value = false
|
isMenuOpen.value = false
|
||||||
|
|||||||
101
frontend/pages/admin/carrier/[[id]].vue
Normal file
101
frontend/pages/admin/carrier/[[id]].vue
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
<template>
|
||||||
|
<form @submit.prevent="validate">
|
||||||
|
<div class="flex items-center justify-between ">
|
||||||
|
<h1 class="text-3xl font-bold uppercase">
|
||||||
|
{{ route.params.id ? 'Modifier transporteur' : 'Ajout transporteur' }}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
|
||||||
|
>Enregistrer
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 items-start gap-y-8 gap-x-40 mb-16">
|
||||||
|
|
||||||
|
<UiTextInput
|
||||||
|
label = "nom du fournisseur"
|
||||||
|
id="carrier-name"
|
||||||
|
v-model="form.name"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UiTextInput
|
||||||
|
label = "code fournisseur"
|
||||||
|
id="code-id"
|
||||||
|
v-model="form.code"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {createCarrier, getCarrier, updateCarrier} from "~/services/carrier";
|
||||||
|
import type {CarrierData, CarrierFormData} from "~/services/dto/carrier-data";
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const idCarrier = Number(route.params.id)
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const isHydrating = ref(false)
|
||||||
|
|
||||||
|
const form = reactive<CarrierFormData>({
|
||||||
|
code:'',
|
||||||
|
name:''
|
||||||
|
})
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'admin'
|
||||||
|
})
|
||||||
|
|
||||||
|
const hydrateFromUser = (carrier: CarrierData | null) => {
|
||||||
|
if (!carrier) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isHydrating.value = true
|
||||||
|
form.name = carrier.name ?? ''
|
||||||
|
form.code = carrier.code ?? ''
|
||||||
|
isHydrating.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => idCarrier,
|
||||||
|
async (id) => {
|
||||||
|
if (id === null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isLoading.value = true
|
||||||
|
try {
|
||||||
|
const user = await getCarrier(id)
|
||||||
|
hydrateFromUser(user)
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{immediate: true}
|
||||||
|
)
|
||||||
|
async function validate() {
|
||||||
|
|
||||||
|
const normalizedCarrierCode = form.code.trim()
|
||||||
|
const normalizedCarrierName = form.name.trim()
|
||||||
|
|
||||||
|
const basePayload = {
|
||||||
|
name: normalizedCarrierName,
|
||||||
|
code: normalizedCarrierCode
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(idCarrier){
|
||||||
|
await updateCarrier(idCarrier, basePayload)
|
||||||
|
navigate()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await createCarrier(basePayload)
|
||||||
|
navigate()
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigate(){
|
||||||
|
router.push("/admin/carrier/carrier-list")
|
||||||
|
}
|
||||||
|
</script>
|
||||||
51
frontend/pages/admin/carrier/carrier-list.vue
Normal file
51
frontend/pages/admin/carrier/carrier-list.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between ">
|
||||||
|
<h1 class="text-3xl font-bold uppercase">listes des transporteurs</h1>
|
||||||
|
<NuxtLink
|
||||||
|
to="/admin/carrier"
|
||||||
|
class="flex items-center justify-center text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
|
>Ajouter
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-6 border border-slate-200 mb-16 ">
|
||||||
|
<div class="grid grid-cols-2 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide">
|
||||||
|
<div>Label</div>
|
||||||
|
<div>Code</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="carrier in carrierList"
|
||||||
|
:key="carrier.id"
|
||||||
|
class="grid grid-cols-2 gap-4 px-4 py-3 text-sm hover:bg-slate-50 cursor-pointer border-t border-slate-200"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
@click="goToCarrier(carrier.id)"
|
||||||
|
@keydown.enter="goToCarrier(carrier.id)"
|
||||||
|
>
|
||||||
|
<div>{{ carrier.name}}</div>
|
||||||
|
<div>{{ carrier.code }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type {CarrierData} from "~/services/dto/carrier-data";
|
||||||
|
import {getCarrierList} from "~/services/carrier";
|
||||||
|
|
||||||
|
const carrierList = ref<CarrierData[]>()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const goToCarrier = (id: number) => {
|
||||||
|
router.push(`/admin/carrier/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'admin'
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
carrierList.value = await getCarrierList(false)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
74
frontend/pages/admin/supplier/supplier-list.vue
Normal file
74
frontend/pages/admin/supplier/supplier-list.vue
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<h1 class="text-3xl font-bold uppercase"> Fournisseurs </h1>
|
||||||
|
<NuxtLink to="/admin/supplier"
|
||||||
|
class="flex items-center justify-center text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
|
>
|
||||||
|
Ajouter
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6 border border-slate-200 mb-16">
|
||||||
|
<div class="max-h-96 overflow-y-auto">
|
||||||
|
<div
|
||||||
|
class="sticky top-0 z-10 grid grid-cols-6 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide"
|
||||||
|
>
|
||||||
|
<div>Nom</div>
|
||||||
|
<div>Mail</div>
|
||||||
|
<div>Rue</div>
|
||||||
|
<div>Complément</div>
|
||||||
|
<div>Code Postal</div>
|
||||||
|
<div>Ville</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-for="supplier in supplierList" :key="supplier.id">
|
||||||
|
<template v-if="supplier.addresses?.length">
|
||||||
|
<div
|
||||||
|
v-for="addr in supplier.addresses"
|
||||||
|
:key="addr.id"
|
||||||
|
class="grid grid-cols-6 hover:bg-slate-50 border-t gap-4 px-4 py-2"
|
||||||
|
@click="goToSupplier(supplier.id)"
|
||||||
|
>
|
||||||
|
<div class="truncate">
|
||||||
|
{{ supplier.name }}
|
||||||
|
</div>
|
||||||
|
<div class="truncate">
|
||||||
|
{{ supplier.email }}
|
||||||
|
</div>
|
||||||
|
<div class="truncate">
|
||||||
|
{{ addr.street }}
|
||||||
|
</div>
|
||||||
|
<div class="truncate">
|
||||||
|
{{ addr.street2 }}
|
||||||
|
</div>
|
||||||
|
<div>{{ addr.postalCode }}</div>
|
||||||
|
<div class="uppercase truncate">
|
||||||
|
{{ addr.city }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type {SupplierData} from "~/services/dto/supplier-data"
|
||||||
|
import {getSupplierList} from "~/services/supplier"
|
||||||
|
|
||||||
|
definePageMeta({layout: "admin"})
|
||||||
|
|
||||||
|
const supplierList = ref<SupplierData[]>([])
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
|
||||||
|
const goToSupplier = (id: number) => {
|
||||||
|
router.push(`/admin/supplier/${id}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
supplierList.value = (await getSupplierList(false)) ?? []
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +46,8 @@
|
|||||||
>
|
>
|
||||||
Connexion
|
Connexion
|
||||||
</button>
|
</button>
|
||||||
</form>
|
<p class="font-bold">v{{ version }}</p>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ import { useAuthStore } from '~/stores/auth'
|
|||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
|
const { version } = useAppVersion()
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: 'auth'
|
layout: 'auth'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useApi } from '~/composables/useApi'
|
import { useApi } from '~/composables/useApi'
|
||||||
import type { CarrierData } from '~/services/dto/carrier-data'
|
import type {CarrierData, CarrierPayload} from "~/services/dto/carrier-data";
|
||||||
|
|
||||||
export type CarrierListResponse =
|
export type CarrierListResponse =
|
||||||
| CarrierData[]
|
| CarrierData[]
|
||||||
@@ -21,3 +21,26 @@ export async function getCarrierList(): Promise<CarrierData[]> {
|
|||||||
|
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getCarrier(id: number) {
|
||||||
|
const api = useApi()
|
||||||
|
return api.get<CarrierData>(`carriers/${id}`, {}, {
|
||||||
|
toastErrorKey: 'errors.carrier.fetch'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateCarrier(id: number, payload: CarrierPayload) {
|
||||||
|
const api = useApi()
|
||||||
|
return api.patch<CarrierData>(`carriers/${id}`, payload, {
|
||||||
|
toastErrorKey: 'errors.carrier.update',
|
||||||
|
toastSuccessKey: 'success.carrier.update'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createCarrier(payload: CarrierPayload = {}) {
|
||||||
|
const api = useApi()
|
||||||
|
return api.post<CarrierData>('carriers', payload, {
|
||||||
|
toastErrorKey: 'errors.carrier.create',
|
||||||
|
toastSuccessKey: 'success.carrier.update'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,3 +3,13 @@ export interface CarrierData {
|
|||||||
name: string
|
name: string
|
||||||
code: string
|
code: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CarrierFormData {
|
||||||
|
name: string
|
||||||
|
code: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CarrierPayload = {
|
||||||
|
name?: string | null
|
||||||
|
code?: string
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Dto;
|
namespace App\ApiResource;
|
||||||
|
|
||||||
use ApiPlatform\Metadata\ApiResource;
|
use ApiPlatform\Metadata\ApiResource;
|
||||||
use ApiPlatform\Metadata\Get;
|
use ApiPlatform\Metadata\Get;
|
||||||
@@ -17,7 +17,6 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
|||||||
provider: AppVersionProvider::class,
|
provider: AppVersionProvider::class,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
security: "is_granted('ROLE_USER')",
|
|
||||||
)]
|
)]
|
||||||
final class AppVersion
|
final class AppVersion
|
||||||
{
|
{
|
||||||
@@ -7,6 +7,8 @@ namespace App\Entity;
|
|||||||
use ApiPlatform\Metadata\ApiResource;
|
use ApiPlatform\Metadata\ApiResource;
|
||||||
use ApiPlatform\Metadata\Get;
|
use ApiPlatform\Metadata\Get;
|
||||||
use ApiPlatform\Metadata\GetCollection;
|
use ApiPlatform\Metadata\GetCollection;
|
||||||
|
use ApiPlatform\Metadata\Patch;
|
||||||
|
use ApiPlatform\Metadata\Post;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Attribute\Groups;
|
use Symfony\Component\Serializer\Attribute\Groups;
|
||||||
|
|
||||||
@@ -21,6 +23,15 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
|||||||
new GetCollection(
|
new GetCollection(
|
||||||
normalizationContext: ['groups' => ['carrier:read']],
|
normalizationContext: ['groups' => ['carrier:read']],
|
||||||
),
|
),
|
||||||
|
new Post(
|
||||||
|
normalizationContext: ['groups' => ['carrier:read']],
|
||||||
|
denormalizationContext: ['groups' => ['carrier:write']],
|
||||||
|
),
|
||||||
|
new Patch(
|
||||||
|
requirements: ['id' => '\d+'],
|
||||||
|
normalizationContext: ['groups' => ['carrier:read']],
|
||||||
|
denormalizationContext: ['groups' => ['carrier:write']],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
security: "is_granted('ROLE_USER')",
|
security: "is_granted('ROLE_USER')",
|
||||||
)]
|
)]
|
||||||
@@ -33,11 +44,11 @@ class Carrier
|
|||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 180)]
|
#[ORM\Column(length: 180)]
|
||||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read'])]
|
#[Groups(['carrier:read', 'carrier:write', 'driver:read', 'vehicle:read', 'reception:read'])]
|
||||||
private string $name = '';
|
private string $name = '';
|
||||||
|
|
||||||
#[ORM\Column(length: 30, nullable: true)]
|
#[ORM\Column(length: 30, nullable: true)]
|
||||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read'])]
|
#[Groups(['carrier:read', 'carrier:write', 'driver:read', 'vehicle:read', 'reception:read'])]
|
||||||
private ?string $code = null;
|
private ?string $code = null;
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace App\State;
|
|||||||
|
|
||||||
use ApiPlatform\Metadata\Operation;
|
use ApiPlatform\Metadata\Operation;
|
||||||
use ApiPlatform\State\ProviderInterface;
|
use ApiPlatform\State\ProviderInterface;
|
||||||
use App\Dto\AppVersion;
|
use App\ApiResource\AppVersion;
|
||||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
|
|
||||||
final readonly class AppVersionProvider implements ProviderInterface
|
final readonly class AppVersionProvider implements ProviderInterface
|
||||||
|
|||||||
Reference in New Issue
Block a user