diff --git a/appinfo/routes.php b/appinfo/routes.php
index 269682834..61d5b44d1 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -127,6 +127,14 @@
'apiVersion' => 'v2.2'
]
],
+ [
+ 'name' => 'api#transferOwner',
+ 'url' => '/api/{apiVersion}/form/transfer',
+ 'verb' => 'POST',
+ 'requirements' => [
+ 'apiVersion' => 'v2.2'
+ ]
+ ],
[
'name' => 'api#deleteForm',
'url' => '/api/{apiVersion}/form/{id}',
diff --git a/docs/API.md b/docs/API.md
index 5871dd534..4de86d4de 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -221,6 +221,20 @@ Update a single or multiple properties of a form-object. Concerns **only** the F
```
"data": 3
```
+### Transfer form ownership
+Transfer the ownership of a form to another user
+- Endpoint: `/api/v2.2/form/transfer`
+- Method: `POST`
+- Parameters:
+ | Parameter | Type | Description |
+ |-----------|---------|-------------|
+ | _formId_ | Integer | ID of the form to tranfer |
+ | _uid_ | Integer | ID of the new form owner |
+- Restrictions: The initiator must be the current form owner.
+- Response: **Status-Code OK**, as well as the id of the new owner.
+```
+"data": "user1"
+```
### Delete a form
- Endpoint: `/api/v2.2/form/{id}`
diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php
index d5abc9ed6..a777751e4 100644
--- a/lib/Controller/ApiController.php
+++ b/lib/Controller/ApiController.php
@@ -51,6 +51,7 @@
use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCSController;
+use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\IL10N;
use OCP\IRequest;
@@ -351,6 +352,50 @@ public function updateForm(int $id, array $keyValuePairs): DataResponse {
return new DataResponse($form->getId());
}
+ /**
+ * @NoAdminRequired
+ *
+ * Transfer ownership of a form to another user
+ *
+ * @param int $formId id of the form to update
+ * @param string $uid id of the new owner
+ * @return DataResponse
+ * @throws OCSBadRequestException
+ * @throws OCSForbiddenException
+ */
+ public function transferOwner(int $formId, string $uid): DataResponse {
+ $this->logger->debug('Updating owner: formId: {formId}, userId: {uid}', [
+ 'formId' => $formId,
+ 'uid' => $uid
+ ]);
+
+ try {
+ $form = $this->formMapper->findById($formId);
+ } catch (IMapperException $e) {
+ $this->logger->debug('Could not find form');
+ throw new NotFoundException('Could not find form');
+ }
+
+ $user = $this->userManager->get($uid);
+ if($user == null) {
+ $this->logger->debug('Could not find new form owner');
+ throw new OCSBadRequestException('Could not find new form owner');
+ }
+
+ if ($form->getOwnerId() !== $this->currentUser->getUID()) {
+ $this->logger->debug('This form is not owned by the current user');
+ throw new OCSForbiddenException('This form is not owned by the current user');
+ }
+
+ // update form owner
+ $form->setOwnerId($uid);
+
+ // Update changed Columns in Db.
+ $this->formMapper->update($form);
+
+ return new DataResponse($form->getOwnerId());
+ }
+
/**
* @CORS
* @NoAdminRequired
diff --git a/src/Forms.vue b/src/Forms.vue
index e3c400f54..d62c43dbe 100644
--- a/src/Forms.vue
+++ b/src/Forms.vue
@@ -230,10 +230,12 @@ export default {
mounted() {
subscribe('forms:last-updated:set', (id) => this.onLastUpdatedByEventBus(id))
+ subscribe('forms:ownership-transfered', (id) => this.onDeleteForm(id))
},
unmounted() {
unsubscribe('forms:last-updated:set', (id) => this.onLastUpdatedByEventBus(id))
+ unsubscribe('forms:ownership-transfered', (id) => this.onDeleteForm(id))
},
methods: {
diff --git a/src/components/SidebarTabs/SettingsSidebarTab.vue b/src/components/SidebarTabs/SettingsSidebarTab.vue
index a94133189..e6ca684f9 100644
--- a/src/components/SidebarTabs/SettingsSidebarTab.vue
+++ b/src/components/SidebarTabs/SettingsSidebarTab.vue
@@ -88,6 +88,8 @@
{{ t('forms', 'Message to show after a user submitted the form. Please note that the message will not be translated!') }}
+
+
@@ -96,6 +98,7 @@ import moment from '@nextcloud/moment'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcDateTimePicker from '@nextcloud/vue/dist/Components/NcDateTimePicker.js'
import ShareTypes from '../../mixins/ShareTypes.js'
+import TransferOwnership from './TransferOwnership.vue'
import { directive as ClickOutside } from 'v-click-outside'
import { loadState } from '@nextcloud/initial-state'
@@ -104,6 +107,7 @@ export default {
components: {
NcCheckboxRadioSwitch,
NcDateTimePicker,
+ TransferOwnership,
},
directives: {
@@ -286,6 +290,11 @@ export default {
margin-inline-start: 40px;
}
+.sidebar-tabs__content {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
.submission-message {
&__description {
color: var(--color-text-maxcontrast);
diff --git a/src/components/SidebarTabs/SharingSearchDiv.vue b/src/components/SidebarTabs/SharingSearchDiv.vue
index f82cc7ee8..e6c0d849d 100644
--- a/src/components/SidebarTabs/SharingSearchDiv.vue
+++ b/src/components/SidebarTabs/SharingSearchDiv.vue
@@ -41,22 +41,16 @@
diff --git a/src/components/SidebarTabs/TransferOwnership.vue b/src/components/SidebarTabs/TransferOwnership.vue
new file mode 100644
index 000000000..7cc2ac229
--- /dev/null
+++ b/src/components/SidebarTabs/TransferOwnership.vue
@@ -0,0 +1,182 @@
+
+
+
+