Compare commits

..

No commits in common. "820c979c94ac16d5979ee7d746c24ab87be3d4cf" and "c3dded1e0571bc1eac28cdf9f02145481e8e288d" have entirely different histories.

9 changed files with 77 additions and 103 deletions

View File

@ -95,7 +95,7 @@ const props = defineProps<{
title: number; title: number;
titleText: string; titleText: string;
description: string; description: string;
isAdmin: boolean; isAdmin: number;
}>(); }>();
const IS_MOCK_MODE = false; const IS_MOCK_MODE = false;
@ -109,21 +109,16 @@ const isEditing = ref<boolean[]>([]);
function getCurrentFormattedDate(): string { function getCurrentFormattedDate(): string {
const now = new Date(); const now = new Date();
const year = now.getFullYear(); const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0"); // +1 car janvier = 0 const month = String(now.getMonth() + 1).padStart(2, '0'); // +1 car janvier = 0
const day = String(now.getDate()).padStart(2, "0"); const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, "0"); const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, "0"); const minutes = String(now.getMinutes()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}`; return `${year}-${month}-${day} ${hours}:${minutes}`;
} }
onMounted(() => { onMounted(() => {
fetchData( fetchData(props.projectId, props.title, getCurrentFormattedDate(), IS_MOCK_MODE);
props.projectId,
props.title,
getCurrentFormattedDate(),
IS_MOCK_MODE
);
}); });
// Fonctions // Fonctions
@ -143,13 +138,9 @@ const saveEdit = (index: number) => {
isEditing.value[index] = false; isEditing.value[index] = false;
if (!IS_MOCK_MODE){ if (!IS_MOCK_MODE){
addSectionCell( addSectionCell(currentDescriptions.value[index],
currentDescriptions.value[index],
(response) => { (response) => {
console.log( console.log("Modification enregistrée avec succès :", response.data);
"Modification enregistrée avec succès :",
response.data
);
}, },
(error) => { (error) => {
console.error("Erreur lors de l'enregistrement :", error); console.error("Erreur lors de l'enregistrement :", error);
@ -158,6 +149,7 @@ const saveEdit = (index: number) => {
} }
}; };
const handleClick = () => { const handleClick = () => {
if (expanded.value) { if (expanded.value) {
const editingInProgress = isEditing.value.some((edit) => edit); const editingInProgress = isEditing.value.some((edit) => edit);
@ -173,13 +165,11 @@ const handleClick = () => {
const handleFetchSuccess = (sectionCells: SectionCell[]) => { const handleFetchSuccess = (sectionCells: SectionCell[]) => {
currentDescriptions.value = sectionCells; currentDescriptions.value = sectionCells;
editedDescriptions.value = sectionCells.map( editedDescriptions.value = sectionCells.map(
(cell) => (cell) => new SectionCell({
new SectionCell({
idSectionCell: cell.idSectionCell, idSectionCell: cell.idSectionCell,
sectionId: cell.sectionId, sectionId: cell.sectionId,
contentSectionCell: cell.contentSectionCell, contentSectionCell: cell.contentSectionCell,
modificationDate: cell.modificationDate, modificationDate: cell.modificationDate, })
})
); );
isEditing.value = Array(sectionCells.length).fill(false); isEditing.value = Array(sectionCells.length).fill(false);
}; };
@ -188,43 +178,28 @@ const handleFetchError = (error: unknown) => {
console.error("Erreur lors de la récupération des données :", error); console.error("Erreur lors de la récupération des données :", error);
}; };
const fetchData = async ( const fetchData = async ( projectId: number, title: number, date: string, useMock = false ) => {
projectId: number,
title: number,
date: string,
useMock = false
) => {
try { try {
if (useMock) { if (useMock) {
const responseData = await mockFetch(projectId, title, date); const responseData = await mockFetch(projectId, title, date);
handleFetchSuccess(responseData); handleFetchSuccess(responseData);
} else { } else {
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
getSectionCellsByDate( getSectionCellsByDate( projectId, title, date,
projectId,
title,
date,
(response: AxiosResponse) => { (response: AxiosResponse) => {
const data = response.data; const data = response.data;
if (Array.isArray(data) && data.length > 0) { if (Array.isArray(data) && data.length > 0) {
const sectionCells = data.map( const sectionCells = data.map((cellData) => new SectionCell({
(cellData) =>
new SectionCell({
idSectionCell: cellData.idSectionCell, idSectionCell: cellData.idSectionCell,
sectionId: cellData.sectionId, sectionId: cellData.sectionId,
contentSectionCell: contentSectionCell: cellData.contentSectionCell,
cellData.contentSectionCell,
modificationDate: modificationDate:
cellData.modificationDate, cellData.modificationDate, })
})
); );
handleFetchSuccess(sectionCells); handleFetchSuccess(sectionCells);
} else { } else {
console.warn( console.warn( "Aucune donnée reçue ou format inattendu :", data);
"Aucune donnée reçue ou format inattendu :",
data
);
} }
resolve(); resolve();
@ -241,11 +216,7 @@ const fetchData = async (
} }
}; };
const mockFetch = async ( const mockFetch = async ( projectId: number, title: number, date: string ): Promise<SectionCell[]> => {
projectId: number,
title: number,
date: string
): Promise<SectionCell[]> => {
console.log( console.log(
`Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}` `Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}`
); );
@ -301,13 +272,8 @@ const mockFetch = async (
// On crée des instances de SectionCell // On crée des instances de SectionCell
const result = section.map( const result = section.map(
(txt, index) => (txt, index) => new SectionCell({ idSectionCell: index + 1, sectionId: title,
new SectionCell({ contentSectionCell: txt, modificationDate: date, })
idSectionCell: index + 1,
sectionId: title,
contentSectionCell: txt,
modificationDate: date,
})
); );
return new Promise<SectionCell[]>((resolve) => { return new Promise<SectionCell[]>((resolve) => {

View File

@ -18,7 +18,7 @@ import { ref } from "vue";
import CanvasItem from "@/components/canvas/CanvasItem.vue"; import CanvasItem from "@/components/canvas/CanvasItem.vue";
const props = defineProps<{ const props = defineProps<{
isAdmin: boolean; isAdmin: number;
}>(); }>();
const items = ref([ const items = ref([

View File

@ -5,6 +5,7 @@ import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
import keycloakService from "./services/keycloak"; import keycloakService from "./services/keycloak";
import { type AuthStore, useAuthStore } from "@/stores/authStore.ts"; import { type AuthStore, useAuthStore } from "@/stores/authStore.ts";
import { jwtDecode } from "jwt-decode";
let store: AuthStore; let store: AuthStore;
@ -28,6 +29,30 @@ keycloakService.CallInit(() => {
} }
}); });
type TokenPayload = {
realm_access?: {
roles?: string[];
};
};
function isAdmin(): boolean{
if (store.authenticated && store.user.token) {
const decoded = jwtDecode<TokenPayload>(store.user.token);
const roles = decoded.realm_access?.roles || [];
if (roles.includes("MyINPulse-admin")) {
return true;
} else {
return false;
}
} else {
return false;
}
}
// this shit made by me so i can run the canva vue app // this shit made by me so i can run the canva vue app
//createApp(App).use(router).mount('#app'); //createApp(App).use(router).mount('#app');

View File

@ -1,11 +1,7 @@
import { type AxiosError, type AxiosResponse } from "axios"; import { type AxiosError, type AxiosResponse } from "axios";
import Project from "@/ApiClasses/Project"; import Project from "@/ApiClasses/Project";
import Report from "@/ApiClasses/Repport"; import Report from "@/ApiClasses/Repport";
import { import { axiosInstance, defaultApiErrorHandler, defaultApiSuccessHandler } from "@/services/api"
axiosInstance,
defaultApiErrorHandler,
defaultApiSuccessHandler,
} from "@/services/api";
// Admin API // Admin API
function getPendingAccounts( function getPendingAccounts(

View File

@ -1,10 +1,6 @@
import Project from "@/ApiClasses/Project"; import Project from "@/ApiClasses/Project";
import SectionCell from "@/ApiClasses/SectionCell"; import SectionCell from "@/ApiClasses/SectionCell";
import { import { axiosInstance, defaultApiErrorHandler, defaultApiSuccessHandler } from "@/services/api"
axiosInstance,
defaultApiErrorHandler,
defaultApiSuccessHandler,
} from "@/services/api";
axiosInstance.interceptors.response.use( axiosInstance.interceptors.response.use(
(response) => response, // Directly return successful responses. (response) => response, // Directly return successful responses.

View File

@ -1,10 +1,7 @@
import { type AxiosError, type AxiosResponse } from "axios"; import { type AxiosError, type AxiosResponse } from "axios";
import Appointment from "@/ApiClasses/Appointment"; import Appointment from "@/ApiClasses/Appointment";
import { import { axiosInstance, defaultApiErrorHandler, defaultApiSuccessHandler } from "@/services/api"
axiosInstance,
defaultApiErrorHandler,
defaultApiSuccessHandler,
} from "@/services/api";
// Shared API // Shared API
function getSectionCellsByDate( function getSectionCellsByDate(

View File

@ -1,10 +1,7 @@
import { type AxiosError, type AxiosResponse } from "axios"; import { type AxiosError, type AxiosResponse } from "axios";
import { import { axiosInstance, defaultApiErrorHandler, defaultApiSuccessHandler } from "@/services/api"
axiosInstance,
defaultApiErrorHandler,
defaultApiSuccessHandler,
} from "@/services/api";
// Unauth API // Unauth API
function finalizeAccount( function finalizeAccount(
@ -52,6 +49,7 @@ function finalizeAccount(
// }); // });
// } // }
export { export {
finalizeAccount, finalizeAccount,
// requestJoinProject, // Not yet implemented [cite: 4] // requestJoinProject, // Not yet implemented [cite: 4]

View File

@ -43,7 +43,8 @@ axiosInstance.interceptors.response.use(
// TODO: spawn a error modal // TODO: spawn a error modal
function defaultApiErrorHandler(err: AxiosError) { function defaultApiErrorHandler(err: AxiosError) {
const errorMessage = const errorMessage =
(err.response?.data as { message?: string })?.message ?? err.message; (err.response?.data as { message?: string })?.message ??
err.message;
addNewMessage(errorMessage, color.Red); addNewMessage(errorMessage, color.Red);
} }
@ -93,11 +94,4 @@ function deleteApi(
//export { axiosInstance, callApi, postApi, deleteApi }; //export { axiosInstance, callApi, postApi, deleteApi };
export { export{ axiosInstance, defaultApiErrorHandler, defaultApiSuccessHandler, callApi, postApi, deleteApi }
axiosInstance,
defaultApiErrorHandler,
defaultApiSuccessHandler,
callApi,
postApi,
deleteApi,
};

View File

@ -10,7 +10,7 @@
Cliquez sur un champ du tableau pour afficher son contenu en détail Cliquez sur un champ du tableau pour afficher son contenu en détail
ci-dessous. ci-dessous.
</p> </p>
<LeanCanvas :is-admin="isAdmin_" /> <LeanCanvas :is-admin="isAdmin" />
<div class="info-box"> <div class="info-box">
<p> <p>
Responsable : Responsable :
@ -35,18 +35,20 @@ import HeaderCanvas from "../components/canvas/HeaderCanvas.vue";
import LeanCanvas from "../components/canvas/LeanCanvas.vue"; import LeanCanvas from "../components/canvas/LeanCanvas.vue";
import { ref, onMounted /*, defineProps*/ } from "vue"; import { ref, onMounted /*, defineProps*/ } from "vue";
import { axiosInstance } from "@/services/api.ts"; import { axiosInstance } from "@/services/api.ts";
import { isAdmin } from "@/services/tools.ts";
const IS_MOCK_MODE = true; const IS_MOCK_MODE = true;
/* /*
const props = defineProps<{ const props = defineProps<{
projectId: number; projectId: number;
token: TokenPayload;
}>(); }>();
const projectId = props.projectId;
is_admin = token.includes("MyINPulse-admin")
*/ */
const isAdmin_: boolean = isAdmin(); const isAdmin = 0;
// Variables pour les informations de l'administrateur // Variables pour les informations de l'administrateur
const admin = ref({ const admin = ref({