@@ -149,7 +135,7 @@ watch(
initializeStateFromNotification(newNotification);
}
},
- { immediate: true }
+ { immediate: true },
);
const handleDeleteNotification = async () => {
diff --git a/src/composables/time.js b/src/composables/time.js
new file mode 100644
index 000000000..8a39696c0
--- /dev/null
+++ b/src/composables/time.js
@@ -0,0 +1,21 @@
+import { useI18n } from "vue-i18n";
+
+export function useTimeAgo() {
+ const { t } = useI18n();
+
+ const formatTimeAgo = (dateObj) => {
+ const diff = Math.floor((Date.now() - dateObj) / 1000);
+
+ if (diff < 60) return t("t.just_now");
+ if (diff < 3600) {
+ return t("t.minutes_ago", { count: Math.floor(diff / 60) });
+ }
+ if (diff < 86400) {
+ return t("t.hours_ago", { count: Math.floor(diff / 3600) });
+ }
+
+ return t("t.days_ago", { count: Math.floor(diff / 86400) });
+ };
+
+ return { formatTimeAgo };
+}
diff --git a/src/i18n/lang/fr.json b/src/i18n/lang/fr.json
index b3128d827..f23dc5d23 100644
--- a/src/i18n/lang/fr.json
+++ b/src/i18n/lang/fr.json
@@ -12,6 +12,7 @@
"createdBy": "Créé par",
"close": "Fermer",
"date": "Date",
+ "days_ago": "il y a {count} jour | il y a {count} jours",
"delete": "Supprimer",
"description": "Description",
"download": "Télécharger",
@@ -25,10 +26,13 @@
"exportXlsx": "Exporter en Excel",
"file": "Fichier",
"folder": "Dossier",
+ "hours_ago": "il y a {count} heure | il y a {count} heures",
"import": "Importer",
"invalidName": "Nom invalide",
+ "just_now": "À l'instant",
"leave": "Quitter",
"location": "Emplacement",
+ "minutes_ago": "il y a {count} minute | il y a {count} minutes",
"modifiedOn": "Modifié le",
"modify": "Modifier",
"name": "Nom",
@@ -47,12 +51,14 @@
"spaces": "Espaces",
"status": "Statut",
"success": "Succès",
+ "today": "Aujourd’hui",
"type": "Type",
"unarchive": "Désarchiver",
"validate": "Valider",
"validation": "Validations",
"validator": "Validants",
- "verify": "Vérifier"
+ "verify": "Vérifier",
+ "yesterday": "Hier"
},
"OidcCallbackError": {
"message": "Une erreur s'est produite lors de l'authentification...",
@@ -80,12 +86,76 @@
"groupsButtonText": "Gestion des groupes"
},
"ProjectOverview": {
+ "title": "",
"openFileUploadButtonText": "Ajouter un modèle",
"forbiddenUploadNotification": "Veuillez sélectionner un fichier de modèle: {extensions}",
"uploadDisableMessage": {
"permission": "Vous n'avez pas les droits requis",
"size": "Vous ne disposez plus assez d'espace de stockage"
},
+ "historyActivityTab": "Historique d'activité",
+ "notificationSettingsTab": "Notifications mail",
+ "activity": {
+ "title": "Activité récente",
+ "folderTitle": "Dossier :",
+ "roleTitle": "Rôle :",
+ "newPermissionTitle": "Nouveaux droits :",
+ "oldPermissionTitle": "Anciens droits :",
+ "oldNameTitle": "Ancien nom :",
+ "newNameTitle": "Nouveau nom :",
+ "document_created": "Dépôt du fichier :",
+ "document_deleted": "Suppression du fichier :",
+ "document_renamed": "Renommage du fichier :",
+ "document_moved": "Déplacement du fichier :",
+
+ "folder_created": "Création du dossier :",
+ "folder_deleted": "Suppression du dossier :",
+ "folder_permissions_updated": "Modification des permissions du dossier :",
+ "folder_renamed": "Renommage du dossier :",
+ "folder_moved": "Déplacement du dossier :",
+
+ "cloud_invitation_sent": "Invitation envoyée à :",
+ "cloud_invitation_canceled": "Invitation annulée pour :",
+ "cloud_invitation_accepted": "Invitation acceptée par :",
+ "cloud_invitation_denied": "Invitation refusée par :",
+
+ "project_invitation_sent": "Invitation projet envoyée à :",
+ "project_invitation_canceled": "Invitation projet annulée pour :",
+ "project_invitation_accepted": "Invitation projet acceptée par :",
+ "project_invitation_denied": "Invitation projet refusée par :",
+ "roles": {
+ "admin": "Administrateur",
+ "user": "Utilisateur",
+ "guest": "Invité"
+ },
+ "permissions": {
+ "default": "Par défaut",
+ "accessDenied": "Accès refusé",
+ "readOnly": "Lecture seule",
+ "readWrite": "Lecture / Écriture"
+ },
+ "badge": {
+ "document_created": "Dépôt du fichier ",
+ "document_deleted": "Suppression du fichier ",
+ "document_renamed": "Renommage du fichier ",
+ "document_moved": "Déplacement du fichier ",
+ "folder_created": "Création du dossier ",
+ "folder_deleted": "Suppression du dossier ",
+ "folder_permissions_updated": "Modification des droits d’accès",
+ "folder_renamed": "Renommage du dossier",
+ "folder_moved": "Déplacement du dossier",
+
+ "cloud_invitation_sent": "Invitation envoyée",
+ "cloud_invitation_canceled": "Invitation annulée",
+ "cloud_invitation_accepted": "Invitation acceptée",
+ "cloud_invitation_denied": "Invitation refusée",
+
+ "project_invitation_sent": "Invitation projet envoyée",
+ "project_invitation_canceled": "Invitation projet annulée",
+ "project_invitation_accepted": "Invitation projet acceptée",
+ "project_invitation_denied": "Invitation projet refusée"
+ }
+ },
"notifications": {
"title": "Paramètres notification mail",
"headerText": "Les paramètres projet de BIMData permettent de gérer les types et la fréquence des notifications pour un suivi personnalisé.",
@@ -462,6 +532,7 @@
"title": "Gestion des membres du groupe"
},
"Errors": {
+ "logsFetchError": "Impossible de récupérer les logs du projet",
"spacesFetchError": "Impossible de récupérer la liste des espaces",
"spaceCreateError": "Erreur lors de la création de l'espace",
"spaceUpdateError": "Erreur de mise à jour de l'espace",
@@ -989,4 +1060,4 @@
"title": "Suppression de {visasCount} visas",
"message": "Vous êtes sur le point de supprimer les visas sur les fichiers suivants :"
}
-}
\ No newline at end of file
+}
diff --git a/src/main.js b/src/main.js
index 605555052..1a68d5ba9 100644
--- a/src/main.js
+++ b/src/main.js
@@ -11,7 +11,6 @@ import ErrorService from "./services/ErrorService.js";
import App from "./App.vue";
-
const app = createApp(App)
.use(i18n)
.use(router)
@@ -25,7 +24,7 @@ for (const [name, component] of Object.entries(globalComponents)) {
}
// Setup global error handler
-app.config.errorHandler = error => {
+app.config.errorHandler = (error) => {
ErrorService.handleError(error);
};
diff --git a/src/services/ErrorService.js b/src/services/ErrorService.js
index 2898841d5..811667e99 100644
--- a/src/services/ErrorService.js
+++ b/src/services/ErrorService.js
@@ -2,6 +2,7 @@ import { useAppNotification } from "../components/specific/app/app-notification/
import i18n from "../i18n/index.js";
const ERRORS = Object.freeze({
+ LOGS_FETCH_ERROR: "logsFetchError",
ORGANIZATIONS_FETCH_ERROR: "organizationsFetchError",
ORGANIZATION_CREATE_ERROR: "organizationCreateError",
ORGANIZATION_UPDATE_ERROR: "organizationUpdateError",
@@ -85,7 +86,7 @@ const ERRORS = Object.freeze({
DATAPACK_UPDATE_ERROR: "datapackUpdateError",
BCF_IMPORT_ERROR: "bcfImportError",
BCF_EXPORT_ERROR: "bcfExportError",
- BCF_DELETE_ERROR: "bcfDeleteError"
+ BCF_DELETE_ERROR: "bcfDeleteError",
});
class RuntimeError {
@@ -112,7 +113,7 @@ class ErrorService {
this.notify({
type: "error",
title: this.t("t.error"),
- message: this.t(`Errors.${errorId}`)
+ message: this.t(`Errors.${errorId}`),
});
}
}
diff --git a/src/services/ProjectService.js b/src/services/ProjectService.js
index 6ba61d478..9562c60f1 100644
--- a/src/services/ProjectService.js
+++ b/src/services/ProjectService.js
@@ -110,7 +110,7 @@ class ProjectService {
return await apiClient.collaborationApi.cancelProjectUserInvitation(
project.cloud.id,
invitation.id,
- project.id
+ project.id,
);
} catch (error) {
throw new RuntimeError(ERRORS.INVITATION_CANCEL_ERROR, error);
@@ -123,7 +123,7 @@ class ProjectService {
project.cloud.id,
user.id,
project.id,
- { role: user.role }
+ { role: user.role },
);
} catch (error) {
throw new RuntimeError(ERRORS.USER_UPDATE_ERROR, error);
@@ -135,7 +135,7 @@ class ProjectService {
return await apiClient.collaborationApi.deleteProjectUser(
project.cloud.id,
user.id,
- project.id
+ project.id,
);
} catch (error) {
throw new RuntimeError(ERRORS.USER_DELETE_ERROR, error);
@@ -155,7 +155,7 @@ class ProjectService {
return await apiClient.collaborationApi.getFolderProjectUsers(
project.cloud.id,
folder.id,
- project.id
+ project.id,
);
} catch (error) {
throw new RuntimeError(ERRORS.USERS_PROJECT_FETCH_ERROR, error);
@@ -175,7 +175,7 @@ class ProjectService {
try {
res = await backendClient.get(`/cloud/${spaceId}/project/${projectId}/notification`);
} catch (error) {
- if(error.status === 404) {
+ if (error.status === 404) {
res = null; // No notification found
} else {
console.error("Error fetching project notification:", error);
@@ -191,6 +191,14 @@ class ProjectService {
deleteProjectNotification(spaceId, projectId) {
return backendClient.delete(`/cloud/${spaceId}/project/${projectId}/notification`);
}
+
+ async fetchLogs(project) {
+ try {
+ return await apiClient.collaborationApi.getLogs(project.cloud.id, project.id);
+ } catch (error) {
+ throw new RuntimeError(ERRORS.LOGS_FETCH_ERROR, error);
+ }
+ }
}
const service = new ProjectService();
diff --git a/src/state/projects.js b/src/state/projects.js
index c4cda543e..f8d50b3d2 100644
--- a/src/state/projects.js
+++ b/src/state/projects.js
@@ -25,7 +25,7 @@ const setCurrentProject = (id) => {
return readonly(state.currentProject);
};
-const loadUserProjects = async options => {
+const loadUserProjects = async (options) => {
const projects = await ProjectService.fetchUserProjects(options);
state.userProjects = sortProjects(projects);
@@ -80,7 +80,7 @@ const updateProject = async (project) => {
state.currentProject = newProject;
}
- let i = state.userProjects.findIndex(p => p.id === newProject.id);
+ let i = state.userProjects.findIndex((p) => p.id === newProject.id);
state.userProjects.splice(i, 1, newProject);
state.spaceProjects.splice(i, 1, newProject);
@@ -90,7 +90,7 @@ const updateProject = async (project) => {
const deleteProject = async (project) => {
await ProjectService.deleteProject(project);
- let i = state.userProjects.findIndex(p => p.id === project.id);
+ let i = state.userProjects.findIndex((p) => p.id === project.id);
state.userProjects.splice(i, 1);
state.spaceProjects.splice(i, 1);
state.projectsCount[project.cloud.id] -= 1;
@@ -101,7 +101,7 @@ const deleteProject = async (project) => {
const leaveProject = async (project) => {
await ProjectService.leaveProject(project);
- let i = state.userProjects.findIndex(p => p.id === project.id);
+ let i = state.userProjects.findIndex((p) => p.id === project.id);
state.userProjects.splice(i, 1);
state.spaceProjects.splice(i, 1);
state.projectsCount[project.cloud.id] -= 1;
@@ -140,19 +140,23 @@ const getUserProjectList = async (project, folder) => {
users = sortUsers(users).filter((user) => !isSelf(user));
return users.map((user) => ({
- ...user,
- fullName: fullName(user),
- hasAccess: user.permission >= 50,
- isFindable: true,
- searchContent:
- `${user.firstname || ""} ${user.lastname || ""} ${user.email || ""}`.toLowerCase(),
- }));
+ ...user,
+ fullName: fullName(user),
+ hasAccess: user.permission >= 50,
+ isFindable: true,
+ searchContent:
+ `${user.firstname || ""} ${user.lastname || ""} ${user.email || ""}`.toLowerCase(),
+ }));
};
const getProjectFolderTree = async (project) => {
return ProjectService.getProjectFolderTree(project);
};
+const fetchLogs = async (project) => {
+ return ProjectService.fetchLogs(project);
+};
+
const fetchProjectNotification = async (spaceId, projectId) => {
try {
const res = await ProjectService.fetchProjectNotification(spaceId, projectId);
@@ -203,6 +207,6 @@ export function useProjects() {
getProjectFolderTree,
fetchProjectNotification,
updateProjectNotification,
- deleteProjectNotification
+ deleteProjectNotification,
};
}
diff --git a/src/views/project-board/ProjectBoard.scss b/src/views/project-board/ProjectBoard.scss
index 98cfef374..b8cec4ac0 100644
--- a/src/views/project-board/ProjectBoard.scss
+++ b/src/views/project-board/ProjectBoard.scss
@@ -21,16 +21,6 @@
gap: var(--spacing-unit);
}
- &:deep() {
- .bimdata-tabs__container__tab.active {
- background-color: rgba(47, 55, 74, 0.1);
- }
-
- .bimdata-tabs__container__tab:hover {
- background-color: rgba(47, 55, 74, 0.03);
- }
- }
-
.beta-badge {
height: 18px;
margin-left: 6px;
diff --git a/src/views/project-board/ProjectBoard.vue b/src/views/project-board/ProjectBoard.vue
index c78009478..24529bd07 100644
--- a/src/views/project-board/ProjectBoard.vue
+++ b/src/views/project-board/ProjectBoard.vue
@@ -15,12 +15,10 @@
:tabs="tabs"
:selected="currentTab.id"
@tab-click="changeView($event.id)"
+ :dark="false"
>
-
+