From 52dae13d6bb395da5fa86d3783e9db5b3c97c25f Mon Sep 17 00:00:00 2001 From: Fin Clausen Date: Fri, 28 Aug 2026 16:08:54 +0200 Subject: [PATCH] rename team folder to group folder Co-authored-by: Copilot GPT-5.6 Sol Signed-off-by: Fin Clausen --- README.md | 74 ++++++++++--------- appinfo/info.xml | 14 ++-- .../RepairMisplacedTrashItemsJob.php | 6 +- lib/Command/ACL.php | 2 +- lib/Command/Create.php | 2 +- lib/Command/Delete.php | 4 +- .../ExpireGroupVersionsPlaceholder.php | 4 +- lib/Command/Group.php | 2 +- lib/Command/ListCommand.php | 4 +- lib/Command/Quota.php | 2 +- lib/Command/Rename.php | 2 +- lib/Command/Scan.php | 14 ++-- lib/Command/Trashbin/Cleanup.php | 10 +-- lib/Controller/FolderController.php | 4 +- lib/DAV/ACLPlugin.php | 4 +- lib/Folder/FolderDefinition.php | 4 +- lib/Folder/FolderManager.php | 34 ++++----- .../RepairMisplacedTrashItemsStep.php | 4 +- lib/Migration/TrimMountpointsRepairStep.php | 2 +- .../Version104000Date20180918132853.php | 2 +- .../Version201000Date20190111132839.php | 2 +- .../Version2300000Date20260720000001.php | 2 +- lib/Settings/Section.php | 2 +- lib/TeamSpace/TeamSpaceProvider.php | 4 +- lib/TeamSpace/TeamSpaceService.php | 34 ++++----- lib/Trash/TrashBackend.php | 10 +-- lib/Versions/VersionsBackend.php | 6 +- src/actions/openGroupfolderAction.ts | 2 +- src/components/SharingSidebarView.vue | 2 +- src/components/TeamFoldersEncryption.vue | 10 +-- src/init-files.ts | 8 +- src/settings/App.tsx | 36 ++++----- templates/index.php | 2 +- tests/Folder/FolderManagerTest.php | 20 ++--- 34 files changed, 169 insertions(+), 165 deletions(-) diff --git a/README.md b/README.md index 7cda75075..fc202990d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ - SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors - SPDX-License-Identifier: AGPL-3.0-or-later --> -# Team folders +# Group folders [![REUSE status](https://api.reuse.software/badge/github.com/nextcloud/groupfolders)](https://api.reuse.software/info/github.com/nextcloud/groupfolders) @@ -15,36 +15,40 @@ [^1]: The releases are now managed in a [dedicated release repository](https://github.com/nextcloud-releases/groupfolders/releases). The releases in this repository may be outdated. -## Configuring Team folder +## Configuring group folders -Team folders can be configured through *Team folders* under *Administration settings*. +Group folders can be configured through *Group folders* under *Administration settings*. After a folder is created, the admin can give access to the folder to one or more groups, users or Teams (formerly Circles). A quota can be assigned for the folder and advanced permissions can be activated and configured. ![edit](screenshots/edit.png) -Permissions to the content of a Team folder can be configured on a per-group/team/user basis. +Permissions to the content of a group folder can be configured on a per-group/team/user basis. ![permissions](screenshots/permissions.png) The configuration options include the _Write_, _Share_ and _Delete_ permissions for each group. -## Using Team folders +## Using group folders Once configured, the folders will show up in the home folder for each user in the configured groups or teams. ![folders](screenshots/folders.png) >[!WARNING] -> There is no record of when a user or team was added to a Team folder, and anything related to the team is considered shared knowledge, including previous versions and deleted files. +> There is no record of when a user or team was added to a group folder, and anything related to the team is considered shared knowledge, including previous versions and deleted files. -## Team Folder Data Storage +## Team folders -Where and how Team folder data is stored depends on your Nextcloud instance’s storage configuration. +Team folders are the main storage for teams and have a 1:1 relationship with a team. Their lifecycle and permissions are managed by the team integration, while group folders remain freely configurable by administrators. + +## Group folder data storage + +Where and how group folder data is stored depends on your Nextcloud instance’s storage configuration. ### Default Storage on Filesystem -By default, all files, versions, and trash for each Team folder are stored **on your server’s local filesystem**, inside your Nextcloud `datadirectory` under a special subdirectory: +By default, all files, versions, and trash for each group folder are stored **on your server’s local filesystem**, inside your Nextcloud `datadirectory` under a special subdirectory: ``` /__groupfolders//files/ @@ -52,11 +56,11 @@ By default, all files, versions, and trash for each Team folder are stored **on /__groupfolders//versions/ ``` -where `` is the numeric ID of the Team folder. Each Team folder gets its own folder within `__groupfolders`. +where `` is the numeric ID of the group folder. Each group folder gets its own folder within `__groupfolders`. ### Object Storage as Primary Storage -If your Nextcloud instance is configured to use **primary object storage** (e.g., S3, Swift), all Team folder data is stored in the object storage bucket, using the same logical layout as above: +If your Nextcloud instance is configured to use **primary object storage** (e.g., S3, Swift), all group folder data is stored in the object storage bucket, using the same logical layout as above: ``` __groupfolders//files/ @@ -71,33 +75,33 @@ In this case, data is never stored on the server’s local disk. The mapping and ### End-User and Admin Experience -Team folders always appear as special shared folders in users’ file lists, regardless of whether you are using local or object storage. No additional configuration is needed for accessing or sharing files, regardless of backend storage type. +Group folders always appear as special shared folders in users’ file lists, regardless of whether you are using local or object storage. No additional configuration is needed for accessing or sharing files, regardless of backend storage type. -All access control, configuration, and permissions for Team folders are managed within the Nextcloud database and UI as before. +All access control, configuration, and permissions for group folders are managed within the Nextcloud database and UI as before. ## Setting Advanced Permissions -_Advanced Permissions_ allows entitled users to configure permissions inside Team folders on a per file and folder basis. +_Advanced Permissions_ allows entitled users to configure permissions inside group folders on a per file and folder basis. -Permissions are configured by setting one or more of "Read", "Write", "Create", "Delete" or "Share" permissions to "allow" or "deny". Any permission not explicitly set will inherit the permissions from the parent folder. If multiple configured advanced permissions for a single file or folder apply for a single user (such as when a user belongs to multiple groups), the "allow" permission will overwrite any "deny" permission. Denied permissions configured for the Team folder itself cannot be overwritten to "allow" permissions by the advanced permission rules. +Permissions are configured by setting one or more of "Read", "Write", "Create", "Delete" or "Share" permissions to "allow" or "deny". Any permission not explicitly set will inherit the permissions from the parent folder. If multiple configured advanced permissions for a single file or folder apply for a single user (such as when a user belongs to multiple groups), the "allow" permission will overwrite any "deny" permission. Denied permissions configured for the group folder itself cannot be overwritten to "allow" permissions by the advanced permission rules. Take a look at this example to understand how to properly configure Advanced Permissions for more complex scenarios with multiple groups or Teams: 1. You have the groups "Management", "Employees" with some users only belonging to "Management", but everyone being part of "Employees". -2. You configure a Team folder and add the groups "Management", "Employees" with "Read" and "Write" permissions. -3. For a sub folder in the Team folder you explicitly configure the group "Employees" to have NO "Write" permission, but still "Read" permission. +2. You configure a group folder and add the groups "Management", "Employees" with "Read" and "Write" permissions. +3. For a sub folder in the group folder you explicitly configure the group "Employees" to have NO "Write" permission, but still "Read" permission. 4. For the same sub folder you configure "Management" to have "Read" and "Write" permissions. Now only users in the "Management" group can write in the sub folder, while all users in the "Employees" group can not. -Note that currently (Nextcloud 31/Hub 10) you need to be a member or admin of a team in order to assign it to a Team folder. +Note that currently (Nextcloud 31/Hub 10) you need to be a member or admin of a team in order to assign it to a group folder. All ACL rules always need to have the least permissions for any user/group/Team with access to the sub folder. For those users/groups/Teams that need more permissions you need to add a second rule that grants them the desired permissions. ![advanced permissions](screenshots/acl.png) -Users or whole groups can be entitled to set advanced permissions for each Team folder separately on the Team folders admin page. +Users or whole groups can be entitled to set advanced permissions for each group folder separately on the Group folders admin page. For entitlements, only users from those groups are selectable which have to be configured selected in the Groups column. ![advanced permission entitlement](screenshots/aclAdmin.png) @@ -106,7 +110,7 @@ For entitlements, only users from those groups are selectable which have to be c Some settings are currently only exposed via `config/config.php`: -### Default quota for new Team folders +### Default quota for new group folders ```injectablephp 'groupfolders.quota.default' => -3, @@ -116,24 +120,24 @@ The special value `-3` means unlimited and any other value is the quota limit in ## Command-line interface management and configuration (via `occ`) -Team folders can be configured and managed from the command-line interface (CLI). This is accomplished by using the `occ` command. +Group folders can be configured and managed from the command-line interface (CLI). This is accomplished by using the `occ` command. -The `occ` command is utilized throughout Nextcloud for many operations and is not specific to Team folders. When the Team folders app is enabled, the `occ` command gains additional functionality specific to Team folders. +The `occ` command is utilized throughout Nextcloud for many operations and is not specific to group folders. When the Group folders app is enabled, the `occ` command gains additional functionality specific to group folders. If you're unfamiliar with `occ` see [Using the occ command](https://docs.nextcloud.com/server/latest/admin_manual/occ_command.html) in the Nextcloud Server Administration Guide for general guidance. ### Commands Available -- `occ groupfolders:create ` → create a Team folder -- `occ groupfolders:delete [-f|--force]` → delete a Team folder and all its contents +- `occ groupfolders:create ` → create a group folder +- `occ groupfolders:delete [-f|--force]` → delete a group folder and all its contents - `occ groupfolders:expire` → trigger file version and trashbin expiration (see [Nextcloud docs for versioning](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/file_versioning.html) and [Nextcloud docs for the trash bin](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/trashbin_configuration.html) for details) -- `occ groupfolders:group [-d|--delete] [write|share|delete]` → assign groups and their rights to a Team folder -- `occ groupfolders:list` → list configured Team folders +- `occ groupfolders:group [-d|--delete] [write|share|delete]` → assign groups and their rights to a group folder +- `occ groupfolders:list` → list configured group folders - `occ groupfolders:permissions` → configure advanced permissions (see below for details) -- `occ groupfolders:quota [|unlimited]` → set a quota for a Team folder -- `occ groupfolders:rename ` → rename a Team folder -- `occ groupfolders:scan ` → trigger a filescan for a Team folder -- `occ groupfolders:trashbin:cleanup` → empty the trashbin of all Team folders +- `occ groupfolders:quota [|unlimited]` → set a quota for a group folder +- `occ groupfolders:rename ` → rename a group folder +- `occ groupfolders:scan ` → trigger a filescan for a group folder +- `occ groupfolders:trashbin:cleanup` → empty the trashbin of all group folders - `occ config:app:set groupfolders enable_encryption --value="true"` → activate encryption (server-side) support ### Configuring Advanced Permissions via `occ` @@ -142,7 +146,7 @@ Advanced permissions can also be configured through the `occ groupfolders:permis #### Enabling -Before configuring any advanced permissions you'll first have to enable advanced permissions for the folder using `occ groupfolders:permissions --enable`. To do this you'll first need to find the `folder_id` of the Team folder you're trying to configure. You can use `occ groupfolders:list` to find the `folder_id` of the target folder. +Before configuring any advanced permissions you'll first have to enable advanced permissions for the folder using `occ groupfolders:permissions --enable`. To do this you'll first need to find the `folder_id` of the group folder you're trying to configure. You can use `occ groupfolders:list` to find the `folder_id` of the target folder. #### Using @@ -172,7 +176,7 @@ To manage the users or groups entitled to set advanced permissions, use `occ gro #### Disabling -To disable the advanced permissions feature for a Team folder, use `occ groupfolders:permissions --disable`. +To disable the advanced permissions feature for a group folder, use `occ groupfolders:permissions --disable`. ## APIs @@ -182,9 +186,9 @@ See the [OpenAPI specification](openapi.json) to learn about all available API e ### WebDAV API -Team folders are also exposed through a separate [WebDAV API](https://docs.nextcloud.com/server/latest/user_manual/en/files/access_webdav.html) at `/remote.php/dav/groupfolders/`. +Group folders are also exposed through a separate [WebDAV API](https://docs.nextcloud.com/server/latest/user_manual/en/files/access_webdav.html) at `/remote.php/dav/groupfolders/`. -In addition to browsing the contents of the Team folders, you can also request the mount point for the Team folder by requesting the `{http://nextcloud.org/ns}mount-point` property. +In addition to browsing the contents of the group folders, you can also request the mount point for the group folder by requesting the `{http://nextcloud.org/ns}mount-point` property. ## 🚧 Development setup @@ -193,4 +197,4 @@ In addition to browsing the contents of the Team folders, you can also request t 2. Run `npm ci` to install JS/frontend dependencies. 3. Run `npm run build` for a production build or `npm run dev` for a watch/dev build. 4. Then activate the app through the apps management. -5. Start using the app in "Team folders" in administration settings. \ No newline at end of file +5. Start using the app in "Group folders" in administration settings. \ No newline at end of file diff --git a/appinfo/info.xml b/appinfo/info.xml index 54f53d78d..6e3fcd998 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,20 +5,20 @@ --> groupfolders - Team Folders - Shared folders managed by admins, accessible to designated teams with configurable permissions and quotas + Group folders + Shared folders managed by admins, accessible to designated groups and teams with configurable permissions and quotas 24.0.0-dev.0 diff --git a/lib/BackgroundJob/RepairMisplacedTrashItemsJob.php b/lib/BackgroundJob/RepairMisplacedTrashItemsJob.php index 651b62a00..7df739bec 100644 --- a/lib/BackgroundJob/RepairMisplacedTrashItemsJob.php +++ b/lib/BackgroundJob/RepairMisplacedTrashItemsJob.php @@ -16,7 +16,7 @@ /** * One-off repair to find trash items whose `group_folders_trash` row was - * updated to point to a new Team folder but the actual entries weren't. + * updated to point to a new group folder but the actual entries weren't. */ class RepairMisplacedTrashItemsJob extends QueuedJob { public function __construct( @@ -28,14 +28,14 @@ public function __construct( } public function getName(): string { - return 'Repair team folder trash item to their correct storage'; + return 'Repair group folder trash item to their correct storage'; } #[\Override] public function run(mixed $argument): void { $fixed = $this->trashBackend->repairMisplacedTrashItems(); if ($fixed > 0) { - $this->logger->info("Moved $fixed team folder trash item(s) to their correct storage"); + $this->logger->info("Moved $fixed group folder trash item(s) to their correct storage"); } } } diff --git a/lib/Command/ACL.php b/lib/Command/ACL.php index df83e4947..606e1451a 100644 --- a/lib/Command/ACL.php +++ b/lib/Command/ACL.php @@ -44,7 +44,7 @@ public function __construct( protected function configure(): void { $this ->setName('groupfolders:permissions') - ->setDescription('Configure advanced permissions for a configured Team folder') + ->setDescription('Configure advanced permissions for a configured group folder') ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to configure') ->addOption('enable', 'e', InputOption::VALUE_NONE, 'Enable advanced permissions for the folder') ->addOption('disable', 'd', InputOption::VALUE_NONE, 'Disable advanced permissions for the folder') diff --git a/lib/Command/Create.php b/lib/Command/Create.php index a8c56c029..88e996d36 100644 --- a/lib/Command/Create.php +++ b/lib/Command/Create.php @@ -26,7 +26,7 @@ public function __construct( protected function configure(): void { $this ->setName('groupfolders:create') - ->setDescription('Create a new Team folder') + ->setDescription('Create a new group folder') ->addArgument('name', InputArgument::REQUIRED, 'Name or mount point of the new folder') ->addOption('bucket', null, InputOption::VALUE_REQUIRED, 'Overwrite the bucket used for the new folder') ->addOption('acl-no-default-permission', null, InputOption::VALUE_NONE, 'Do not grant any advanced permission by default'); diff --git a/lib/Command/Delete.php b/lib/Command/Delete.php index 923f9e8f8..08ea2fb89 100644 --- a/lib/Command/Delete.php +++ b/lib/Command/Delete.php @@ -19,7 +19,7 @@ class Delete extends FolderCommand { protected function configure(): void { $this ->setName('groupfolders:delete') - ->setDescription('Delete Team folder') + ->setDescription('Delete group folder') ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to rename') ->addOption('force', 'f', InputOption::VALUE_NONE, 'Skip confirmation'); parent::configure(); @@ -38,7 +38,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int /** @var QuestionHelper $helper */ $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion('Are you sure you want to delete the Team folder ' . $folder->mountPoint . ' and all files within, this cannot be undone (y/N).', false); + $question = new ConfirmationQuestion('Are you sure you want to delete the group folder ' . $folder->mountPoint . ' and all files within, this cannot be undone (y/N).', false); if ($input->getOption('force') || $helper->ask($input, $output, $question)) { $this->folderStorageManager->deleteStoragesForFolder($folder); $this->folderManager->removeFolder($folder->id); diff --git a/lib/Command/ExpireGroupVersionsPlaceholder.php b/lib/Command/ExpireGroupVersionsPlaceholder.php index 51022254f..d21e06f95 100644 --- a/lib/Command/ExpireGroupVersionsPlaceholder.php +++ b/lib/Command/ExpireGroupVersionsPlaceholder.php @@ -17,13 +17,13 @@ class ExpireGroupVersionsPlaceholder extends Base { protected function configure(): void { $this ->setName('groupfolders:expire') - ->setDescription('Trigger expiry of versions for files stored in Team folders'); + ->setDescription('Trigger expiry of versions for files stored in group folders'); parent::configure(); } #[\Override] protected function execute(InputInterface $input, OutputInterface $output): int { - $output->writeln('Team folder version handling is only supported with Nextcloud 15 and up'); + $output->writeln('Group folder version handling is only supported with Nextcloud 15 and up'); return 0; } } diff --git a/lib/Command/Group.php b/lib/Command/Group.php index c3aeea018..dd85bc5ba 100644 --- a/lib/Command/Group.php +++ b/lib/Command/Group.php @@ -40,7 +40,7 @@ public function __construct( protected function configure(): void { $this ->setName('groupfolders:group') - ->setDescription('Edit the groups that have access to a Team folder') + ->setDescription('Edit the groups that have access to a group folder') ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to configure') ->addArgument('group', InputArgument::REQUIRED, 'The group to configure') ->addArgument('permissions', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The permissions to set for the group as a white space separated list (ex: read write). Leave empty for read only') diff --git a/lib/Command/ListCommand.php b/lib/Command/ListCommand.php index 1031af328..4e6703f80 100644 --- a/lib/Command/ListCommand.php +++ b/lib/Command/ListCommand.php @@ -41,8 +41,8 @@ public function __construct( protected function configure(): void { $this ->setName('groupfolders:list') - ->setDescription('List the configured Team folders') - ->addOption('user', 'u', InputArgument::OPTIONAL, 'List Team folders applicable for a user'); + ->setDescription('List the configured group folders') + ->addOption('user', 'u', InputArgument::OPTIONAL, 'List group folders applicable for a user'); parent::configure(); } diff --git a/lib/Command/Quota.php b/lib/Command/Quota.php index af817a3de..ebeb8d966 100644 --- a/lib/Command/Quota.php +++ b/lib/Command/Quota.php @@ -17,7 +17,7 @@ class Quota extends FolderCommand { protected function configure(): void { $this ->setName('groupfolders:quota') - ->setDescription('Edit the quota of a configured Team folder') + ->setDescription('Edit the quota of a configured group folder') ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to configure') ->addArgument('quota', InputArgument::REQUIRED, 'New value for the quota of the folder'); parent::configure(); diff --git a/lib/Command/Rename.php b/lib/Command/Rename.php index dccf76309..df6fe22d7 100644 --- a/lib/Command/Rename.php +++ b/lib/Command/Rename.php @@ -16,7 +16,7 @@ class Rename extends FolderCommand { protected function configure(): void { $this ->setName('groupfolders:rename') - ->setDescription('Rename Team folder') + ->setDescription('Rename group folder') ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to rename') ->addArgument('name', InputArgument::REQUIRED, 'New value name of the folder'); parent::configure(); diff --git a/lib/Command/Scan.php b/lib/Command/Scan.php index 956c2b4a7..5809fefa2 100644 --- a/lib/Command/Scan.php +++ b/lib/Command/Scan.php @@ -38,16 +38,16 @@ public function __construct( protected function configure(): void { $this ->setName('groupfolders:scan') - ->setDescription('Scan a Team folder for outside changes') + ->setDescription('Scan a group folder for outside changes') ->addArgument( 'folder_id', InputArgument::OPTIONAL, - 'Id of the Team folder to scan.' + 'Id of the group folder to scan.' )->addOption( 'all', null, InputOption::VALUE_NONE, - 'Scan all the Team folders.' + 'Scan all the group folders.' ) ->addOption( 'path', @@ -67,12 +67,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int $folderId = $input->getArgument('folder_id'); $all = $input->getOption('all'); if ($folderId === null && !$all) { - $output->writeln('Either a Team folder id or --all needs to be provided'); + $output->writeln('Either a group folder id or --all needs to be provided'); return -1; } if ($folderId !== null && $all) { - $output->writeln('Specifying a Team folder id and --all are mutually exclusive'); + $output->writeln('Specifying a group folder id and --all are mutually exclusive'); return -1; } @@ -131,9 +131,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int /** @var Scanner&\OC\Hooks\BasicEmitter $scanner */ $scanner = $storage->getScanner(); - $output->writeln("Scanning Team folder with id\t$folderId - $type", OutputInterface::VERBOSITY_VERBOSE); + $output->writeln("Scanning group folder with id\t$folderId - $type", OutputInterface::VERBOSITY_VERBOSE); if ($scanner instanceof ObjectStoreScanner) { - $output->writeln('Scanning Team folders using an object store as primary storage is not supported.'); + $output->writeln('Scanning group folders using an object store as primary storage is not supported.'); return -1; } diff --git a/lib/Command/Trashbin/Cleanup.php b/lib/Command/Trashbin/Cleanup.php index db3abd446..60fe2f615 100644 --- a/lib/Command/Trashbin/Cleanup.php +++ b/lib/Command/Trashbin/Cleanup.php @@ -39,8 +39,8 @@ public function __construct( protected function configure(): void { $this ->setName('groupfolders:trashbin:cleanup') - ->setDescription('Empty the Team folder trashbin') - ->addArgument('folder_id', InputArgument::OPTIONAL, 'Id of the Team folder') + ->setDescription('Empty the group folder trashbin') + ->addArgument('folder_id', InputArgument::OPTIONAL, 'Id of the group folder') ->addOption('force', 'f', InputOption::VALUE_NONE, 'Skip confirmation'); parent::configure(); } @@ -48,7 +48,7 @@ protected function configure(): void { #[\Override] protected function execute(InputInterface $input, OutputInterface $output): int { if (!$this->trashBackend) { - $output->writeln('files_trashbin is disabled: Team folders trashbin is not available'); + $output->writeln('files_trashbin is disabled: Group folders trashbin is not available'); return -1; } @@ -64,7 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($folders as $folder) { if ($folder->id === $folderId) { - $question = new ConfirmationQuestion('Are you sure you want to empty the trashbin of your Team folder with id ' . $folderId . ', this can not be undone (y/N).', false); + $question = new ConfirmationQuestion('Are you sure you want to empty the trashbin of your group folder with id ' . $folderId . ', this can not be undone (y/N).', false); if (!$input->getOption('force') && !$helper->ask($input, $output, $question)) { return -1; } @@ -79,7 +79,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return -1; } else { - $question = new ConfirmationQuestion('Are you sure you want to empty the trashbin of your Team folders, this can not be undone (y/N).', false); + $question = new ConfirmationQuestion('Are you sure you want to empty the trashbin of your group folders, this can not be undone (y/N).', false); if (!$input->getOption('force') && !$helper->ask($input, $output, $question)) { return -1; } diff --git a/lib/Controller/FolderController.php b/lib/Controller/FolderController.php index a2634b0d3..c49352817 100644 --- a/lib/Controller/FolderController.php +++ b/lib/Controller/FolderController.php @@ -415,9 +415,9 @@ public function removeGroup(int $id, string $group): DataResponse { public function setPermissions(int $id, string $group, int $permissions): DataResponse { $folder = $this->checkedGetFolder($id); - // The owning team's permissions on a team space are fixed. + // The owning team's permissions on a team folder are fixed. if ($folder->isTeamSpace() && $folder->teamCircleId === $group) { - throw new OCSForbiddenException('This team space belongs to this team and its permissions cannot be changed independently; unlink the team space from the team first'); + throw new OCSForbiddenException('This team folder belongs to this team and its permissions cannot be changed independently; unlink the team folder from the team first'); } $this->manager->setGroupPermissions($id, $group, $permissions); diff --git a/lib/DAV/ACLPlugin.php b/lib/DAV/ACLPlugin.php index 5d3159815..f09064aae 100644 --- a/lib/DAV/ACLPlugin.php +++ b/lib/DAV/ACLPlugin.php @@ -272,13 +272,13 @@ public function propPatch(string $path, PropPatch $propPatch): void { $formattedRules = array_map(fn (Rule $rule): string => $rule->getUserMapping()->getType() . ' ' . $rule->getUserMapping()->getDisplayName() . ': ' . $rule->formatPermissions(), $rules); if (count($formattedRules)) { $formattedRules = implode(', ', $formattedRules); - $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('The advanced permissions for "%s" in Team folder with ID %d was set to "%s"', [ + $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('The advanced permissions for "%s" in group folder with ID %d was set to "%s"', [ $fileInfo->getInternalPath(), $mount->getFolderId(), $formattedRules, ])); } else { - $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('The advanced permissions for "%s" in Team folder with ID %d was cleared', [ + $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('The advanced permissions for "%s" in group folder with ID %d was cleared', [ $fileInfo->getInternalPath(), $mount->getFolderId(), ])); diff --git a/lib/Folder/FolderDefinition.php b/lib/Folder/FolderDefinition.php index 79c3e4605..89433f0f7 100644 --- a/lib/Folder/FolderDefinition.php +++ b/lib/Folder/FolderDefinition.php @@ -11,7 +11,7 @@ class FolderDefinition { /** * @param array{separate-storage?: bool} $options - * @param ?string $teamCircleId The circle single id this team space belongs to; null for regular team folders. + * @param ?string $teamCircleId The circle single id this team folder belongs to; null for regular group folders. */ public function __construct( public readonly int $id, @@ -31,7 +31,7 @@ public function useSeparateStorage(): bool { } /** - * Whether this folder belongs to a team (i.e. is a team space) and + * Whether this folder belongs to a team (i.e. is a team folder) and * therefore cannot be deleted or renamed independently of that team. */ public function isTeamSpace(): bool { diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php index 52a8a2079..551cde17d 100644 --- a/lib/Folder/FolderManager.php +++ b/lib/Folder/FolderManager.php @@ -898,7 +898,7 @@ public function trimMountpoint(string $mountpoint): string { $mountpoint = FileSystem::normalizePath($mountpoint); - // Used to mount a Team folder at the user's home. + // Used to mount a group folder at the user's home. if ($mountpoint === '/') { return $mountpoint; } @@ -982,14 +982,14 @@ public function addApplicableGroup(int $folderId, string $groupId): void { * @throws Exception */ public function removeApplicableGroup(int $folderId, string $groupId): void { - // Removing the owning team's access would orphan the team space from + // Removing the owning team's access would orphan the team folder from // its team. Block it; the folder must be unlinked from its team first // (which clears team_circle_id and then removes the applicable group). $teamCircleId = $this->getTeamCircleId($folderId); if ($teamCircleId !== null && $teamCircleId === $groupId) { throw new Exception( - 'This team space belongs to this team and its access cannot be removed independently; ' - . 'unlink the team space from the team first', + 'This team folder belongs to this team and its access cannot be removed independently; ' + . 'unlink the team folder from the team first', ); } @@ -1016,13 +1016,13 @@ public function removeApplicableGroup(int $folderId, string $groupId): void { * @throws Exception */ public function setGroupPermissions(int $folderId, string $groupId, int $permissions): void { - // The owning team's permissions on a team space are fixed; they must + // The owning team's permissions on a team folder are fixed; they must // not be lowered or removed independently of the team-space link. $teamCircleId = $this->getTeamCircleId($folderId); if ($teamCircleId !== null && $teamCircleId === $groupId) { throw new Exception( - 'This team space belongs to this team and its permissions cannot be changed independently; ' - . 'unlink the team space from the team first', + 'This team folder belongs to this team and its permissions cannot be changed independently; ' + . 'unlink the team folder from the team first', ); } @@ -1081,12 +1081,12 @@ public function setManageACL(int $folderId, string $type, string $id, bool $mana * @throws Exception */ public function removeFolder(int $folderId): void { - // Prevent deletion of team spaces (folders that belong to a team). - // The owning app is responsible for unlinking the team space from its team + // Prevent deletion of team folders (folders that belong to a team). + // The owning app is responsible for unlinking the team folder from its team // before deleting it. $folder = $this->getFolder($folderId); if ($folder !== null && $folder->isTeamSpace()) { - throw new Exception('This team space belongs to a team and cannot be deleted directly; unlink it from its team first'); + throw new Exception('This team folder belongs to a team and cannot be deleted directly; unlink it from its team first'); } $this->connection->beginTransaction(); @@ -1162,10 +1162,10 @@ public function setFolderOptions(int $folderId, array $options): void { * @throws Exception */ public function renameFolder(int $folderId, string $newMountPoint): void { - // Prevent renaming of team spaces (folders that belong to a team). + // Prevent renaming of team folders (folders that belong to a team). $folder = $this->getFolder($folderId); if ($folder !== null && $folder->isTeamSpace()) { - throw new Exception('This team space belongs to a team and cannot be renamed; unlink it from its team first'); + throw new Exception('This team folder belongs to a team and cannot be renamed; unlink it from its team first'); } $query = $this->connection->getQueryBuilder(); @@ -1248,7 +1248,7 @@ public function deleteCircle(string $circleId): void { } /** - * Look up the team space that belongs to the given team (circle single id) + * Look up the team folder that belongs to the given team (circle single id) * via the `team_circle_id` column. * * This is the single source of truth for the "folder belongs to team" @@ -1286,7 +1286,7 @@ public function getFolderIdByTeamCircleId(string $circleId): ?int { public function setTeamCircleId(int $folderId, string $circleId): void { $existingFolderId = $this->getFolderIdByTeamCircleId($circleId); if ($existingFolderId !== null && $existingFolderId !== $folderId) { - throw new Exception('This team already has a team space'); + throw new Exception('This team already has a team folder'); } $query = $this->connection->getQueryBuilder(); @@ -1297,7 +1297,7 @@ public function setTeamCircleId(int $folderId, string $circleId): void { } /** - * Clear the team ownership of a team space by resetting the + * Clear the team ownership of a team folder by resetting the * `team_circle_id` column to null. */ public function clearTeamCircleId(int $folderId): void { @@ -1312,7 +1312,7 @@ public function clearTeamCircleId(int $folderId): void { * Reject a mutation that would change the sharing, rights, or ownership of * a folder that belongs to a team. * - * Team spaces are meant to host the team-specific apps and data of their + * Team folders are meant to host the team-specific apps and data of their * owning team: they must not be shared with other teams/groups, have their * permissions or ACL management changed, or have their quota altered * independently of the team-space policy. The owning team's access can @@ -1331,7 +1331,7 @@ public function clearTeamCircleId(int $folderId): void { private function assertNotTeamSpace(int $folderId, string $operation): void { if ($this->getTeamCircleId($folderId) !== null) { throw new Exception( - 'This team space belongs to a team and its ' . $operation + 'This team folder belongs to a team and its ' . $operation . ' cannot be changed independently; unlink it from its team first', ); } diff --git a/lib/Migration/RepairMisplacedTrashItemsStep.php b/lib/Migration/RepairMisplacedTrashItemsStep.php index a3f1359bd..e70b022ae 100644 --- a/lib/Migration/RepairMisplacedTrashItemsStep.php +++ b/lib/Migration/RepairMisplacedTrashItemsStep.php @@ -16,7 +16,7 @@ /** * One-off repair to find trash items whose `group_folders_trash` row was - * updated to point to a new Team folder but the actual entries weren't. + * updated to point to a new group folder but the actual entries weren't. */ class RepairMisplacedTrashItemsStep implements IRepairStep { public function __construct( @@ -28,7 +28,7 @@ public function __construct( #[\Override] public function getName(): string { - return 'Repair team folder trash item to their correct storage'; + return 'Repair group folder trash item to their correct storage'; } #[\Override] diff --git a/lib/Migration/TrimMountpointsRepairStep.php b/lib/Migration/TrimMountpointsRepairStep.php index f47490675..ee29419b3 100644 --- a/lib/Migration/TrimMountpointsRepairStep.php +++ b/lib/Migration/TrimMountpointsRepairStep.php @@ -22,7 +22,7 @@ public function __construct( #[\Override] public function getName(): string { - return 'Fix invalid Team folders mountpoints'; + return 'Fix invalid group folder mountpoints'; } #[\Override] diff --git a/lib/Migration/Version104000Date20180918132853.php b/lib/Migration/Version104000Date20180918132853.php index 2631c3591..96ad76d0a 100644 --- a/lib/Migration/Version104000Date20180918132853.php +++ b/lib/Migration/Version104000Date20180918132853.php @@ -21,7 +21,7 @@ public function name(): string { #[\Override] public function description(): string { - return 'Adds table to store trashbin information for Team folders'; + return 'Adds table to store trashbin information for group folders'; } #[\Override] diff --git a/lib/Migration/Version201000Date20190111132839.php b/lib/Migration/Version201000Date20190111132839.php index 32de733c7..b75d1d3b1 100644 --- a/lib/Migration/Version201000Date20190111132839.php +++ b/lib/Migration/Version201000Date20190111132839.php @@ -21,7 +21,7 @@ public function name(): string { #[\Override] public function description(): string { - return 'Adds table to store ACL information for Team folders'; + return 'Adds table to store ACL information for group folders'; } #[\Override] diff --git a/lib/Migration/Version2300000Date20260720000001.php b/lib/Migration/Version2300000Date20260720000001.php index 4300b4e30..115a79cde 100644 --- a/lib/Migration/Version2300000Date20260720000001.php +++ b/lib/Migration/Version2300000Date20260720000001.php @@ -24,7 +24,7 @@ * "this folder belongs to a team" relationship is stored as an explicit, * indexed, queryable column. */ -#[AddColumn('group_folders', 'team_circle_id', ColumnType::STRING, 'the circle single id this team space belongs to (null for regular team folders)')] +#[AddColumn('group_folders', 'team_circle_id', ColumnType::STRING, 'the circle single id this team folder belongs to (null for regular group folders)')] #[AddIndex('group_folders', IndexType::UNIQUE, 'unique team circle id to prevent a team owning multiple folders')] class Version2300000Date20260720000001 extends SimpleMigrationStep { #[\Override] diff --git a/lib/Settings/Section.php b/lib/Settings/Section.php index ed5994f8f..304c61fcc 100644 --- a/lib/Settings/Section.php +++ b/lib/Settings/Section.php @@ -27,7 +27,7 @@ public function getID(): string { #[\Override] public function getName(): string { - return $this->l->t('Team folders'); + return $this->l->t('Group folders'); } #[\Override] diff --git a/lib/TeamSpace/TeamSpaceProvider.php b/lib/TeamSpace/TeamSpaceProvider.php index 09c3aba22..0c5222c06 100644 --- a/lib/TeamSpace/TeamSpaceProvider.php +++ b/lib/TeamSpace/TeamSpaceProvider.php @@ -31,7 +31,7 @@ public function getId(): string { #[\Override] public function getName(): string { - return $this->l10n->t('Team spaces'); + return $this->l10n->t('Team folders'); } #[\Override] @@ -50,7 +50,7 @@ public function createTeamFolder(Team $team, int $quota = 0): TeamFolder { $folder = $this->getTeamFolder($team->getId()); if ($folder === null) { - throw new \RuntimeException('Created team space could not be found'); + throw new \RuntimeException('Created team folder could not be found'); } return $folder; diff --git a/lib/TeamSpace/TeamSpaceService.php b/lib/TeamSpace/TeamSpaceService.php index 6d5fc2cae..82a79d451 100644 --- a/lib/TeamSpace/TeamSpaceService.php +++ b/lib/TeamSpace/TeamSpaceService.php @@ -17,7 +17,7 @@ use Psr\Log\LoggerInterface; /** - * Orchestrates the lifecycle of team spaces: team folders that belong to a + * Orchestrates the lifecycle of team folders that belong to a * team (circle). * * This is the single owner of the team-space lifecycle. The "folder belongs @@ -68,7 +68,7 @@ public function createTeamSpace(string $circleId, string $mountPoint, int $quota } catch (\Exception $e) { $existingFolderId = $this->folderManager->getFolderIdByTeamCircleId($circleId); $this->logger->error( - 'Failed to configure team space, rolling back creation', + 'Failed to configure team folder, rolling back creation', [ 'circleId' => $circleId, 'folderId' => $folderId, @@ -82,7 +82,7 @@ public function createTeamSpace(string $circleId, string $mountPoint, int $quota $this->folderManager->removeFolder($folderId); } catch (\Exception $rollbackException) { $this->logger->error( - 'Could not roll back team space creation, manual cleanup required', + 'Could not roll back team folder creation, manual cleanup required', [ 'circleId' => $circleId, 'folderId' => $folderId, @@ -92,7 +92,7 @@ public function createTeamSpace(string $circleId, string $mountPoint, int $quota } if ($existingFolderId !== null) { - $this->logger->info('Another request created the team space first; using the existing folder', [ + $this->logger->info('Another request created the team folder first; using the existing folder', [ 'circleId' => $circleId, 'folderId' => $existingFolderId, ]); @@ -105,14 +105,14 @@ public function createTeamSpace(string $circleId, string $mountPoint, int $quota } /** - * Create the folder reserved for app data in a team space. + * Create the folder reserved for app data in a team folder. * * @throws \RuntimeException when the folder cannot be created. */ private function createAppDirectory(int $folderId): void { $teamSpace = $this->folderManager->getFolder($folderId); if ($teamSpace === null) { - throw new \RuntimeException('Created team space could not be found'); + throw new \RuntimeException('Created team folder could not be found'); } $storage = $this->folderStorageManager->getBaseStorageForFolder( @@ -126,18 +126,18 @@ private function createAppDirectory(int $folderId): void { } if (!$storage->mkdir(self::APP_DIRECTORY_NAME)) { - throw new \RuntimeException('Could not create ' . self::APP_DIRECTORY_NAME . ' folder for team space'); + throw new \RuntimeException('Could not create ' . self::APP_DIRECTORY_NAME . ' folder for team folder'); } $storage->getScanner()->scan(self::APP_DIRECTORY_NAME); } /** - * Unlink the team space from a team without deleting the folder. + * Unlink the team folder from a team without deleting the folder. * * Clears the `team_circle_id` column and removes the applicable-group entry * so the team no longer has access. The folder and its contents are - * preserved and become a regular team folder that can be managed via the + * preserved and become a regular group folder that can be managed via the * groupfolders admin UI. * * This is the path used when a team is destroyed: the folder is kept so an @@ -155,7 +155,7 @@ public function unlinkTeamSpace(string $circleId): ?int { $this->folderManager->clearTeamCircleId($folderId); $this->folderManager->removeApplicableGroup($folderId, $circleId); - $this->logger->info('Unlinked team space from circle', [ + $this->logger->info('Unlinked team folder from circle', [ 'circleId' => $circleId, 'folderId' => $folderId, ]); @@ -164,7 +164,7 @@ public function unlinkTeamSpace(string $circleId): ?int { } /** - * Remove the team space that belongs to a team, deleting its contents. + * Remove the team folder that belongs to a team, deleting its contents. * * Clears the `team_circle_id` column first so the `isTeamSpace` guard in * {@see FolderManager::removeFolder()} does not reject the deletion, then @@ -182,7 +182,7 @@ public function removeTeamSpace(string $circleId): bool { $this->folderManager->clearTeamCircleId($folderId); $this->folderManager->removeApplicableGroup($folderId, $circleId); $this->folderManager->removeFolder($folderId); - $this->logger->info('Removed team space for circle', [ + $this->logger->info('Removed team folder for circle', [ 'circleId' => $circleId, 'folderId' => $folderId, ]); @@ -191,7 +191,7 @@ public function removeTeamSpace(string $circleId): bool { } /** - * Create a team space for a team that predates the feature (or return the + * Create a team folder for a team that predates the feature (or return the * existing one if the team already has a folder). * * Idempotent: if the team already owns a folder, its id is returned without @@ -216,7 +216,7 @@ public function upgradeTeamSpace(Team $team, int $quota = 0): int { } /** - * Find the team space that belongs to the given team. + * Find the team folder that belongs to the given team. * * @return TeamFolder|null */ @@ -239,7 +239,7 @@ public function getTeamSpaceForCircle(string $circleId): ?TeamFolder { /** * Return all group folders directly accessible to the given team. * - * This includes the team's dedicated team space as well as regular group + * This includes the team's dedicated team folder as well as regular group * folders that have been assigned to the team's circle. * * @return list @@ -252,14 +252,14 @@ public function getGroupFoldersForCircle(string $circleId): array { } /** - * Whether the given circle (looked up by single id) owns a team space. + * Whether the given circle (looked up by single id) owns a team folder. */ public function hasTeamSpace(string $circleId): bool { return $this->folderManager->getFolderIdByTeamCircleId($circleId) !== null; } /** - * Pick a non-empty base name for the team space mount point. + * Pick a non-empty base name for the team folder mount point. * * Tries the display name first, then the circle name, then the single id. */ diff --git a/lib/Trash/TrashBackend.php b/lib/Trash/TrashBackend.php index 5bae78243..fddadf25e 100644 --- a/lib/Trash/TrashBackend.php +++ b/lib/Trash/TrashBackend.php @@ -122,7 +122,7 @@ public function listTrashFolder(ITrashItem $folder): array { */ public function restoreItem(ITrashItem $item): void { if (!($item instanceof GroupTrashItem)) { - throw new \LogicException('Trying to restore normal trash item in Team folder trash backend'); + throw new \LogicException('Trying to restore normal trash item in group folder trash backend'); } $user = $item->getUser(); @@ -240,7 +240,7 @@ private function unlinkTrashNode(Node $node): bool { */ public function removeItem(ITrashItem $item): void { if (!($item instanceof GroupTrashItem)) { - throw new \LogicException('Trying to remove normal trash item in Team folder trash backend'); + throw new \LogicException('Trying to remove normal trash item in group folder trash backend'); } $user = $item->getUser(); @@ -334,7 +334,7 @@ public function moveToTrash(IStorage $storage, string $internalPath): bool { } else { // Move failed — clean up the DB record to avoid an orphaned trash entry $this->trashManager->removeItem($folderId, $name, $time); - throw new \Exception('Failed to move Team folder item to trash'); + throw new \Exception('Failed to move group folder item to trash'); } return true; @@ -364,7 +364,7 @@ private function userHasAccessToItem( private function getNodeForTrashItem(IUser $user, ITrashItem $trashItem): ?Node { if (!($trashItem instanceof GroupTrashItem)) { - throw new \LogicException('Trying to remove normal trash item in Team folder trash backend'); + throw new \LogicException('Trying to remove normal trash item in group folder trash backend'); } $folderId = $trashItem->folder->id; @@ -733,7 +733,7 @@ private function moveTrashItems(int $fromFolderId, int $toFolderId, string $from /** * Find trash items whose `group_folders_trash` row was updated to point to a - * new Team folder but the actual entries weren't. + * new group folder but the actual entries weren't. * * @return int the number of trash items that were moved */ diff --git a/lib/Versions/VersionsBackend.php b/lib/Versions/VersionsBackend.php index 2d6f58a15..fc4828036 100644 --- a/lib/Versions/VersionsBackend.php +++ b/lib/Versions/VersionsBackend.php @@ -72,7 +72,7 @@ private function getFolderForFile(FileInfo $file): FolderDefinition { return $storage->getFolder(); } - throw new \LogicException('Team folder version backend called for non Team folder file'); + throw new \LogicException('Group folder version backend called for non-group folder file'); } public function getVersionFolderForFile(FileInfo $file): Folder { @@ -122,7 +122,7 @@ public function getVersionsForFile(IUser $user, FileInfo $file): array { $versionsOnFS = $versionsFolder->getDirectoryListing(); foreach ($versionsOnFS as $version) { if ($version instanceof Folder) { - $this->logger->error('Found an unexpected subfolder inside the Team folder version folder.'); + $this->logger->error('Found an unexpected subfolder inside the group folder version folder.'); } $versionEntity = new GroupVersionEntity(); @@ -257,7 +257,7 @@ public function createVersion(IUser $user, FileInfo $file): void { public function rollback(IVersion $version): void { if (!($version instanceof GroupVersion)) { - throw new \LogicException('Trying to restore a version from a file not in a Team folder'); + throw new \LogicException('Trying to restore a version from a file not in a group folder'); } if (!$this->currentUserHasPermissions($version->getSourceFile(), \OCP\Constants::PERMISSION_UPDATE)) { diff --git a/src/actions/openGroupfolderAction.ts b/src/actions/openGroupfolderAction.ts index c3ed92617..4e80ef758 100644 --- a/src/actions/openGroupfolderAction.ts +++ b/src/actions/openGroupfolderAction.ts @@ -10,7 +10,7 @@ import { t } from '@nextcloud/l10n' export const action: IFileAction = { id: 'open-group-folders', - displayName: () => t('files', 'Open Team folder'), + displayName: () => t('files', 'Open group folder'), iconSvgInline: () => '', enabled: ({ view }) => view.id === appName, diff --git a/src/components/SharingSidebarView.vue b/src/components/SharingSidebarView.vue index 520d7dc83..8ef7095bf 100644 --- a/src/components/SharingSidebarView.vue +++ b/src/components/SharingSidebarView.vue @@ -297,7 +297,7 @@ async function changePermission(item: Rule, permission: number, state: number) {