Skip to content

Commit

Permalink
feat: ✨ add application patch feature
Browse files Browse the repository at this point in the history
  • Loading branch information
thomashbrnrd committed Dec 16, 2024
1 parent 613a555 commit 67c73ee
Show file tree
Hide file tree
Showing 17 changed files with 269 additions and 312 deletions.
2 changes: 1 addition & 1 deletion client/.env.development
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VITE_RDA_KEYCLOAK_AUTH_SERVER_URL=http://localhost:8082
VITE_RDA_KEYCLOAK_REALM=referentiel-applications
VITE_RDA_KEYCLOAK_CLIENT_ID=referentiel-applications
VITE_RDA_API_URL=http://localhost:8080
VITE_RDA_API_URL=http://localhost:3500
2 changes: 1 addition & 1 deletion client/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {};
export {}

/* prettier-ignore */
declare module 'vue' {
Expand Down
70 changes: 31 additions & 39 deletions client/src/components/ApplicationOverview.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script setup lang="ts">
import type { Application } from "@/models/Application";
import { ref } from "vue";
import Description from "./Description.vue";
import InformationsGenerales from "./InformationsGenerales.vue";
import Objectifs from "./Objectifs.vue";
import Tags from "./Tags.vue";
Expand All @@ -13,46 +12,39 @@ const activeTab = ref(0);
const tabListName = "Informations sur l’application";
const tabTitles = [
{ title: "Informations générales", icon: "ri-checkbox-circle-line", tabId: "tab-0", panelId: "tab-content-0" },
{ title: "Description", icon: "ri-checkbox-circle-line", tabId: "tab-1", panelId: "tab-content-1" },
{ title: "Objectifs", icon: "ri-checkbox-circle-line", tabId: "tab-2", panelId: "tab-content-2" },
{ title: "Tags", icon: "ri-checkbox-circle-line", tabId: "tab-3", panelId: "tab-content-3" },
{ title: "Objectifs", icon: "ri-checkbox-circle-line", tabId: "tab-1", panelId: "tab-content-2" },
{ title: "Tags", icon: "ri-checkbox-circle-line", tabId: "tab-2", panelId: "tab-content-3" },
];
</script>

<template>
<div class="fr-container fr-my-2w">
<!-- DsfrTabs pour les onglets avec gestion de l'onglet actif -->
<DsfrTabs v-model="activeTab" :tab-list-name="tabListName">
<!-- Définir chaque onglet via DsfrTabItem -->
<template #tab-items>
<DsfrTabItem
v-for="(tab, index) in tabTitles"
:key="tab.tabId"
:tab-id="tab.tabId"
:panel-id="tab.panelId"
:icon="tab.icon"
@click="activeTab = index"
>
{{ tab.title }}
</DsfrTabItem>
</template>

<!-- Contenu de chaque onglet -->
<DsfrTabContent v-if="activeTab === 0" panel-id="tab-content-0" tab-id="tab-0">
<InformationsGenerales :application="props.application" />
</DsfrTabContent>

<DsfrTabContent v-if="activeTab === 1" panel-id="tab-content-1" tab-id="tab-1">
<Description :application="props.application" />
</DsfrTabContent>

<DsfrTabContent v-if="activeTab === 2" panel-id="tab-content-2" tab-id="tab-2">
<Objectifs :application="props.application" />
</DsfrTabContent>

<DsfrTabContent v-if="activeTab === 3" panel-id="tab-content-3" tab-id="tab-3">
<Tags :application="props.application" />
</DsfrTabContent>
</DsfrTabs>
</div>
<!-- DsfrTabs pour les onglets avec gestion de l'onglet actif -->
<DsfrTabs v-model="activeTab" :tab-list-name="tabListName">
<!-- Définir chaque onglet via DsfrTabItem -->
<template #tab-items>
<DsfrTabItem
v-for="(tab, index) in tabTitles"
:key="tab.tabId"
:tab-id="tab.tabId"
:panel-id="tab.panelId"
:icon="tab.icon"
@click="activeTab = index"
>
{{ tab.title }}
</DsfrTabItem>
</template>

<!-- Contenu de chaque onglet -->
<DsfrTabContent v-if="activeTab === 0" panel-id="tab-content-0" tab-id="tab-0">
<InformationsGenerales :application="props.application" />
</DsfrTabContent>

<DsfrTabContent v-if="activeTab === 1" panel-id="tab-content-1" tab-id="tab-1">
<Objectifs :application="props.application" />
</DsfrTabContent>

<DsfrTabContent v-if="activeTab === 2" panel-id="tab-content-2" tab-id="tab-2">
<Tags :application="props.application" />
</DsfrTabContent>
</DsfrTabs>
</template>
14 changes: 0 additions & 14 deletions client/src/components/Description.vue

This file was deleted.

36 changes: 29 additions & 7 deletions client/src/components/InformationsGenerales.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
<script setup lang="ts">
import type { Application } from "@/models/Application";
import useToaster from "@/composables/use-toaster";
import axios from "axios";
const props = defineProps<{ application: Application }>();
const loading = ref(false);
const toaster = useToaster();
function patchApplication(event: Event) {
loading.value = true;
axios
.patch(`/applications/${props.application.id}`, {
label: props.application.label,
shortName: props.application.shortName,
description: props.application.description,
})
.then(() => {
toaster.addSuccessMessage("Application mise à jour avec succès");
})
.catch((error) => {
toaster.addErrorMessage("Erreur lors de la mise à jour de l'application");
})
.finally(() => {
loading.value = false;
});
}
</script>

<template>
<div>
<h3>Informations générales</h3>
<p><strong>Identifiant unique :</strong> {{ application.id }}</p>
<p><strong>Nom court :</strong> {{ application.label }}</p>
<p><strong>Nom abrégé :</strong> {{ application.shortName }}</p>
<p><strong>Logo :</strong> {{ application.logo }}</p>
</div>
<h3>Informations générales</h3>
<div class="fr-mb-3w"><DsfrInput v-model="application.id" label="Identifiant unique" label-visible disabled /></div>
<div class="fr-mb-3w"><DsfrInput v-model="application.label" label="Nom" label-visible required /></div>
<div class="fr-mb-3w"><DsfrInput v-model="application.shortName" label="Nom abrégé" label-visible required /></div>
<div class="fr-mb-3w"><DsfrInput v-model="application.description" label="Description" label-visible required isTextarea /></div>
<DsfrButton label="Sauvegarder" primary @click="patchApplication" />
</template>
2 changes: 1 addition & 1 deletion client/src/components/SearchApplications.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async function doSearch() {
isLoading.value = true;
errorMessage.value = "";
const results = await Applications.getAllApplicationBySearch(searchTerm.value || "");
searchResults.value = results?.collection || [];
searchResults.value = results || [];
} catch (error) {
errorMessage.value = "Une erreur est survenue lors du chargement des applications.";
} finally {
Expand Down
1 change: 1 addition & 0 deletions client/src/models/Application.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface Application {
id: string;
label: string;
shortName?: string;
description?: string;
organisationCode?: string;
createdAt: string;
Expand Down
15 changes: 13 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ services:
- ALLOWED_ORIGINS=http://localhost:5173,http://localhost:8080,http://krakend:8080
- KEYCLOAK_BASE_URL=http://localhost:8082
- KEYCLOAK_REALM=referentiel-applications
# To be deleted
- KEYCLOAK_CLIENT_SECRET="client secret"
depends_on:
- postgres
ports:
Expand All @@ -34,6 +32,19 @@ services:
- ./server:/app
- /app/node_modules

prisma-studio:
build:
context: ./server
command: npx prisma studio
environment:
- DATABASE_URL=postgresql://postgres:password@postgres:5432/postgres
- ALLOWED_ORIGINS=http://localhost:5173,http://localhost:8080,http://krakend:8080
- KEYCLOAK_BASE_URL=http://localhost:8082
depends_on:
- postgres
ports:
- "5555:5555"

keycloak:
build:
context: ./keycloak
Expand Down
50 changes: 39 additions & 11 deletions krakend.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@
"name": "krakend",
"extra_config": {
"security/cors": {
"allow_origins": ["http://localhost:5173"],
"allow_methods": ["GET", "HEAD", "POST", "OPTIONS"],
"allow_origins": ["http://localhost:5173", "http://localhost:8080"],
"allow_methods": [
"GET",
"HEAD",
"POST",
"OPTIONS",
"PUT",
"PATCH",
"DELETE"
],
"expose_headers": ["Content-Length", "Content-Type"],
"allow_headers": [
"Accept-Language",
"X-User-Id",
"X-User-Email",
"Authorization",
"Content-Type"
"Content-Type",
"Origin"
],
"max_age": "12h",
"allow_credentials": true,
Expand Down Expand Up @@ -49,27 +58,46 @@
]
},
{
"endpoint": "api/v2/{ressource}",
"output_encoding": "no-op",
"endpoint": "api/v2/applications",
"method": "POST",
"backend": [
{
"encoding": "no-op",
"host": ["http://backend:3500"],
"url_pattern": "api/v2/{ressource}"
"url_pattern": "api/v2/applications",
"method": "POST"
}
],
"output_encoding": "no-op",
"input_headers": [
"Authorization",
"X-User",
"X-Role",
"ClientId",
"X-Requested-With",
"Content-Type",
"Content-Length"
]
},
{
"endpoint": "api/v2/applications",
"method": "POST",
"endpoint": "api/v2/applications/{id}",
"method": "PATCH",
"backend": [
{
"host": ["http://backend:3500"],
"url_pattern": "api/v2/applications",
"method": "POST"
"method": "PATCH"
}
],
"output_encoding": "no-op"
"output_encoding": "no-op",
"input_headers": [
"Authorization",
"X-User",
"X-Role",
"ClientId",
"X-Requested-With",
"Content-Type",
"Content-Length"
]
},
{
"endpoint": "api/v2/applications/search",
Expand Down
3 changes: 2 additions & 1 deletion server/nest-cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
"deleteOutDir": true,
"plugins": ["@nestjs/swagger"]
}
}
1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"jwks-rsa": "^3.1.0",
"lodash-es": "^4.17.21",
"moment": "^2.30.1",
"nestjs-prisma": "^0.23.0",
"passport": "^0.6.0",
"passport-jwt": "^4.0.1",
"pg": "^8.11.3",
Expand Down
Loading

0 comments on commit 67c73ee

Please sign in to comment.