diff --git a/appinfo/info.xml b/appinfo/info.xml index 360fca2c7..1da127464 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -25,6 +25,10 @@ Create Groupfolders with delegated management + + + + '/', 'verb' => 'GET', ], + [ + 'name' => 'connectedGroup#addConnectedGroup', + 'url' => '/spaces/{spaceId}/connected-group', + 'verb' => 'POST' + ], + [ + 'name' => 'connectedGroup#getConnectedGroupsFromSpaceId', + 'url' => '/spaces/{spaceId}/connected-group', + 'verb' => 'GET' + ], + [ + 'name' => 'connectedGroup#getConnectedGroups', + 'url' => '/connected-group', + 'verb' => 'GET' + ], [ 'name' => 'workspace#addGroupsInfo', 'url' => '/api/workspace/formatGroups', @@ -77,6 +92,16 @@ 'url' => '/workspaces', 'verb' => 'GET' ], + [ + 'name' => 'connectedGroup#addGroup', + 'url' => '/spaces/{spaceId}/connected-groups/{gid}', + 'verb' => 'POST', + ], + [ + 'name' => 'connectedGroup#removeGroup', + 'url' => '/spaces/{spaceId}/connected-groups/{gid}', + 'verb' => 'DELETE' + ], [ 'name' => 'workspace#findAll', 'url' => '/spaces', @@ -117,6 +142,11 @@ 'url' => '/api/group/{gid}', 'verb' => 'PATCH', ], + [ + 'name' => 'group#search', + 'url' => '/groups', + 'verb' => 'GET', + ], [ 'name' => 'group#addUser', /** @@ -147,6 +177,11 @@ 'url' => '/api/group/delUser/{spaceId}', 'verb' => 'PATCH', ], + [ + 'name' => 'workspace#getUsers', + 'url' => '/spaces/{spaceId}/users', + 'verb' => 'GET', + ], [ 'name' => 'group#removeUserFromWorkspace', 'url' => '/spaces/{spaceId}/users/{user}/groups', diff --git a/css/workspace-style.css b/css/workspace-style.css index cc269767c..a1d2e6eea 100644 --- a/css/workspace-style.css +++ b/css/workspace-style.css @@ -92,3 +92,9 @@ .workspace-sidebar .icon-collapse { visibility: visible !important; } + +.icon-added-group, .icon-added-group-dark { + background-image: url('../img/added_group_black.svg'); + min-width: 42px; + min-height: 42px; +} diff --git a/img/added_group_black.svg b/img/added_group_black.svg new file mode 100644 index 000000000..267d7cfca --- /dev/null +++ b/img/added_group_black.svg @@ -0,0 +1,9 @@ + + + Added Group + + + + + + diff --git a/l10n/cs.js b/l10n/cs.js index d95022a80..f5f9f9516 100644 --- a/l10n/cs.js +++ b/l10n/cs.js @@ -5,11 +5,11 @@ OC.L10N.register( 'Are you sure you want to delete the {space} workspace ?': 'Opravdu chcete prostor {space} smazat?', 'Add users': 'Přidat uživatele', 'All spaces': 'Všechny prac. prostory', - 'admin': 'Správce prac. prostour', + 'wm': 'Správce prac. prostour', 'Error': 'Chyba', 'Please specify a name.': 'Zadejte název.', 'Caution, users highlighted in red are not yet member of this workspace. They will be automaticaly added.': 'Upozornění – červeně označení uživatelé ještě nejsou členy tohoto pracovního prostoru. Budou automaticky přidáni.', - 'Create group': 'Vytvořit skupinu', + 'Create a workspace group': 'Vytvořit skupinu', 'Delete space': 'Smazat prac. prostor', 'Delete user': 'Odebrat uživatele', 'Error 403': 'Chyba 403', diff --git a/l10n/cs.json b/l10n/cs.json index 2e1e67d6d..e2b6a20d5 100644 --- a/l10n/cs.json +++ b/l10n/cs.json @@ -7,7 +7,7 @@ "Error": "Chyba", "Please specify a name.": "Zadejte název.", "Caution, users highlighted in red are not yet member of this workspace. They will be automaticaly added.": "Upozornění – červeně označení uživatelé ještě nejsou členy tohoto pracovního prostoru. Budou automaticky přidáni.", - "Create group": "Vytvořit skupinu", + "Create a workspace group": "Vytvořit skupinu", "Delete space": "Smazat prac. prostor", "Delete user": "Odebrat uživatele", "Error 403": "Chyba 403", diff --git a/l10n/en.js b/l10n/en.js index cb120cfe1..8ecbd1dfe 100644 --- a/l10n/en.js +++ b/l10n/en.js @@ -3,10 +3,12 @@ OC.L10N.register( { 'Workspace': 'Workspace', 'Are you sure you want to delete the {space} workspace ?': 'Are you sure you want to delete the {space} workspace ?', + 'Add': 'Add', 'Add users': 'Add users', + 'Add a group': 'Add a group', 'All spaces': 'All Workspaces', 'Administrators': 'General manager', - 'admin': 'Workspace manager', + 'wm': 'Workspace manager', 'Error': 'Error', 'Settings': 'Settings', 'Please specify a name.': 'Please specify a name.', @@ -15,7 +17,8 @@ OC.L10N.register( 'Unknown error': 'Unknown error', 'Error in file format': 'Error in file format', 'Caution, users highlighted in red are not yet member of this workspace. They will be automaticaly added.': 'Caution, users highlighted in red are not yet member of this workspace. They will be automaticaly added.', - 'Create group': 'Create group', + 'Create a workspace group': 'Create a workspace group', + 'Add a group': 'Add a group', 'Delete space': 'Delete Workspace', 'Search users': 'Search users', 'Delete user': 'Remove user', @@ -24,6 +27,7 @@ OC.L10N.register( 'Error in the table header': 'Error in the table header', 'The content of your file is invalid. Two columns are required, with the following header names and values:
- "user": the user\'s username or e-mail address
- "role": the user\'s role ("u" or "user" for a user and "wm" for a workspace manager)': 'The content of your file is invalid. Two columns are required, with the following header names and values:
- "user": the user\'s username or e-mail address
- "role": the user\'s role ("u" or "user" for a user and "wm" for a workspace manager)', 'This group already exists. Please, change the name': 'This group already exists. Please, change the name', + 'Remove conntected group': 'Remove conntected group', 'You aren\'t allowed to access into this application !': 'You aren\'t allowed to access into this application !', 'Only the following values are allowed: %1$s

- "wm": to define the user as a workspace manager.
- "u" or "user": to define the user as a simple user.

Check the role for these users:
%2$s': 'Only the following values are allowed: %1$s

- "wm": to define the user as a workspace manager.
- "u" or "user": to define the user as a simple user.

Check the role for these users:
%2$s', 'Error in CSV file content': 'Error in CSV file content', @@ -32,10 +36,12 @@ OC.L10N.register( 'Your CSV file must use a comma (",") as separator': 'Your CSV file must use a comma (",") as separator', 'Email': 'Emails', 'Groups': 'Groups', + 'remove group from selection': 'remove group from selection', + 'No group selected': 'No group selected', 'Duplication of groups': 'Duplication of groups', 'or': 'or', 'The group already exists.': 'The group already exists.', - 'Make administrator': 'Assign as Workspace manager', + 'Make administrator': 'Assign as WM', 'Error to rename space': 'Error to rename space', 'The space name already exist. We cannot rename with this name.': 'The space name already exist. We cannot rename with this name.', 'User doesn\'t exist': 'User doesn\'t exist', @@ -53,7 +59,7 @@ OC.L10N.register( 'Select groupfolders to convert in workspace': 'Select groupfolders to convert in workspace', 'Convert in spaces': 'Convert in spaces', 'The name space must be defined.': 'The name space must be defined.', - 'Remove admin rights': 'Remove workspace manager rights', + 'Remove admin rights': 'Remove WM rights', 'Remove user from selection': 'Remove user from selection', 'There is a problem to add group to groupfolder. The group is deleted.': 'There is a problem to add group to groupfolder. The group is deleted.', 'Rename space': 'Rename Workspace', @@ -71,6 +77,7 @@ OC.L10N.register( 'Remove from group': 'Remove from group', 'Workspace name': 'Workspace name', 'No users': 'No users', + 'Start typing text to search for groups': 'Start typing text to search for groups', 'Group name': 'Group name', 'Space name': 'Space name', 'Your Workspace name must not contain the following characters: [ ~ < > { } | ; . : , ! ? \' @ # $ + ( ) % \\\\ ^ = / & * ]': 'Your Workspace name must not contain the following characters: [ ~ < > { } | ; . : , ! ? \' @ # $ + ( ) % \\ ^ = / & * ]', @@ -85,6 +92,11 @@ OC.L10N.register( 'unlimited': 'unlimited', 'You may only specify "unlimited" or a number followed by "TB", "GB", "MB", or "KB" (eg: "5GB") as quota': 'Vous devez spécifier le terme "unlimited" ou un nombre suivi de "TB", "GB", "MB" ou "KB" (exemple: "5GB") comme quota.', 'This space or groupfolder already exist. Please, input another space.\nIf "toto" space exist, you cannot create the "tOTo" space.\nMake sure you the groupfolder doesn\'t exist.': 'This space or groupfolder already exist. Please, input another space.\nIf "toto" space exist, you cannot create the "tOTo" space.\nMake sure you the groupfolder doesn\'t exist.', + 'Please, note that once {groupname} group has been removed, its users will lose access to the {spacename} workspace': 'Please, note that once {groupname} group has been removed, its users will lose access to the {spacename} workspace', + 'Please note that after deleting the {groupname} group, its users will retain access to the {spacename} workspace': 'Please note that after deleting the {groupname} group, its users will retain access to the {spacename} workspace', + 'Confirm': 'Confirm', + 'Workspace groups': 'Workspace groups', + 'Added groups': 'Added groups', 'A network error occured while trying to create group {group}
The error is: {error}': 'A network error occured while trying to create group {group}
The error is: {error}', 'A network error occured while trying to add user {user_name} to workspaces.
The error is: {error}': 'A network error occured while trying to add user {user_name} to workspaces.
The error is: {error}', 'An error occured while trying to retrieve workspaces.
The error is: {error}': 'An error occured while trying to retrieve workspaces.
The error is: {error}', @@ -104,5 +116,10 @@ OC.L10N.register( 'Something went wrong. Couldn\'t open the file.': 'Something went wrong. Couldn\'t open the file.', 'Upload new files': 'Upload new files', 'Choose from Files': 'Choose from Files', + 'Warning, after removal of group {groupname}, its users will lose access to the nouveaux espaces workspace, with the exception of:

- Workspace Managers (WM-nouveaux espaces)
- users who are members of Groupe Workspace (prefixed G-)
- users who are members of another Added Group
- users manually added from the Workspace nouveaux espaces': 'Warning, after removal of group {groupname}, its users will lose access to the nouveaux espaces workspace, with the exception of:

- Workspace Managers (WM-nouveaux espaces)
- users who are members of Groupe Workspace (prefixed G-)
- users who are members of another Added Group
- users manually added from the Workspace nouveaux espaces', + 'Wrong file extension. Must be .csv.': 'Wrong file extension. Must be .csv.', + 'Add users from csv file': 'Ajouter à partir du fichier csv', + 'Import csv from Files': 'Importer csv à partir de Files', + 'View Profile': 'View Profile' }, 'nplurals=2; plural=(n > 1)') diff --git a/l10n/fr.js b/l10n/fr.js index 69ad85262..98efe9858 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -4,12 +4,16 @@ OC.L10N.register( 'Workspace': 'Espace de travail', 'Are you sure you want to delete the {space} workspace ?': 'Êtes vous sûr de vouloir supprimer l\'espace de travail {space} ?', 'Add': 'Ajouter', + 'Add users': 'Ajouter un utilisateur', + 'Add a group': 'Ajouter un groupe', 'All spaces': 'Tous les espaces de travail', 'Administrators': 'Gestionnaires généraux', - 'admin': "Gestionnaire d'espace", + 'wm': 'Gestionnaire d\'espace', + 'WM': 'G.E.', 'The content of your file is invalid. Two columns are required, with the following header names and values:
- "user": the user\'s username or e-mail address
- "role": the user\'s role ("u" or "user" for a user and "wm" for a workspace manager)': 'Le contenu de votre fichier est invalide. L\'en-tête ne contient pas les valeurs souhaitées.
Deux colonnes sont requises, avec les noms d\'en-têtes et valeurs suivantes :
- "user" : le nom d\'utilisateur ou l\'adresse e-mail de l\'utilisateur
- "role" : le rôle de l\'utilisateur ("u" ou "user" pour un utilisateur et "wm" pour un gestionnaire d\'espace)', 'Group name': 'Nom du groupe', 'Space name': 'Nom de l\'espace de travail', + 'Add a group': 'Ajouter un groupe', 'Cancel': 'Annuler', 'Unknown error': 'Erreur inconnue', 'You csv file must follow this structure:': 'Votre fichier csv doit respecter cette structure :', @@ -23,12 +27,17 @@ OC.L10N.register( 'or': 'ou', 'Create group': 'Créer un groupe', 'Error in CSV file content': 'Erreur dans le contenu du fichier CSV', + 'remove group from selection': 'retirer le groupe de la sélection', + 'Create a workspace group': 'Créer un groupe workspace', 'Duplication of groups': 'Duplication des groupes', 'Invalid separator for CSV file': 'Séparateur incorrect pour le fichier CSV', 'Your CSV file must use a comma (",") as separator': 'Votre fichier CSV doit utiliser une virgule (",") comme séparateur.', 'The group already exists.': 'Le groupe existe déjà.', 'Delete space': "Supprimer l'espace de travail", 'Delete user': "Retirer de l'espace de travail", + 'Please, note that once {groupname} group has been removed, its users will lose access to the {spacename} workspace': 'Attention, après le retrait du groupe {groupname}, ses utilisateurs perdront l\'accès à l\'espace de travail {spacename}', + 'Please note that after deleting the {groupname} group, its users will retain access to the {spacename} workspace': 'Attention, après la suppression du groupe {groupname}, ses utilisateurs conserveront l\'accès à l\'espace de travail {spacename}', + 'Confirm': 'Confirmer', 'Email': 'Email', 'User doesn\'t exist': 'Des utilisateurs n\'existent pas', 'Only the following values are allowed: %1$s

- "wm": to define the user as a workspace manager.
- "u" or "user": to define the user as a simple user.

Check the role for these users:
%2$s': 'Seule les valeurs suivantes sont autorisées pour le champs "role": %1$s

- "wm": pour définir le rôle de gestionnaire d\'espace.
- "u" ou "user": pour définir le rôle d\'utilisateur.

Veuillez vérifier les rôles utilisateurs suivants:
%2$s', @@ -36,6 +45,7 @@ OC.L10N.register( 'Error: unknown users': 'Erreur: utilisateurs non reconnus', '- %1$s has the %2$s role': '- %1$s a le rôle %2$s', 'The users of this CSV file are unknown and can not be imported. Check the following users and repeat the process:
': 'Les utilisateurs de ce fichier CSV ne sont pas reconnus et ne peuvent pas être importés. Veuillez vérifier les utilisateurs suivants et répéter l\'opération :
', + 'Remove conntected group': 'Retirer le groupe', 'Settings': 'Paramètres', 'This group already exists. Please, change the name': 'Ce groupe existe déjà. Changez le nom, s\'il vous plaît.', 'Groups': 'Groupes', @@ -75,8 +85,8 @@ OC.L10N.register( 'Rename space': "Renommer l'espace de travail", 'Rename group': 'Renommer le groupe', 'Delete group': 'Supprimer le groupe', + 'No group selected': 'Aucun groupe selectionné', 'Role': 'Rôle', - 'WM': 'WM', 'Error 403': 'Erreur 403', 'You aren\'t allowed to access into this application !': 'Vous n\'êtes pas autorisé à être dans cette application !', 'return to home': 'retourner à l\'accueil', @@ -90,6 +100,9 @@ OC.L10N.register( 'There are no users in this space/group yet': 'Il n\'y a pas encore d\'utilisateur dans cet espace de travail', 'Start typing to lookup users': 'Commencez à saisir du texte pour rechercher des utilisateurs', 'remove users from selection': 'retirer l\'utilisateur de la sélection', + 'Start typing text to search for groups': 'Commencez à saisir du texte pour rechercher des groupes', + 'Workspace groups': 'Groupes d\'espace de travail', + 'Added groups': 'Groupes ajoutés', 'Workspace name': "Nom de l'espace de travail", 'Error - Duplicate space name': 'Erreur - Duplication de nom de l\'espace de travail', 'Error - This workspace name already exists': 'Erreur - Ce nom d\'espace de travail existe déjà', @@ -103,6 +116,13 @@ OC.L10N.register( 'Invalid file format. Table header doesn\'t contain any of the following values:
{values}': 'Format de fichier est invalide. L\'en-tête du tableau ne contient aucune des valeurs suivantes :
{values}', 'Something went wrong. Couldn\'t open the file.': 'Quelque chose s\'est mal passé. Impossible d\'ouvrir le fichier.', 'Upload new files': 'Téléverser de nouveaux fichiers', - 'Choose from Files': 'Choisir depuis Fichiers' + 'Choose from Files': 'Choisir depuis Fichiers', + 'Wrong file extension. Must be .csv.': 'Mauvais format de fichier. Doit être .csv.', + 'Warning, after removal of group {groupname}, its users will lose access to the nouveaux espaces workspace, with the exception of:

- Workspace Managers (WM-nouveaux espaces)
- users who are members of Groupe Workspace (prefixed G-)
- users who are members of another Added Group
- users manually added from the Workspace nouveaux espaces': 'Attention, après le retrait du groupe {groupname}, les membres de ce groupe perdront l\'accès à l\'espace de travail nouveaux espaces, à l\'exception :

- des Gestionnaires d\'Espaces (WM-nouveaux espaces)
- des utilisateurs embres d\'un Groupe Workspace (préfixé G-)
- des utilisateurs membres d\'un autre Groupe Ajouté
- des utilisateurs ajoutés manuellement depuis l\'espace de travail nouveaux espaces', + 'Invalid file format. Table header doesn\'t contain any of the following values:
{values}': 'Format de fichier est invalide. L\'en-tête du tableau ne contient aucune des valeurs suivantes :
{values}', + 'Something went wrong. Couldn\'t open a file.': 'Quelque chose s\'est mal passé. Impossible d\'ouvrir un fichier.', + 'Add users from csv file': 'Ajouter à partir du fichier csv', + 'Import csv from Files': 'Importer csv à partir de Files', + 'View Profile': 'Voir le profil' }, "nplurals=2; plural=(n > 1)"); diff --git a/l10n/fr.json b/l10n/fr.json index f659f07ba..364ae7eff 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -2,26 +2,32 @@ "Workspace": "Espace de travail", "Are you sure you want to delete the {space} workspace ?": "Êtes vous sûr de vouloir supprimer l'espace de travail {space} ?", "Add": "Ajouter", + "Add users": "Ajouter des utilisateurs", + "Add a group": "Ajouter un groupe", "All spaces": "Tous les espaces de travail", "Administrators" : "Gestionnaires généraux", "admin" : "Gestionnaire d'espace", "Cancel": "Annuler", "Caution, users highlighted in red are not yet member of this workspace. They will be automaticaly added.": "Attention, les utilisateurs surlignés en rouge ne sont pas encore membres de l'espace. Ils seront ajoutés automatiquement à ce dernier", - "Create group": "Créer un groupe", + "Create a workspace group": "Créer un groupe workspace", "Delete space" : "Supprimer l'espace de travail", "Duplication of groups": "Duplication des groupes", "The group already exists.": "Le groupe existe déjà.", "Unknown error": "Erreur inconnue", "Delete user" : "Supprimer de l'espace de travail", "Group name": "Nom du groupe", + "Remove conntected group": "Retirer le groupe", + "Please, note that once {groupname} group has been removed, its users will lose access to the {spacename} workspace": "Attention, après le retrait du groupe {groupname}, ses utilisateurs perdront l'accès à l'espace de travail {spacename}", + "Please note that after deleting the {groupname} group, its users will retain access to the {spacename} workspace": "Attention, après la suppression du groupe {groupname}, ses utilisateurs conserveront l'accès à l'espace de travail {spacename}", + "remove group from selection": "retirer le groupe de la sélection", "Space name": "Nom de l'espace de travail", "Import a .csv file": "Importer un fichier .csv", "Error in file format": "Erreur dans le format de fichier", "Search users": "Rechercher des utilisateurs", "Groups": "Groupes", "Error in the table header": "Erreur dans l'en-tête", - "Search users": "Rechercher des utilisateurs", "The content of your file is invalid. Two columns are required, with the following header names and values:
- \"user\": the user's username or e-mail address
- \"role\": the user's role (\"u\" or \"user\" for a user and \"wm\" for a workspace manager)": "Le contenu de votre fichier est invalide.
Deux colonnes sont requises, avec les noms d'en-têtes et valeurs suivantes :
- \"user\" : le nom d'utilisateur ou l'adresse e-mail de l'utilisateur
- \"role\" : le rôle de l'utilisateur (\"u\" ou \"user\" pour un utilisateur et \"wm\" pour un gestionnaire d'espace)", + "Confirm": "Confirmer", "Make administrator" : "Assigner en tant que WM", "New space" : "Créer un espace de travail", "Settings": "Paramètres", @@ -72,23 +78,29 @@ "Network error occured while trying to change the role of user {user}.
The error is: {error}": "Une erreur réseau s'est produite lors de modification du rôle de l'utilisateur {user}.
L'erreur est: {error}", "An error occured while trying to update the workspace's quota.
The error is: {error}": "Une erreur s'est produite lors de mise à jour du quota de l'espace de travail.
L'erreur est: {error}", "Network error occured while trying to update the workspace's quota.
The error is: {error}": "Une erreur réseau s'est produite lors de mise à jour du quota de l'espace de travail.
L'erreur est: {error}", + "No group selected": "Aucun groupe selectionné", "return to home": "retourner à l'accueil", "Rename group": "Renommer le groupe", "Delete group": "Supprimer le groupe", "Role": "Rôle", - "WM": "WM", + "WM": "G.E.", "Set quota": "Définir un quota", "Space administrators" : "Gestionnaires d'espace de travail", "Users" : "Utilisateurs", "user" : "utilisateur", + "Start typing text to search for groups": "Commencez à saisir du texte pour rechercher des groupes", "Workspace name" : "Nom de l'espace de travail", "Remove from group": "Retirer du groupe", "No users": "Pas d'utilisateur", "Add users": "Ajouter des utilisateurs", "Your Workspace name must not contain the following characters: [ ~ < > { } | ; . : , ! ? ' @ # $ + ( ) % \\\\ ^ = / & * ]": "Le nom de votre Espace de travail ne doit pas contenir les caractères suivants : [ ~ < > { } | ; . : , ! ? ' @ # $ + ( ) % \\\\ ^ = / & * ]", + "Add a group": "Ajouter un groupe", "No spaces": "Aucun espace de travail", "You have not yet created any workspace": "Vous n'avez pas encore créé d'espace de travail", "unlimited": "unlimited", + "Workspace groups": "Groupes d'espace de travail", + "Added groups": "Groupes ajoutés", + "Warning, after removal of group {groupname}, its users will lose access to the nouveaux espaces workspace, with the exception of:

- Workspace Managers (WM-nouveaux espaces)
- users who are members of Groupe Workspace (prefixed G-)
- users who are members of another Added Group
- users manually added from the Workspace nouveaux espaces": "Attention, après le retrait du groupe {groupname}, les membres de ce groupe perdront l'accès à l'espace de travail nouveaux espaces, à l'exception :

- des Gestionnaires d'Espaces (WM-nouveaux espaces)
- des utilisateurs embres d'un Groupe Workspace (préfixé G-)
- des utilisateurs membres d'un autre Groupe Ajouté
- des utilisateurs ajoutés manuellement depuis l'espace de travail nouveaux espaces", "You may only specify \"unlimited\" or a number followed by \"TB\", \"GB\", \"MB\", or \"KB\" (eg: \"5GB\") as quota": "Vous devez spécifier le terme \"unlimited\" ou un nombre suivi de \"TB\", \"GB\", \"MB\" ou \"KB\" (exemple: \"5GB\") comme quota.", "There are no users in this space/group yet": "Il n'y a pas encore d'utilisateur dans cet espace de travail", "Start typing to lookup users": "Commencez à saisir du texte pour rechercher des utilisateurs", @@ -97,7 +109,10 @@ "Invalid file format. Table header doesn't contain any of the following values:
{values}": "Format de fichier est invalide. L'en-tête du tableau ne contient aucune des valeurs suivantes :
{values}", "Something went wrong. Couldn't open the file.": "Quelque chose s'est mal passé. Impossible d'ouvrir le fichier.", "Upload new files": "Téléverser de nouveaux fichiers", - "Choose from Files": "Choisir depuis Fichiers" + "Choose from Files": "Choisir depuis Fichiers", + "Add users from csv file": "Ajouter à partir du fichier csv", + "Import csv from Files": "Importer csv à partir de Files", + "View Profile": "Voir le profil" }, "pluralForm" : "nplurals=2; plural=(n > 1);" } diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 216b74427..8ef493e64 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -22,6 +22,8 @@ namespace OCA\Workspace\AppInfo; +use OCA\Workspace\Db\SpaceMapper; +use OCA\Workspace\Group\GroupBackend; use OCA\Workspace\Middleware\IsGeneralManagerMiddleware; use OCA\Workspace\Middleware\IsSpaceAdminMiddleware; use OCA\Workspace\Middleware\WorkspaceAccessControlMiddleware; @@ -32,6 +34,7 @@ use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\Utility\IControllerMethodReflector; +use OCP\IGroupManager; use OCP\IRequest; use OCP\IURLGenerator; @@ -43,6 +46,7 @@ public function __construct(array $urlParams = []) { } public function register(IRegistrationContext $context): void { + $context->registerService(WorkspaceAccessControlMiddleware::class, function ($c) { return new WorkspaceAccessControlMiddleware( $c->query(IURLGenerator::class), @@ -75,6 +79,14 @@ public function register(IRegistrationContext $context): void { } public function boot(IBootContext $context): void { - } + // Unexplained BUG with autoload. Keep this line + $context->getAppContainer()->query(SpaceMapper::class); + $context->injectFn(function ( + IGroupManager $groupManager, + GroupBackend $groupBackend, + ) { + $groupManager->addBackend($groupBackend); + }); + } } diff --git a/lib/Controller/ConnectedGroupController.php b/lib/Controller/ConnectedGroupController.php new file mode 100644 index 000000000..ab56ba6c9 --- /dev/null +++ b/lib/Controller/ConnectedGroupController.php @@ -0,0 +1,167 @@ +groupManager->groupExists($gid)) { + $message = sprintf('The group %s does not exist', $gid); + + $this->logger->error($message); + + return new JSONResponse( + [ + 'message' => $message, + 'success' => false + ], + Http::STATUS_NOT_FOUND + ); + } + + $group = $this->groupManager->get($gid); + + if (str_starts_with($group->getGID(), 'SPACE-')) { + $message = sprintf('The group %s cannot be added, as it is already a workspace group', $gid); + + $this->logger->error($message); + + return new JSONResponse( + [ + 'message' => $message, + 'success' => false + ], + Http::STATUS_NOT_FOUND + ); + } + + $space = $this->spaceMapper->find($spaceId); + + $this->folderHelper->addApplicableGroup( + $space->getGroupfolderId(), + $group->getGid(), + ); + + + foreach ($group->getUsers() as $user) { + $users[$user->getUID()] = $this->userService->formatUser( + $user, + $this->spaceManager->get($spaceId), + 'user' + ); + }; + + foreach ($users as &$user) { + if (array_key_exists('groups', $user)) { + array_push($user['groups'], 'SPACE-U-' . $space->getSpaceId()); + } + } + + $message = sprintf('The %s group is added to the %s workspace.', $group->getGID(), $space->getSpaceName()); + + $this->logger->info($message); + + return new JSONResponse([ + 'message' => sprintf('The %s group is added to the %s workspace.', $group->getGID(), $space->getSpaceName()), + 'success' => true, + 'users' => $users, + 'slug' => Slugger::slugger($gid), + ]); + } + + /** + * Remove a group connected to a workspace/groupfolder. + * + * @NoAdminRequired + * @SpaceAdminRequired + */ + public function removeGroup(int $spaceId, string $gid) { + if (!$this->groupManager->groupExists($gid)) { + $message = sprintf('The group %s does not exist', $gid); + + $this->logger->error($message); + + return new JSONResponse( + [ + 'message' => $message, + 'success' => false + ], + Http::STATUS_NOT_FOUND + ); + } + + $group = $this->groupManager->get($gid); + + if (str_starts_with($group->getGID(), 'SPACE-')) { + + $message = sprintf('The %s group is not authorized to remove.', $gid); + + $this->logger->error($message); + + return new JSONResponse( + [ + 'message' => $message, + 'success' => false + ], + Http::STATUS_NOT_FOUND + ); + } + + $space = $this->spaceMapper->find($spaceId); + + $this->folderHelper->removeApplicableGroup( + $space->getGroupfolderId(), + $group->getGID() + ); + + $message = sprintf('The group %s is removed from the workspace %s', $group->getGID(), $space->getSpaceName()); + + $this->logger->info($message); + + return new JSONResponse([ + 'message' => sprintf('The group %s is removed from the workspace %s', $group->getGID(), $space->getSpaceName()), + 'success' => true + ]); + } +} diff --git a/lib/Controller/GroupController.php b/lib/Controller/GroupController.php index 00648cb95..edff39474 100644 --- a/lib/Controller/GroupController.php +++ b/lib/Controller/GroupController.php @@ -31,16 +31,21 @@ use OCA\Workspace\Service\Group\ManagersWorkspace; use OCA\Workspace\Service\Group\UserGroup; use OCA\Workspace\Service\Group\WorkspaceManagerGroup; +use OCA\Workspace\Service\Slugger; use OCA\Workspace\Service\User\UserFormatter; use OCA\Workspace\Service\User\UserWorkspace; use OCA\Workspace\Service\UserService; +use OCA\Workspace\Share\Group\GroupMembersOnlyChecker; +use OCA\Workspace\Share\Group\ShareMembersOnlyFilter; use OCA\Workspace\Space\SpaceManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; +use OCP\Collaboration\Collaborators\ISearch; use OCP\IGroupManager; use OCP\IRequest; use OCP\IUserManager; +use OCP\Share\IShare; use Psr\Log\LoggerInterface; class GroupController extends Controller { @@ -52,12 +57,15 @@ class GroupController extends Controller { public function __construct( private GroupsWorkspaceService $groupsWorkspace, private IGroupManager $groupManager, - private LoggerInterface $logger, private SpaceManager $spaceManager, private IUserManager $userManager, + private ISearch $collaboratorSearch, + private LoggerInterface $logger, private UserFormatter $userFormatter, private UserService $userService, private UserWorkspace $userWorkspace, + private GroupMembersOnlyChecker $groupMembersOnlyChecker, + private ShareMembersOnlyFilter $shareMembersOnlyFilter, ) { } @@ -96,7 +104,10 @@ public function create(array $data = []): JSONResponse { return new JSONResponse([ 'group' => [ 'gid' => $NCGroup->getGID(), - 'displayName' => $NCGroup->getDisplayName() + 'displayName' => $NCGroup->getDisplayName(), + 'types' => $NCGroup->getBackendNames(), + 'usersCount' => 0, + 'slug' => Slugger::slugger($NCGroup->getGID()) ] ]); } @@ -429,4 +440,58 @@ public function transferUsersToGroups(string $spaceId, 'users' => (object)$users ], Http::STATUS_OK); } + + /** + * @NoAdminRequired + * + * @param string $pattern The pattern to search + * @param bool $ignoreSpaces (not require) Ignore the workspace groups + * @param array $groupsPresents are groups already present + */ + public function search(string $pattern, ?bool $ignoreSpaces = null, array $groupsPresents = []): JSONResponse { + + [$groups] = $this->collaboratorSearch->search( + $pattern, + [ + IShare::TYPE_GROUP + ], + false, + 200, + 0 + ); + + $groupsSearching = array_map( + fn ($group) => $group['value']['shareWith'], + $groups['groups'] + ); + + $groupsExact = []; + if (!empty($groups['exact']['groups'])) { + $groupsExact[] = $groups['exact']['groups'][0]['value']['shareWith']; + } + + $groups = array_merge($groupsSearching, $groupsExact); + + $groups = array_map(fn ($group) => $this->groupManager->get($group), $groups); + + if (!is_null($ignoreSpaces) && (bool)$ignoreSpaces) { + $groups = array_filter($groups, function ($group) { + $gid = $group->getGID(); + + return !str_starts_with($gid, WorkspaceManagerGroup::getPrefix()) + && !str_starts_with($gid, UserGroup::getPrefix()) + && !str_starts_with($gid, 'SPACE-G') + && $gid !== ManagersWorkspace::GENERAL_MANAGER + && $gid !== ManagersWorkspace::WORKSPACES_MANAGERS; + }); + } + + $groups = array_filter($groups, fn ($group) => !in_array($group->getGID(), $groupsPresents)); + + $groupsFormatted = GroupFormatter::formatGroups($groups); + + uksort($groupsFormatted, 'strcasecmp'); + + return new JSONResponse($groupsFormatted); + } } diff --git a/lib/Controller/WorkspaceController.php b/lib/Controller/WorkspaceController.php index c0fb0b96a..9af769741 100644 --- a/lib/Controller/WorkspaceController.php +++ b/lib/Controller/WorkspaceController.php @@ -25,18 +25,19 @@ namespace OCA\Workspace\Controller; -use OCA\Workspace\Db\Space; use OCA\Workspace\Db\SpaceMapper; use OCA\Workspace\Exceptions\BadRequestException; use OCA\Workspace\Folder\RootFolder; use OCA\Workspace\Group\Admin\AdminGroup; use OCA\Workspace\Group\Admin\AdminUserGroup; use OCA\Workspace\Helper\GroupfolderHelper; +use OCA\Workspace\Service\Group\ConnectedGroupsService; use OCA\Workspace\Service\Group\GroupFormatter; use OCA\Workspace\Service\Group\ManagersWorkspace; use OCA\Workspace\Service\Group\UserGroup; use OCA\Workspace\Service\Group\WorkspaceManagerGroup; use OCA\Workspace\Service\SpaceService; +use OCA\Workspace\Service\User\UserFormatter; use OCA\Workspace\Service\UserService; use OCA\Workspace\Service\Workspace\WorkspaceCheckService; use OCA\Workspace\Service\WorkspaceService; @@ -62,12 +63,14 @@ public function __construct( private SpaceMapper $spaceMapper, private SpaceService $spaceService, private UserService $userService, + private ConnectedGroupsService $connectedGroups, private WorkspaceCheckService $workspaceCheck, private WorkspaceService $workspaceService, private UserGroup $userGroup, + private UserFormatter $userFormatter, private WorkspaceManagerGroup $workspaceManagerGroup, private SpaceManager $spaceManager, - public $AppName + public $AppName, ) { parent::__construct($AppName, $request); } @@ -109,20 +112,10 @@ public function createWorkspace(string $spaceName): JSONResponse { * */ public function destroy(int $spaceId): JSONResponse { - $this->logger->debug('Removing GE users from the WorkspacesManagers group if needed.'); - foreach ($this->adminGroup->getUsers($spaceId) as $user) { - if ($this->userService->canRemoveWorkspaceManagers($user)) { - $this->adminUserGroup->removeUser($user); - } - } - - // Removes all workspaces groups $space = $this->spaceManager->get($spaceId); $groups = []; - $this->logger->debug('Removing workspaces groups.'); foreach (array_keys($space['groups']) as $group) { $groups[] = $group; - $this->groupManager->get($group)->delete(); } $this->spaceManager->remove($spaceId); @@ -181,9 +174,47 @@ public function findAll(): JSONResponse { $groups[] = $group; } + $gids = array_keys($space['groups'] ?? []); + $groups = []; + + $gids = array_filter($gids, fn ($gid) => str_starts_with($gid, 'SPACE-')); + + $space['users'] = []; + foreach ($gids as $gid) { + $group = $this->groupManager->get($gid); + if (is_null($group)) { + $this->logger->warning( + "Be careful, the $gid group is not exist in the oc_groups table." + . " But, it's present in the oc_group_folders_groups table." + . 'It necessary to recreate it with the occ command.' + ); + continue; + } + $groups[] = $group; + + if (str_starts_with($gid, 'SPACE-U-')) { + $space['userCount'] = $group->count(); + } + + if (str_starts_with($gid, 'SPACE-GE')) { + $users = $group->getUsers(); + $space['users'] = $this->userFormatter->formatUsers($users, $folderInfo, (string)$space['id']); + } + + $space['users'] = (object)$space['users']; + } + + $addedGroups = []; + foreach ($gids as $gid) { + $addedToGroup = $this->connectedGroups->getConnectedGroupsToSpaceGroup($gid); + if ($addedToGroup !== null) { + $addedGroups = array_merge($addedGroups, $addedToGroup); + } + } + $space['groups'] = GroupFormatter::formatGroups($groups); - $space['users'] = $this->workspaceService->addUsersInfo($space); - + $space['added_groups'] = (object)GroupFormatter::formatGroups($addedGroups); + $spaces[] = $space; } // We only want to return those workspaces for which the connected user is a manager @@ -198,6 +229,21 @@ public function findAll(): JSONResponse { return new JSONResponse($spaces); } + /** + * @NoAdminRequired + */ + public function getUsers(int $spaceId): JSONResponse { + + $space = $this->spaceMapper->find($spaceId); + + $groupfolder = $this->folderHelper->getFolder($space->getGroupfolderId(), $this->rootFolder->getRootFolderStorageId()); + + $workspace = array_merge($groupfolder, $space->jsonSerialize()); + $users = $this->workspaceService->addUsersInfo($workspace); + + return new JSONResponse($users); + } + /** * @NoAdminRequired * @param string|array $workspace diff --git a/lib/Db/ConnectedGroup.php b/lib/Db/ConnectedGroup.php new file mode 100644 index 000000000..27ad9879e --- /dev/null +++ b/lib/Db/ConnectedGroup.php @@ -0,0 +1,54 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Workspace\Db; + +use JsonSerializable; + +use OCP\AppFramework\Db\Entity; + +class ConnectedGroup extends Entity implements JsonSerializable { + + /** + * @var integer + */ + protected $spaceId; + + /** + * @var string + */ + protected $gid; + + public function __construct() { + $this->addType('space_id', 'integer'); + $this->addType('gid', 'string'); + } + + public function jsonSerialize(): array { + return [ + 'space_id' => (int)$this->getSpaceId(), + 'gid' => $this->getGid(), + ]; + } +} diff --git a/lib/Db/GroupFoldersGroupsMapper.php b/lib/Db/GroupFoldersGroupsMapper.php index 9f7635eb7..f671533e6 100644 --- a/lib/Db/GroupFoldersGroupsMapper.php +++ b/lib/Db/GroupFoldersGroupsMapper.php @@ -32,19 +32,20 @@ class GroupFoldersGroupsMapper extends QBMapper { public function __construct(IDBConnection $db) { $this->db = $db; + $this->entityClass = ConnectedGroup::class; } /** * @return array [ - * [ - * 'space_name' => 'Space01', - * 'group_id' => 'Mars-9', - * ], - * [ - * 'space_name' => 'Space02', - * 'group_id' => 'Moon-10', - * ], - * ] + * [ + * 'space_name' => 'Space01', + * 'group_id' => 'Mars-9', + * ], + * [ + * 'space_name' => 'Space02', + * 'group_id' => 'Moon-10', + * ], + * ] */ public function getSpacenamesGroupIds() { $qb = $this->db->getQueryBuilder(); @@ -65,4 +66,45 @@ public function getSpacenamesGroupIds() { return $qb->executeQuery()->fetchAll(); } + + + /** + * @return array + */ + public function findAllAddedGroups() : array { + $qb = $this->db->getQueryBuilder(); + $query = $qb + ->select([ 'space_id', 'group_id as gid' ]) + ->from('group_folders_groups', 'gf_groups') + ->innerJoin( + 'gf_groups', + 'work_spaces', + 'ws', + $qb->expr()->eq( + 'ws.groupfolder_id', + 'gf_groups.folder_id' + ) + ) + ->where('group_id not like :wmGroup') // G and GE + ->andWhere('group_id not like :uGroup') + ->setParameter('wmGroup', 'SPACE-G%') + ->setParameter('uGroup', 'SPACE-U%'); + + return $this->findEntities($query); + } + + public function isUserConnectedGroup(string $uid): mixed { + $qb = $this->db->getQueryBuilder(); + + $query = $qb + ->select('*') + ->from('group_user') + ->where('uid = :uid') + ->setParameter('uid', $uid) + ; + + $res = $query->executeQuery(); + + return $res->fetch(); + } } diff --git a/lib/Group/AddedGroups/AddedGroups.php b/lib/Group/AddedGroups/AddedGroups.php new file mode 100644 index 000000000..8a7204b1f --- /dev/null +++ b/lib/Group/AddedGroups/AddedGroups.php @@ -0,0 +1,52 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Workspace\Group\AddedGroups; + +use OCA\Workspace\Service\Group\ConnectedGroupsService; +use OCA\Workspace\Service\Group\GroupFormatter; + +class AddedGroups { + + public function __construct( + private ConnectedGroupsService $connectedGroupsService, + ) { + } + + public function get(array $gids): array { + $addedGroups = []; + foreach ($gids as $gid) { + $addedToGroup = $this->connectedGroupsService->getConnectedGroupsToSpaceGroup($gid); + if ($addedToGroup !== null) { + $addedGroups = array_merge($addedGroups, $addedToGroup); + } + } + + return $addedGroups; + } + + public function getGroupsFormatted(array $gids): array { + return GroupFormatter::formatGroups($this->get($gids)); + } +} diff --git a/lib/Group/Admin/AdminGroup.php b/lib/Group/Admin/AdminGroup.php index fd24df5a0..35730c08b 100644 --- a/lib/Group/Admin/AdminGroup.php +++ b/lib/Group/Admin/AdminGroup.php @@ -24,6 +24,8 @@ namespace OCA\Workspace\Group\Admin; +use OCA\Workspace\Db\Space; +use OCA\Workspace\Service\User\UserFormatter; use OCP\IGroupManager; use OCP\IUser; use Psr\Log\LoggerInterface; @@ -34,20 +36,28 @@ class AdminGroup { public const GID_PREFIX = 'SPACE-GE-'; - public function __construct(private AdminUserGroup $adminUserGroup, + public function __construct( + private AdminUserGroup $adminUserGroup, private AdminGroupManager $adminGroupManager, private LoggerInterface $logger, - private IGroupManager $groupManager) { + private UserFormatter $userFormatter, + private IGroupManager $groupManager, + ) { } - public function addUser(IUser $user, string $gid): bool { - $group = $this->adminGroupManager->get($gid); + public function addUser(IUser $user, int $spaceId): bool { + $group = $this->adminGroupManager->get(self::GID_PREFIX . $spaceId); $group->addUser($user); $this->adminUserGroup->addUser($user); return true; } + public function removeUser(IUser $user, int $spaceId): void { + $group = $this->groupManager->get(self::GID_PREFIX . $spaceId); + $group->removeUser($user); + } + /** * @return IUser[] */ @@ -55,4 +65,9 @@ public function getUsers(int $spaceId): array { $group = $this->groupManager->get(self::GID_PREFIX . $spaceId); return $group->getUsers(); } + + public function getUsersFormatted(mixed $folderInfo, Space $space): array { + $users = $this->getUsers($space->getSpaceId()); + return $this->userFormatter->formatUsers($users, $folderInfo, (string)$space->getSpaceId()); + } } diff --git a/lib/Group/GroupBackend.php b/lib/Group/GroupBackend.php new file mode 100644 index 000000000..da8c2f86e --- /dev/null +++ b/lib/Group/GroupBackend.php @@ -0,0 +1,182 @@ + + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Workspace\Group; + +use OCA\Workspace\Service\Group\ConnectedGroupsService; +use OCP\Group\Backend\ABackend; +use OCP\Group\Backend\ICountUsersBackend; +use OCP\Group\Backend\INamedBackend; +use OCP\GroupInterface; +use OCP\IGroupManager; +use OCP\IUserManager; + +class GroupBackend extends ABackend implements GroupInterface, INamedBackend, ICountUsersBackend { + + private bool $avoidRecurse_users; + private bool $avoidRecurse_groups; + + /** + * @param IGroupManager $groupManager parent group manager + */ + public function __construct( + protected IGroupManager $groupManager, + protected IUserManager $userManager, + private ConnectedGroupsService $connectedGroups, + ) { + $this->avoidRecurse_users = $this->avoidRecurse_groups = false; + } + + /** + * is user in group? + * @param string $uid uid of the user + * @param string $gid gid of the group + * @return bool + * + * Checks whether the user is member of a group or not. + */ + public function inGroup($uid, $gid) { + // not backend responsability + return false; + } + + /** + * Get all groups a user belongs to + * @param string $uid Name of the user + * @return string[] an array of group names + * + * This function fetches all groups a user belongs to. It does not check + * if the user exists at all. + */ + public function getUserGroups($uid) { + if ($this->avoidRecurse_groups) { + return []; + } + + $avoid = $this->avoidRecurse_groups; + $this->avoidRecurse_groups = true; + $user = $this->userManager->get($uid); + if ($user) { + $groupIds = $this->groupManager->getUserGroupIds($user); + } else { + $groupIds = []; + } + $this->avoidRecurse_groups = $avoid; + if (empty($groupIds)) { + return []; + } + $userGroups = []; + foreach ($groupIds as $gid) { + $connectedGids = $this->connectedGroups->getConnectedSpaceToGroupIds($gid); + if ($connectedGids !== null) { + $userGroups = array_merge($userGroups, $connectedGids); + } + } + + return $userGroups; + } + + /** + * get a list of all groups + * @param string $search + * @param int $limit + * @param int $offset + * @return array an array of group names + * @since 4.5.0 + * + * Returns a list with all groups + */ + public function getGroups($search = '', $limit = -1, $offset = 0) { + return []; // return all virtual groups + } + + /** + * check if a group exists + * @param string $gid + * @return bool + */ + public function groupExists($gid) { + // @note : need to implement, but this backend doesn't manage existence of connected groups + return $this->connectedGroups->hasConnectedGroups($gid); + } + + /** + * get a list of all users in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return string[] an array of user ids + */ + public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { + if ($this->avoidRecurse_users) { + return []; + } + + $groups = $this->connectedGroups->getConnectedGroupsToSpaceGroup($gid); + if ($groups === null) { + return []; + } + + $users = []; + $avoid = $this->avoidRecurse_users; + $this->avoidRecurse_users = true; + foreach ($groups as $group) { + if (!is_null($group)) { + foreach ($group->getUsers() as $user) { + $users[] = $user->getUID(); + }; + } + } + $this->avoidRecurse_users = $avoid; + return $users; + } + + public function getBackendName(): string { + return 'WorkspaceGroupBackend'; + } + + + public function countUsersInGroup(string $gid, string $search = ''): int { + + $users = $this->usersInGroup($gid); + if (!is_array($users)) { + return 0; + } + + // get database users first + $group = $this->groupManager->get($gid); + $this->avoidRecurse_users = true; + $usersDb = $group->getUsers(); + $this->avoidRecurse_users = false; + + $nbUsers = 0; + foreach ($users as $userId) { + if (!isset($usersDb[$userId])) { + $usersDb[$userId] = true; + $nbUsers ++; + } + } + return $nbUsers; + } +}; diff --git a/lib/Group/SubGroups/SubGroup.php b/lib/Group/SubGroups/SubGroup.php new file mode 100644 index 000000000..ad820ec26 --- /dev/null +++ b/lib/Group/SubGroups/SubGroup.php @@ -0,0 +1,58 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Workspace\Group\SubGroups; + +use OCA\Workspace\Service\Group\GroupFormatter; +use OCP\IGroupManager; +use Psr\Log\LoggerInterface; + +class SubGroup { + public function __construct( + private IGroupManager $groupManager, + private LoggerInterface $logger, + ) { + } + + public function get(array $gids): array { + $groups = []; + foreach ($gids as $gid) { + $group = $this->groupManager->get($gid); + if (is_null($group)) { + $this->logger->warning( + "Be careful, the $gid group is not exist in the oc_groups table." + . " But, it's present in the oc_group_folders_groups table." + . 'It necessary to recreate it with the occ command.' + ); + continue; + } + $groups[] = $group; + } + return $groups; + } + + public function getGroupsFormatted(array $gids): array { + return GroupFormatter::formatGroups($this->get($gids)); + } +} diff --git a/lib/Group/User/UserGroup.php b/lib/Group/User/UserGroup.php index 8e4f90b02..4ca57fab8 100644 --- a/lib/Group/User/UserGroup.php +++ b/lib/Group/User/UserGroup.php @@ -24,6 +24,7 @@ namespace OCA\Workspace\Group\User; +use OCP\IGroupManager; use OCP\IUser; /** @@ -32,7 +33,10 @@ class UserGroup { public const GID_PREFIX = 'SPACE-U-'; - public function __construct(private UserGroupManager $userGroupManager) { + public function __construct( + private UserGroupManager $userGroupManager, + private IGroupManager $groupManager, + ) { } public function addUser(IUser $user, string $gid): bool { @@ -41,4 +45,9 @@ public function addUser(IUser $user, string $gid): bool { return true; } + + public function count(int $spaceId): int { + $usersGroup = $this->groupManager->get($this::GID_PREFIX . $spaceId); + return $usersGroup->count(); + } } diff --git a/lib/Helper/GroupfolderHelper.php b/lib/Helper/GroupfolderHelper.php index 2f42cafc7..0bf1b22a5 100644 --- a/lib/Helper/GroupfolderHelper.php +++ b/lib/Helper/GroupfolderHelper.php @@ -81,6 +81,21 @@ public function addApplicableGroup(int $id, string $group): void { } } + /** + * Remove a group from a groupfolder. + * + * @param integer $id is the folderId of the groupfolder. + * @param string $gid correspond to the gid of group already present in groupfolder. + * @return void + */ + public function removeApplicableGroup(int $id, string $gid): void { + try { + $this->folderManager->removeApplicableGroup($id, $gid); + } catch (\Exception $e) { + throw new GroupFolderFunctionException($e->getMessage() . 'Impossible to use the removeApplicableGroup from FolderManager.'); + } + } + public function setManageACL(int $folderId, string $type, string $id, bool $manageAcl): void { try { $this->folderManager->setManageACL($folderId, $type, $id, $manageAcl); diff --git a/lib/Middleware/IsSpaceAdminMiddleware.php b/lib/Middleware/IsSpaceAdminMiddleware.php index 4759e778a..ffc840246 100644 --- a/lib/Middleware/IsSpaceAdminMiddleware.php +++ b/lib/Middleware/IsSpaceAdminMiddleware.php @@ -47,8 +47,15 @@ public function __construct( public function beforeController($controller, $methodName): void { if ($this->reflector->hasAnnotation('SpaceAdminRequired')) { $spaceId = $this->request->getParam('spaceId'); + if ($spaceId === null) { + $data = $this->request->getParam('data'); + $spaceId = $data ? $data['spaceId'] : null; + } + if ($spaceId === null) { + throw new AccessDeniedException(); + } $space = $this->spaceService->find($spaceId); - if (!$this->userService->isSpaceManagerOfSpace($space->jsonSerialize()) && !$this->userService->isUserGeneralAdmin()) { + if ($spaceId === null || $space === null || (!$this->userService->isSpaceManagerOfSpace($space->jsonSerialize()) && !$this->userService->isUserGeneralAdmin())) { throw new AccessDeniedException(); } } diff --git a/lib/Service/Group/ConnectedGroupsService.php b/lib/Service/Group/ConnectedGroupsService.php new file mode 100644 index 000000000..e4893cd76 --- /dev/null +++ b/lib/Service/Group/ConnectedGroupsService.php @@ -0,0 +1,163 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Workspace\Service\Group; + +use OCA\Workspace\Db\ConnectedGroup; +use OCA\Workspace\Db\GroupFoldersGroupsMapper; +use OCA\Workspace\Db\Space; +use OCA\Workspace\Db\SpaceMapper; +use OCP\IGroup; +use OCP\IGroupManager; + +class ConnectedGroupsService { + + + private ?array $linkedSpaceGroups = null; + private array $linkedGroupsWSGroups = []; + + public function __construct( + private IGroupManager $groupManager, + private GroupFoldersGroupsMapper $mapper, + private SpaceMapper $spaceMapper, + ) { + } + + private function getLinkedSpaceGroups(): array { + if ($this->linkedSpaceGroups === null) { + $this->initLinkedSpaceGroups(); + } + return $this->linkedSpaceGroups; + } + + private function initLinkedSpaceGroups(): void { + $connectedGroups = $this->mapper->findAllAddedGroups(); + + if (empty($connectedGroups)) { + $this->linkedSpaceGroups = []; + return; + } + + $data = []; + foreach ($connectedGroups as $connectedGroup) { + $gid = 'SPACE-U-' . $connectedGroup->getSpaceId(); + $linked_gid = $connectedGroup->getGid(); + $data[$gid][] = $linked_gid; + $this->linkedGroupsWSGroups[$linked_gid][] = $gid; + } + + $this->linkedSpaceGroups = $data; + } + + /** + * @param string $gid + * @param array $spaceGids + * @return bool + */ + public function isConnectedToWorkspace(string $gid, array $spaceGids) : bool { + $linkedSpaceGroups = $this->getLinkedSpaceGroups(); + + foreach ($spaceGids as $spaceGid) { + if (isset($linkedSpaceGroups[$spaceGid])) { + return in_array($gid, $linkedSpaceGroups[$spaceGid]); + } + } + return false; + } + + /** + * @param string $gid + * @return array|null + */ + public function getConnectedSpaceToGroupIds(string $gid): ?array { + if ($this->linkedSpaceGroups === null) { + $this->initLinkedSpaceGroups(); + } + if (isset($this->linkedGroupsWSGroups[$gid])) { + return $this->linkedGroupsWSGroups[$gid]; + } + return null; + } + + /** + * @param string $spaceGid + * @return array|null + */ + public function getConnectedGroupsToSpaceGroup(string $spaceGid): ?array { + $linkedSpaceGroups = $this->getLinkedSpaceGroups(); + + if (!isset($linkedSpaceGroups[$spaceGid])) { + return null; + } + $groups = []; + foreach ($linkedSpaceGroups[$spaceGid] as $gid) { + $groups[] = $this->groupManager->get($gid); + } + return $groups; + } + + /** + * @param string $gid + * @param ?string $gidUserGroup - Specify the gid user group + * @return bool + */ + public function hasConnectedGroups(string $gid, ?string $gidUserGroup = null) : bool { + + $linkedSpaceGroups = $this->getLinkedSpaceGroups(); + + if (empty($linkedSpaceGroups)) { + return false; + } + + if (!is_null($gidUserGroup)) { + $values = $linkedSpaceGroups[$gidUserGroup]; + if (!is_null($values)) { + return in_array($gid, $values); + } + return false; + } + + return isset($linkedSpaceGroups[$gid]); + } + + /** + * @deprecated don't use this function + * @todo delete this function + */ + public function add(IGroup $group, Space $space): bool { + /* + $connectedGroup = new ConnectedGroup(); + $connectedGroup->setSpaceId($space->getSpaceId()); + $connectedGroup->setGid($group->getGid()); + + $this->mapper->insert($connectedGroup); + */ + return true; + } + + public function isUserConnectedGroup(string $uid): bool { + $res = $this->mapper->isUserConnectedGroup($uid); + return empty($res); + } +} diff --git a/lib/Service/Group/GroupFormatter.php b/lib/Service/Group/GroupFormatter.php index 4295a068e..fda2d5eca 100644 --- a/lib/Service/Group/GroupFormatter.php +++ b/lib/Service/Group/GroupFormatter.php @@ -24,19 +24,36 @@ namespace OCA\Workspace\Service\Group; +use OCA\Workspace\Service\Slugger; use OCP\IGroup; class GroupFormatter { /** * @param IGroup[] $groups + * @return array [ + * 'gid' => string, + * 'displayName' => string, + * 'types' => string[], + * 'is_ldap' => boolean + * ] */ public static function formatGroups(array $groups): array { $groupsFormat = []; foreach ($groups as $group) { + + $backendnames = $group->getBackendNames(); + $backendnames = array_map( + fn ($backendname) => strtoupper($backendname), + $backendnames + ); + $groupsFormat[$group->getGID()] = [ 'gid' => $group->getGID(), - 'displayName' => $group->getDisplayName() + 'displayName' => $group->getDisplayName(), + 'types' => $group->getBackendNames(), + 'usersCount' => $group->count(), + 'slug' => Slugger::slugger($group->getGID()) ]; } diff --git a/lib/Service/Slugger.php b/lib/Service/Slugger.php new file mode 100644 index 000000000..a232a0bed --- /dev/null +++ b/lib/Service/Slugger.php @@ -0,0 +1,24 @@ + $user->getEmailAddress(), 'subtitle' => $user->getEmailAddress(), 'groups' => $this->groupsWorkspace->getGroupsUserFromGroupfolder($user, $groupfolder, $spaceId), + 'is_connected' => $this->connectedGroupsService->isUserConnectedGroup($user->getUID()), + 'profile' => $this->urlGenerator->linkToRouteAbsolute('core.ProfilePage.index', ['targetUserId' => $user->getUID()]), 'role' => $role ]; } diff --git a/lib/Service/UserService.php b/lib/Service/UserService.php index 9948d9366..fa07a390c 100644 --- a/lib/Service/UserService.php +++ b/lib/Service/UserService.php @@ -25,9 +25,11 @@ namespace OCA\Workspace\Service; +use OCA\Workspace\Service\Group\ConnectedGroupsService; use OCA\Workspace\Service\Group\ManagersWorkspace; use OCA\Workspace\Service\Group\WorkspaceManagerGroup; use OCP\IGroupManager; +use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserSession; use Psr\Log\LoggerInterface; @@ -36,7 +38,9 @@ class UserService { public function __construct( private IGroupManager $groupManager, private IUserSession $userSession, - private LoggerInterface $logger + private LoggerInterface $logger, + private ConnectedGroupsService $connectedGroups, + private IURLGenerator $urlGenerator, ) { } @@ -55,7 +59,8 @@ public function __construct( * @return array|null * */ - public function formatUser(IUser $user, array $space, string $role): array|null { + + public function formatUser(IUser $user, array $space, string $role): ?array { if (is_null($user)) { return null; } @@ -72,19 +77,20 @@ public function formatUser(IUser $user, array $space, string $role): array|null } foreach ($this->groupManager->getUserGroups($user) as $group) { - if (in_array($group->getGID(), array_keys($space['groups']))) { + if (in_array($group->getGID(), array_keys($space['groups'])) || $this->connectedGroups->isConnectedToWorkspace($group->getGID(), array_keys($space['groups']))) { array_push($groups, $group->getGID()); } } - // Returns a user that is valid for the frontend return [ 'uid' => $user->getUID(), 'name' => $user->getDisplayName(), 'email' => $user->getEmailAddress(), 'subtitle' => $user->getEmailAddress(), 'groups' => $groups, - 'role' => $role + 'role' => $role, + 'is_connected' => $this->connectedGroups->isUserConnectedGroup($user->getUID()), + 'profile' => $this->urlGenerator->linkToRouteAbsolute('core.ProfilePage.index', ['targetUserId' => $user->getUID()]) ]; } @@ -148,7 +154,7 @@ public function canRemoveWorkspaceManagers(IUser $user): bool { fn ($group) => str_starts_with($group->getGID(), 'SPACE-GE') ); - $canRemove = count($allManagersGroups) > 0 && count($allManagersGroups) <= 1 ? true : false; + $canRemove = count($allManagersGroups) >= 0 && count($allManagersGroups) <= 1 ? true : false; if (!$canRemove) { $this->logger->debug('User is still manager of other workspaces, will not remove it from the ' . ManagersWorkspace::WORKSPACES_MANAGERS . ' group.'); diff --git a/lib/Service/WorkspaceService.php b/lib/Service/WorkspaceService.php index 108d658df..45704b8b2 100644 --- a/lib/Service/WorkspaceService.php +++ b/lib/Service/WorkspaceService.php @@ -26,6 +26,8 @@ namespace OCA\Workspace\Service; use OCA\Workspace\Db\SpaceMapper; +use OCA\Workspace\Service\Group\ConnectedGroupsService; +use OCA\Workspace\Service\Group\GroupFormatter; use OCA\Workspace\Service\Group\UserGroup; use OCA\Workspace\Service\Group\WorkspaceManagerGroup; use OCA\Workspace\Share\Group\GroupMembersOnlyChecker; @@ -46,7 +48,8 @@ public function __construct( private SpaceMapper $spaceMapper, private UserService $userService, private ShareMembersOnlyFilter $shareMembersFilter, - private GroupMembersOnlyChecker $memberGroupOnlyChecker + private GroupMembersOnlyChecker $memberGroupOnlyChecker, + private ConnectedGroupsService $connectedGroups, ) { } @@ -177,11 +180,13 @@ public function addUsersInfo(string|array $workspace): \stdClass { $group = $this->groupManager->get(WorkspaceManagerGroup::get($workspace['id'])); if (!is_null($group)) { foreach ($group->getUsers() as $user) { - $users[$user->getUID()] = $this->userService->formatUser($user, $workspace, 'wm'); + if (isset($users[$user->getUID()])) { + $users[$user->getUID()] = $this->userService->formatUser($user, $workspace, 'wm'); + } }; } - return (object) $users; + return (object)$users; } /** @@ -193,15 +198,23 @@ public function addUsersInfo(string|array $workspace): \stdClass { * */ public function addGroupsInfo(array|string $workspace): array { - $groups = []; + if (!isset($workspace['groups'])) { + return $workspace; + } + $groups = array_map( + fn ($gid) => $this->groupManager->get($gid), + array_keys($workspace['groups']) + ); + $addedGroups = []; foreach (array_keys($workspace['groups']) as $gid) { - $NCGroup = $this->groupManager->get($gid); - $groups[$gid] = [ - 'gid' => $NCGroup->getGID(), - 'displayName' => $NCGroup->getDisplayName() - ]; + $addedToGroup = $this->connectedGroups->getConnectedGroupsToSpaceGroup($gid); + if ($addedToGroup !== null) { + $addedGroups = array_merge($addedGroups, $addedToGroup); + } } - $workspace['groups'] = $groups; + + $workspace['groups'] = GroupFormatter::formatGroups($groups); + $workspace['added_groups'] = GroupFormatter::formatGroups($addedGroups); return $workspace; } diff --git a/lib/Space/SpaceManager.php b/lib/Space/SpaceManager.php index 14c67d8d5..6dcbe735d 100644 --- a/lib/Space/SpaceManager.php +++ b/lib/Space/SpaceManager.php @@ -30,13 +30,23 @@ use OCA\Workspace\Exceptions\CreateWorkspaceException; use OCA\Workspace\Exceptions\WorkspaceNameExistException; use OCA\Workspace\Folder\RootFolder; +use OCA\Workspace\Group\AddedGroups\AddedGroups; +use OCA\Workspace\Group\Admin\AdminGroup; +use OCA\Workspace\Group\Admin\AdminUserGroup; +use OCA\Workspace\Group\SubGroups\SubGroup; +use OCA\Workspace\Group\User\UserGroup as UserWorkspaceGroup; use OCA\Workspace\Helper\GroupfolderHelper; use OCA\Workspace\Service\ColorCode; +use OCA\Workspace\Service\Group\ConnectedGroupsService; use OCA\Workspace\Service\Group\GroupFormatter; use OCA\Workspace\Service\Group\UserGroup; use OCA\Workspace\Service\Group\WorkspaceManagerGroup; +use OCA\Workspace\Service\User\UserFormatter; +use OCA\Workspace\Service\UserService; use OCA\Workspace\Service\Workspace\WorkspaceCheckService; use OCP\AppFramework\Http; +use OCP\IGroupManager; +use Psr\Log\LoggerInterface; class SpaceManager { public function __construct( @@ -44,7 +54,17 @@ public function __construct( private RootFolder $rootFolder, private WorkspaceCheckService $workspaceCheck, private UserGroup $userGroup, + private AdminGroup $adminGroup, + private AdminUserGroup $adminUserGroup, + private AddedGroups $addedGroups, + private SubGroup $subGroup, + private UserWorkspaceGroup $userWorkspaceGroup, private SpaceMapper $spaceMapper, + private ConnectedGroupsService $connectedGroupsService, + private LoggerInterface $logger, + private UserFormatter $userFormatter, + private UserService $userService, + private IGroupManager $groupManager, private WorkspaceManagerGroup $workspaceManagerGroup, private ColorCode $colorCode, ) { @@ -120,20 +140,40 @@ public function create(string $spacename): array { $newSpaceManagerGroup, $newSpaceUsersGroup ]), + 'added_groups' => (object)[], 'quota' => $groupfolder['quota'], 'size' => $groupfolder['size'], 'acl' => $groupfolder['acl'], - 'manage' => $groupfolder['manage'] + 'manage' => $groupfolder['manage'], + 'userCount' => 0 ]; } public function get(int $spaceId): array { - $space = $this->spaceMapper->find($spaceId)->jsonSerialize(); - $workspace = array_merge( - $this->folderHelper->getFolder($space['groupfolder_id'], $this->rootFolder->getRootFolderStorageId()), - $space + $space = $this->spaceMapper->find($spaceId); + $groupfolder = $this->folderHelper->getFolder($space->getSpaceId(), $this->rootFolder->getRootFolderStorageId()); + + $workspace = array_merge($space->jsonSerialize(), $groupfolder); + + $folderInfo = $this->folderHelper->getFolder( + $workspace['groupfolder_id'], + $this->rootFolder->getRootFolderStorageId() ); + $workspace = ($folderInfo !== false) ? array_merge( + $folderInfo, + $workspace + ) : $workspace; + + $gids = array_keys($workspace['groups'] ?? []); + + $gids = array_filter($gids, fn ($gid) => str_starts_with($gid, 'SPACE-')); + + $workspace['userCount'] = $this->userWorkspaceGroup->count($space->getSpaceId()); + + $workspace['users'] = $this->adminGroup->getUsersFormatted($folderInfo, $space); + $workspace['groups'] = $this->subGroup->getGroupsFormatted($gids); + $workspace['added_groups'] = (object)$this->addedGroups->getGroupsFormatted($gids); return $workspace; } @@ -153,6 +193,21 @@ private function deleteBlankSpaceName(string $spaceName): string { public function remove(string $spaceId): void { $space = $this->get($spaceId); + + foreach ($this->adminGroup->getUsers($spaceId) as $user) { + if ($this->userService->canRemoveWorkspaceManagers($user)) { + $this->logger->debug('Remove user ' . $user->getUID() . ' from the Workspace Manager group in ' . $space['name']); + $this->adminUserGroup->removeUser($user); + } + } + + $groups = []; + $this->logger->debug('Removing workspace groups.'); + foreach (array_keys($space['groups']) as $group) { + $groups[] = $group; + $this->groupManager->get($group)->delete(); + } + $folderId = $space['groupfolder_id']; $this->folderHelper->removeFolder($folderId); } diff --git a/lib/Users/UserFormatter.php b/lib/Users/UserFormatter.php index 2374c724e..97696596c 100644 --- a/lib/Users/UserFormatter.php +++ b/lib/Users/UserFormatter.php @@ -2,11 +2,17 @@ namespace OCA\Workspace\Users; +use OCA\Workspace\Service\Group\ConnectedGroupsService; use OCP\IGroupManager; +use OCP\IURLGenerator; use OCP\IUser; class UserFormatter { - public function __construct(private IGroupManager $groupManager) { + public function __construct( + private IGroupManager $groupManager, + private ConnectedGroupsService $connectedGroupsService, + private IURLGenerator $urlGenerator, + ) { } /** @@ -32,6 +38,8 @@ public function formatUser(IUser $user, array $space, string $role): array { 'email' => $user->getEmailAddress(), 'subtitle' => $user->getEmailAddress(), 'groups' => $groups, + 'is_connected' => $this->connectedGroupsService->isUserConnectedGroup($user->getUID()), + 'profile' => $this->urlGenerator->linkToRouteAbsolute('core.ProfilePage.index', ['targetUserId' => $user->getUID()]), 'role' => $role ]; } diff --git a/src/AddUsersTabs.vue b/src/AddUsersTabs.vue index 6e70d7019..818770c65 100644 --- a/src/AddUsersTabs.vue +++ b/src/AddUsersTabs.vue @@ -70,13 +70,13 @@ -

@@ -172,36 +172,132 @@ export default { this.$emit('close-sidebar') const space = this.$store.state.spaces[this.$route.params.space] this.allSelectedUsers.forEach(user => { - let gid = '' - if (this.$route.params.group !== undefined) { - // Adding a user to a workspace 'subgroup - this.$store.dispatch('addUserToGroup', { - name: this.$route.params.space, - gid: this.$route.params.group, - user, - }) - if (this.isWorkspaceManager(user.role)) { - this.$store.dispatch('addUserToGroup', { - name: this.$route.params.space, - gid: ManagerGroup.getGid(space), - user, - }) + if (this.$route.params.slug !== undefined) { + if (decodeURIComponent(this.$route.params.slug).startsWith('SPACE-U')) { + this.addUserFromUserGroup(user) + return } - } else { - // Adding a user to the workspace - if (this.isWorkspaceManager(user.role)) { - gid = ManagerGroup.getGid(space) + if (decodeURIComponent(this.$route.params.slug).startsWith('SPACE-GE')) { + this.addUserFromManagerGroup(user, space) + return + } + if (Object.keys(space.users).includes(user.uid) && decodeURIComponent(this.$route.params.slug).startsWith('SPACE-G-')) { + this.addExistingUserFromSubgroup(user) } else { - gid = UserGroup.getGid(space) + this.addNewUserFromSubgroup(user, space) } - this.$store.dispatch('addUserToGroup', { - name: this.$route.params.space, - gid, - user, - }) + } else { + this.addUserFromWorkspace(user, space) } }) }, + addUserFromWorkspace(user, space) { + let gid = '' + if (user.role === 'wm') { + gid = ManagerGroup.getGid(space) + } else { + gid = UserGroup.getGid(space) + } + this.$store.dispatch('addUserToGroup', { + name: this.$route.params.space, + gid, + user, + }) + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid, + }) + this.$store.dispatch('incrementSpaceUserCount', { + spaceName: this.$route.params.space, + }) + if (user.role === 'wm') { + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: UserGroup.getGid(space), + }) + } + }, + addExistingUserFromSubgroup(user) { + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + }) + this.$store.dispatch('addUserToGroup', { + name: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + user, + }) + }, + addNewUserFromSubgroup(user, space) { + this.$store.dispatch('addUserToGroup', { + name: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + user, + }) + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + }) + this.$store.dispatch('incrementSpaceUserCount', { + spaceName: this.$route.params.space, + }) + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: UserGroup.getGid(space), + }) + if (user.role === 'wm') { + this.$store.dispatch('addUserToGroup', { + name: this.$route.params.space, + gid: ManagerGroup.getGid(space), + user, + }) + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: ManagerGroup.getGid(space), + }) + } + }, + addUserFromManagerGroup(user, space) { + const usersBackup = [...Object.keys(space.users)] + this.$store.dispatch('addUserToGroup', { + name: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + user, + }) + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + }) + if (usersBackup.includes(user.uid)) { + return + } + this.$store.dispatch('addUserToGroup', { + name: this.$route.params.space, + gid: UserGroup.getGid(space), + user, + }) + this.$store.dispatch('incrementSpaceUserCount', { + spaceName: this.$route.params.space, + }) + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: UserGroup.getGid(space), + }) + }, + addUserFromUserGroup(user) { + this.$store.dispatch('addUserToGroup', { + name: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + user, + }) + this.$store.dispatch('incrementGroupUserCount', { + spaceName: this.$route.params.space, + gid: decodeURIComponent(decodeURIComponent(this.$route.params.slug)), + }) + this.$store.dispatch('incrementSpaceUserCount', { + spaceName: this.$route.params.space, + }) + }, // Adds user to the batch when user selects user in the MultiSelect addUserToBatch(user) { this.allSelectedUsers.push(user) diff --git a/src/AlertRemoveGroup.vue b/src/AlertRemoveGroup.vue new file mode 100644 index 000000000..89555355d --- /dev/null +++ b/src/AlertRemoveGroup.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/ButtonUploadLocalFile.vue b/src/ButtonUploadLocalFile.vue index 0c3bc002f..c4238490c 100644 --- a/src/ButtonUploadLocalFile.vue +++ b/src/ButtonUploadLocalFile.vue @@ -70,7 +70,7 @@ export default { try { const users = await this.$store.dispatch('addUsersFromCSV', { formData: bodyFormData, - spaceId: space.id + spaceId: space.id, }) let usersToDisplay = this.filterAlreadyPresentUsers(users) usersToDisplay = this.addSubtitleToUsers(usersToDisplay) @@ -96,14 +96,14 @@ export default { // When adding users to a space, show only those users who are not already member of the space filterAlreadyPresentUsers(recvUsers) { let users = [] - if (this.$route.params.group === undefined) { + if (this.$route.params.slug === undefined) { const space = this.$store.state.spaces[this.$route.params.space] users = recvUsers.filter(user => { return (!(user.uid in space.users)) }, space) } else { users = recvUsers.filter(user => { - return (!(user.groups.includes(this.$route.params.group))) + return (!(user.groups.includes(decodeURIComponent(decodeURIComponent(this.$route.params.slug))))) }) } // Filters user that are already selected diff --git a/src/ButtonUploadShareFiles.vue b/src/ButtonUploadShareFiles.vue index 81b8bc38e..57bec05d1 100644 --- a/src/ButtonUploadShareFiles.vue +++ b/src/ButtonUploadShareFiles.vue @@ -88,14 +88,14 @@ export default { // When adding users to a space, show only those users who are not already member of the space filterAlreadyPresentUsers(recvUsers) { let users = [] - if (this.$route.params.group === undefined) { + if (this.$route.params.slug === undefined) { const space = this.$store.state.spaces[this.$route.params.space] users = recvUsers.filter(user => { return (!(user.uid in space.users)) }, space) } else { users = recvUsers.filter(user => { - return (!(user.groups.includes(this.$route.params.group))) + return (!(user.groups.includes(decodeURIComponent(decodeURIComponent(this.$route.params.slug))))) }) } // Filters user that are already selected diff --git a/src/GroupDetails.vue b/src/GroupDetails.vue index c5fc36b4d..87ccf94cf 100644 --- a/src/GroupDetails.vue +++ b/src/GroupDetails.vue @@ -21,16 +21,16 @@ --> diff --git a/src/LeftSidebar.vue b/src/LeftSidebar.vue index 575925169..1a795ac6a 100644 --- a/src/LeftSidebar.vue +++ b/src/LeftSidebar.vue @@ -26,7 +26,7 @@ :title="t('workspace', 'New space')" @new-item="createSpace" /> diff --git a/src/SpaceTable.vue b/src/SpaceTable.vue index ea2e42107..0a4b5aa31 100644 --- a/src/SpaceTable.vue +++ b/src/SpaceTable.vue @@ -104,6 +104,9 @@ export default { this.$router.push({ path: `/workspace/${name}`, }) + + const space = this.$store.state.spaces[this.$route.params.space] + this.$store.dispatch('loadUsers', { space }) }, }, } diff --git a/src/UserCard.vue b/src/UserCard.vue index fa026885a..603ac1186 100644 --- a/src/UserCard.vue +++ b/src/UserCard.vue @@ -29,10 +29,11 @@

-
+
{{ t('workspace', 'WM') }} diff --git a/src/UserTable.vue b/src/UserTable.vue index a22f252dd..6d1e10f06 100644 --- a/src/UserTable.vue +++ b/src/UserTable.vue @@ -54,7 +54,7 @@
- {{ t('workspace', $store.getters.isSpaceAdmin(user, $route.params.space) ? 'admin' : 'user') }} + {{ t('workspace', $store.getters.isSpaceAdmin(user, $route.params.space) ? 'wm' : 'user') }} {{ user.groups.map(group => $store.getters.groupName($route.params.space, group)).join(', ') }} @@ -62,24 +62,36 @@