From ac80cb8aad573385bdbc61bfc03b225fa051574a Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Tue, 8 Sep 2026 18:41:26 +0200 Subject: [PATCH 1/2] docs: add pages for teams, team folders and the Teams API Teams and team folders had no page in any manual. "Team folder" appeared 19 times across the three manuals - activity, encryption, primary storage, trashbin, automated tagging - always in passing and never defined, and the Teams API had no developer documentation at all even though it has existed since 29.0.0 and Files, Talk and Deck implement it. Adds one page per manual: - user: what a team is and is not, that it owns nothing until it has a team space, roles, and an FAQ - admin: team folders versus team spaces, which teams are eligible, the circles app settings that gate provisioning, detach versus delete, and an FAQ - developer: ITeamResourceProvider, ITeamManager, TeamResource and the ITeamFolderProvider added in 35.0.0, with registration and the existing implementations Assisted-by: AGENT:claude-opus-5[1m] Signed-off-by: Anna Larch --- admin_manual/configuration_files/index.rst | 1 + .../configuration_files/team_folders.rst | 112 +++++++++++++++++ developer_manual/digging_deeper/index.rst | 1 + developer_manual/digging_deeper/teams.rst | 114 ++++++++++++++++++ user_manual/groupware/index.rst | 1 + user_manual/groupware/teams.rst | 86 +++++++++++++ 6 files changed, 315 insertions(+) create mode 100644 admin_manual/configuration_files/team_folders.rst create mode 100644 developer_manual/digging_deeper/teams.rst create mode 100644 user_manual/groupware/teams.rst diff --git a/admin_manual/configuration_files/index.rst b/admin_manual/configuration_files/index.rst index 375c888d5f7..af493628a26 100644 --- a/admin_manual/configuration_files/index.rst +++ b/admin_manual/configuration_files/index.rst @@ -8,6 +8,7 @@ File sharing and management file_sharing_configuration federated_cloud_sharing_configuration + team_folders big_file_upload_configuration default_files_configuration primary_storage diff --git a/admin_manual/configuration_files/team_folders.rst b/admin_manual/configuration_files/team_folders.rst new file mode 100644 index 00000000000..61001b26751 --- /dev/null +++ b/admin_manual/configuration_files/team_folders.rst @@ -0,0 +1,112 @@ +============================ +Team folders and team spaces +============================ + +Team folders are folders that are mounted for a set of groups or teams rather than owned by one account. They are +provided by the **Team folders** app, whose app id is ``groupfolders`` - the name you will see in :command:`occ` +commands, in the app store and in log entries. + +A **team space** is a team folder in an exclusive relationship with a single team: it belongs to that team, follows +the team's membership, and has its own quota. Team spaces were introduced in Nextcloud 35. + +Team folder or team space? +-------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 30 35 35 + + * - + - Team folder + - Team space + * - Mounted for + - any number of groups and teams + - exactly one team + * - Created by + - an administrator or a delegated group + - the team owner, or an administrator + * - Membership follows + - the groups and teams you assign + - the team's own membership + * - Quota + - set per folder + - set per space + +Which teams can have a space +---------------------------- + +A team is not eligible for a team space if it is: + +- a **personal** team, +- a **hidden** team, +- a **system** team, or +- a team provided by an **external backend**. + +For every other team, the **owner** or a server administrator can add a space. Members, moderators and team admins +cannot. + +Configuration +------------- + +Team space provisioning is controlled by two app settings of the ``circles`` app. Neither is exposed in the +administration interface, so set them with :command:`occ`: + +.. code-block:: bash + + # allow teams to be created with a space, and existing teams to be upgraded (default: yes) + occ config:app:set circles team_folder_auto_create --value=1 --type=boolean + + # default quota in bytes for a new team space; 0 means unlimited (default: 0) + occ config:app:set circles team_folder_default_quota --value=0 --type=integer + +With provisioning disabled, requests to create or upgrade a team space are refused, and existing spaces are left +untouched. + +.. note:: + + A team space is only created at team-creation time if the person creating the team asks for one. Teams created + without a space are not upgraded automatically; someone has to upgrade them deliberately. + +Detaching versus deleting +------------------------- + +.. warning:: + + These two actions look similar and are not. + +**Detaching** ends the exclusive relationship and **keeps the folder and its contents**. The folder remains as an +ordinary team folder that you can reassign to groups, teams or nobody. This is the intended way to recover access to +the contents of a team that is being disbanded. + +**Deleting** removes the team folder and everything in it. + +How team folders interact with other features +--------------------------------------------- + +Team folders behave differently from ordinary user storage in several areas that are documented elsewhere: + +- :doc:`encryption_configuration` - encrypting team folders and other non-home mount points. +- :doc:`primary_storage` - how team folder contents are stored on object storage. +- :doc:`trashbin_configuration` - deleted files from a team folder go to the team folder's own trash. +- :doc:`../configuration_server/activity_configuration` - activities for team folders, and why they can be missing. + +Frequently asked questions +-------------------------- + +**A user says their team cannot own any files. Is that expected?** + Yes. A team is a membership list; anything shared with it stays owned by the account that shared it. For storage + owned by the team, the team needs a space, which its owner can add if provisioning is enabled. + +**Why is the option to add a space missing for one particular team?** + Either provisioning is disabled server-wide, or the team is not eligible - personal, hidden, system and + backend-provided teams cannot have a space. The person asking may also not be the team's owner. + +**Can I convert an existing team folder into a team's space?** + Yes. An existing team folder can be linked to a team instead of creating a new one, which is the way to migrate a + folder that predates team spaces. + +**How do I take a space away from a team without losing the data?** + Detach it. The folder and its contents survive; only the exclusive relationship ends. + +**Does a team space count against the members' quotas?** + No. It has its own quota, set per space, where zero means unlimited. diff --git a/developer_manual/digging_deeper/index.rst b/developer_manual/digging_deeper/index.rst index bf10a488549..0643bf0393d 100644 --- a/developer_manual/digging_deeper/index.rst +++ b/developer_manual/digging_deeper/index.rst @@ -10,6 +10,7 @@ Digging deeper auth direct_editing groupware_workflows + teams discovery devtools internals diff --git a/developer_manual/digging_deeper/teams.rst b/developer_manual/digging_deeper/teams.rst new file mode 100644 index 00000000000..4c2ac674cc0 --- /dev/null +++ b/developer_manual/digging_deeper/teams.rst @@ -0,0 +1,114 @@ +===== +Teams +===== + +Teams are user-defined groups of accounts, provided by the **Teams** app (app id ``circles``). Apps do not store +anything in a team themselves: they *contribute* to it, by telling the server which of their own resources are shared +with a given team. A team's overview is assembled from every app that does so. + +The API lives in the ``OCP\Teams`` namespace and has been available since Nextcloud 29. + +Contributing resources to a team +-------------------------------- + +Implement ``OCP\Teams\ITeamResourceProvider`` and register it from your ``Application`` class: + +.. code-block:: php + + registerTeamResourceProvider(MyAppResourceProvider::class); + } + + public function boot(IBootContext $context): void { + } + } + +The provider answers three questions about your app's resources: + +.. code-block:: php + + interface ITeamResourceProvider { + public function getId(): string; // your provider id, e.g. 'deck' + public function getName(): string; // translated, shown to users + public function getIconSvg(): string; // inline SVG + + /** @return TeamResource[] resources of yours shared with this team */ + public function getSharedWith(string $teamId): array; + + public function isSharedWithTeam(string $teamId, string $resourceId): bool; + + /** @return string[] team ids a resource of yours is shared with */ + public function getTeamsForResource(string $resourceId): array; + } + +Each resource is returned as an ``OCP\Teams\TeamResource``, carrying the provider, an id, a label, a URL and an icon +- as inline SVG, a URL or an emoji. + +.. note:: + + A resource contributed this way is still owned by whoever created it. Nothing about registering a provider makes + the team the owner of anything. + +Reading teams and their resources +--------------------------------- + +``OCP\Teams\ITeamManager`` is the consumer side: + +.. code-block:: php + + $providers = $teamManager->getProviders(); // since 29.0.0 + $provider = $teamManager->getProvider('deck'); // since 29.0.0 + $resources = $teamManager->getSharedWith($teamId, $userId); // since 29.0.0 + $teams = $teamManager->getTeamsForResource('deck', $boardId, $userId); // since 29.0.0 + $teams = $teamManager->getTeamsForUser($userId); // since 33.0.0 + $lists = $teamManager->getSharedWithList($teams, $userId, $resourceId); // since 33.0.0 + $members = $teamManager->getMembersOfTeam($teamId, $userId); // since 34.0.0 + +``getSharedWithList()`` gained its ``$resourceId`` parameter in 34.0.0, so guard for the server version if your app +supports older releases. + +The team folder provider +------------------------ + +Since Nextcloud 35 a team can also have **one exclusive folder** - a team space. That folder is supplied by an +implementation of ``OCP\Teams\ITeamFolderProvider``, which extends ``ITeamResourceProvider``: + +.. code-block:: php + + interface ITeamFolderProvider extends ITeamResourceProvider { + public function getTeamFolder(string $teamId): ?TeamFolder; + public function createTeamFolder(Team $team, int $quota = 0): TeamFolder; // quota 0 = unlimited + public function getLinkableTeamFolders(string $circleId): array; + public function linkTeamFolder(string $circleId, int $folderId): TeamFolder; + public function updateTeamFolderQuota(string $teamId, int $quota): TeamFolder; + public function unlinkTeamFolder(string $teamId): ?TeamFolder; // keeps the folder + public function removeTeamFolder(string $teamId): bool; // deletes the folder + } + +Implementations are registered the same way as any other resource provider, through +``registerTeamResourceProvider()``. Retrieve the active one with ``ITeamManager::getTeamFolderProvider()``, which +returns ``null`` when no app provides team folders - always handle that case. + +.. warning:: + + ``unlinkTeamFolder()`` ends the relationship and preserves the folder and its contents; ``removeTeamFolder()`` + deletes them. If you expose either in a user interface, make the difference obvious. + +Implementations to look at +-------------------------- + +- **Files** - ``FileSharingTeamResourceProvider`` in the ``circles`` app, for files and folders shared with a team. +- **Talk** - ``TalkTeamResourceProvider`` in ``spreed``, for conversations. +- **Deck** - ``DeckTeamResourceProvider``, for boards. +- **Team folders** - ``TeamSpaceProvider`` in ``groupfolders``, the reference implementation of + ``ITeamFolderProvider``. diff --git a/user_manual/groupware/index.rst b/user_manual/groupware/index.rst index abfea4355be..ce5d4cdf3d2 100644 --- a/user_manual/groupware/index.rst +++ b/user_manual/groupware/index.rst @@ -15,6 +15,7 @@ You can find out more about Nextcloud Groupware `on our website