-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor: Move personal user settings page to Vue
Signed-off-by: codewithvk <[email protected]>
- Loading branch information
1 parent
705cdf6
commit ca586cb
Showing
4 changed files
with
362 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<!-- | ||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors | ||
- SPDX-License-Identifier: AGPL-3.0-or-later | ||
--> | ||
|
||
<template> | ||
<p> | ||
<label :for="id"> | ||
{{ label }} | ||
</label> | ||
<br> | ||
<textarea :id="id" | ||
v-model="localValue" | ||
:name="name" /> | ||
<br> | ||
<button :id="id + 'Save'" @click="onClickSave"> | ||
<span :title="saveTooltip" data-toggle="tooltip"> | ||
Save | ||
</span> | ||
</button> | ||
|
||
<button :id="id + 'Remove'" @click="onClickRemove"> | ||
<span class="icon-delete" | ||
:title="removeTooltip" | ||
data-toggle="tooltip" /> | ||
</button> | ||
</p> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
name: 'DocSigningField', | ||
props: { | ||
id: { | ||
type: String, | ||
required: true, | ||
}, | ||
name: { | ||
type: String, | ||
default: '', | ||
}, | ||
label: { | ||
type: String, | ||
required: true, | ||
}, | ||
value: { | ||
type: String, | ||
default: '', | ||
}, | ||
saveTooltip: { | ||
type: String, | ||
default: 'Save', | ||
}, | ||
removeTooltip: { | ||
type: String, | ||
default: 'Remove', | ||
}, | ||
}, | ||
data() { | ||
return { | ||
localValue: this.value, | ||
} | ||
}, | ||
watch: { | ||
value(newVal) { | ||
this.localValue = newVal | ||
}, | ||
}, | ||
methods: { | ||
onClickSave() { | ||
this.$emit('save', this.localValue) | ||
}, | ||
onClickRemove() { | ||
this.$emit('remove') | ||
}, | ||
}, | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
<!-- | ||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors | ||
- SPDX-License-Identifier: AGPL-3.0-or-later | ||
--> | ||
|
||
<template> | ||
<div id="richdocuments" class="section"> | ||
<h2> | ||
{{ t('richdocuments', 'Nextcloud Office') }} | ||
</h2> | ||
|
||
<span id="documents-admin-msg" class="msg" /> | ||
|
||
<!-- Template folder selection --> | ||
<p> | ||
<label for="templateInputField"> | ||
{{ t('richdocuments', 'Select a template directory') }} | ||
</label><br> | ||
<input id="templateInputField" | ||
type="text" | ||
name="templateInputField" | ||
:value="templateFolder" | ||
disabled> | ||
<button id="templateSelectButton" | ||
@click="onTemplateSelectButtonClick"> | ||
<span class="icon-folder" | ||
:title="t('richdocuments', 'Select a personal template folder')" | ||
data-toggle="tooltip" /> | ||
</button> | ||
<button id="templateResetButton" | ||
@click="resetTemplate"> | ||
<span class="icon-delete" | ||
:title="t('richdocuments', 'Remove personal template folder')" | ||
data-toggle="tooltip" /> | ||
</button> | ||
</p> | ||
<p> | ||
<em> | ||
{{ t('richdocuments', 'Templates inside of this directory will be added to the template selector of Nextcloud Office.') }} | ||
</em> | ||
</p> | ||
|
||
<!-- Zotero --> | ||
<p><strong>{{ t('richdocuments', 'Zotero') }}</strong></p> | ||
<template v-if="hasZoteroSupport"> | ||
<div class="input-wrapper"> | ||
<p> | ||
<label for="zoteroAPIKeyField"> | ||
{{ t('richdocuments', 'Enter Zotero API Key') }} | ||
</label><br> | ||
<input id="zoteroAPIKeyField" | ||
v-model="zoteroAPIKey" | ||
type="text" | ||
name="zoteroAPIKeyField"> | ||
<button id="zoteroAPIKeySave" | ||
@click="saveZoteroAPIKey"> | ||
<span :title="t('richdocuments', 'Save Zotero API key')" data-toggle="tooltip"> | ||
Save | ||
</span> | ||
</button> | ||
<button id="zoteroAPIKeyRemove" | ||
@click="resetZoteroAPI"> | ||
<span class="icon-delete" | ||
:title="t('richdocuments', 'Remove Zotero API Key')" | ||
data-toggle="tooltip" /> | ||
</button> | ||
</p> | ||
<p> | ||
<em> | ||
{{ t('richdocuments', 'To use Zotero specify your API key here. You can create your API key in your') }} | ||
<a href="https://www.zotero.org/settings/keys" target="_blank"> | ||
{{ t('richdocuments', 'Zotero account API settings.') }} | ||
</a> | ||
</em> | ||
</p> | ||
</div> | ||
</template> | ||
<p v-else> | ||
<em> | ||
{{ t('richdocuments', 'This instance does not support Zotero, because the feature is missing or disabled. Please contact the administration.') }} | ||
</em> | ||
</p> | ||
|
||
<!-- Document signing --> | ||
<p><strong>{{ t('richdocuments', 'Document signing') }}</strong></p> | ||
<template v-if="hasDocumentSigningSupport"> | ||
<div class="input-wrapper"> | ||
<!-- Cert --> | ||
<DocSigningField id="documentSigningCertField" | ||
name="documentSigningCertField" | ||
:label="t('richdocuments', 'Enter document signing cert (in PEM format)')" | ||
:value="documentSigningCert" | ||
:save-tooltip="t('richdocuments', 'Save document signing cert')" | ||
:remove-tooltip="t('richdocuments', 'Remove document signing cert')" | ||
@save="val => setDocumentSigningCert(val)" | ||
@remove="() => setDocumentSigningCert('')" /> | ||
|
||
<!-- Key --> | ||
<DocSigningField id="documentSigningKeyField" | ||
name="documentSigningKeyField" | ||
:label="t('richdocuments', 'Enter document signing key')" | ||
:value="documentSigningKey" | ||
:save-tooltip="t('richdocuments', 'Save document signing key')" | ||
:remove-tooltip="t('richdocuments', 'Remove document signing key')" | ||
@save="val => setDocumentSigningKey(val)" | ||
@remove="() => setDocumentSigningKey('')" /> | ||
|
||
<!-- CA --> | ||
<DocSigningField id="documentSigningCaField" | ||
name="documentSigningCaField" | ||
:label="t('richdocuments', 'Enter document signing CA chain')" | ||
:value="documentSigningCa" | ||
:save-tooltip="t('richdocuments', 'Save document signing CA chain')" | ||
:remove-tooltip="t('richdocuments', 'Remove document signing CA chain')" | ||
@save="val => setDocumentSigningCa(val)" | ||
@remove="() => setDocumentSigningCa('')" /> | ||
|
||
<p> | ||
<em> | ||
{{ t('richdocuments', 'To use document signing, specify your signing certificate, key and CA chain here.') }} | ||
</em> | ||
</p> | ||
</div> | ||
</template> | ||
<p v-else> | ||
<em> | ||
{{ t('richdocuments', 'This instance does not support document signing, because the feature is missing or disabled. Please contact the administrator.') }} | ||
</em> | ||
</p> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import { generateFilePath } from '@nextcloud/router' | ||
import { showError, showSuccess } from '@nextcloud/dialogs' | ||
import DocSigningField from './DocSigningField.vue' | ||
|
||
export default { | ||
name: 'PersonalSettings', | ||
components: { | ||
DocSigningField, | ||
}, | ||
props: { | ||
initial: { | ||
type: Object, | ||
required: true, | ||
}, | ||
}, | ||
data() { | ||
return { | ||
templateFolder: this.initial.templateFolder || '', | ||
hasZoteroSupport: this.initial.hasZoteroSupport || false, | ||
zoteroAPIKey: this.initial.zoteroAPIKey || '', | ||
hasDocumentSigningSupport: this.initial.hasDocumentSigningSupport || false, | ||
documentSigningCert: this.initial.documentSigningCert || '', | ||
documentSigningKey: this.initial.documentSigningKey || '', | ||
documentSigningCa: this.initial.documentSigningCa || '', | ||
} | ||
}, | ||
methods: { | ||
onTemplateSelectButtonClick() { | ||
OC.dialogs.filepicker( | ||
this.t('richdocuments', 'Select a personal template folder'), | ||
(datapath) => { | ||
this.updateSetting({ templateFolder: datapath }, () => { | ||
this.templateFolder = datapath | ||
}, () => {}) | ||
}, | ||
false, | ||
'httpd/unix-directory', | ||
true, | ||
OC.dialogs.FILEPICKER_TYPE_CHOOSE, | ||
) | ||
}, | ||
resetTemplate() { | ||
this.updateSetting({ templateFolder: '' }, () => { | ||
this.templateFolder = '' | ||
}, () => {}) | ||
}, | ||
saveZoteroAPIKey() { | ||
this.updateSetting({ zoteroAPIKeyInput: this.zoteroAPIKey }, () => { | ||
showSuccess(this.t('richdocuments', 'Zotero API key saved')) | ||
}, () => { | ||
showError(this.t('richdocuments', 'Failed to update the Zotero API key')) | ||
}) | ||
}, | ||
resetZoteroAPI() { | ||
this.updateSetting({ zoteroAPIKeyInput: '' }, () => { | ||
this.zoteroAPIKey = '' | ||
}, () => { | ||
showError(this.t('richdocuments', 'Failed to reset the Zotero API key')) | ||
}) | ||
}, | ||
setDocumentSigningCert(val) { | ||
this.updateSetting({ documentSigningCertInput: val }, () => { | ||
this.documentSigningCert = val | ||
if (val === '') { | ||
showSuccess(this.t('richdocuments', 'Document signing cert removed')) | ||
} else { | ||
showSuccess(this.t('richdocuments', 'Document signing cert saved')) | ||
} | ||
}, () => { | ||
showError(this.t('richdocuments', 'Failed to update the document signing CA chain')) | ||
}) | ||
}, | ||
setDocumentSigningKey(val) { | ||
this.updateSetting({ documentSigningKeyInput: val }, () => { | ||
this.documentSigningKey = val | ||
if (val === '') { | ||
showSuccess(this.t('richdocuments', 'Document signing key removed')) | ||
} else { | ||
showSuccess(this.t('richdocuments', 'Document signing key saved')) | ||
} | ||
}, () => { | ||
showError(this.t('richdocuments', 'Failed to update the document signing CA chain')) | ||
}) | ||
}, | ||
setDocumentSigningCa(val) { | ||
this.updateSetting({ documentSigningCaInput: val }, () => { | ||
this.documentSigningCa = val | ||
if (val === '') { | ||
showSuccess(this.t('richdocuments', 'Document signing CA chain removed')) | ||
} else { | ||
showSuccess(this.t('richdocuments', 'Document signing CA chain saved')) | ||
} | ||
}, () => { | ||
showError(this.t('richdocuments', 'Failed to update the document signing CA chain')) | ||
}) | ||
}, | ||
|
||
updateSetting(data, successCallback, errorCallback) { | ||
OC.msg.startAction('#documents-admin-msg', this.t('richdocuments', 'Saving …')) | ||
const request = new XMLHttpRequest() | ||
request.open('POST', generateFilePath('richdocuments', 'ajax', 'personal.php'), true) | ||
request.setRequestHeader('Content-Type', 'application/json') | ||
request.setRequestHeader('requesttoken', OC.requestToken) | ||
request.onload = function() { | ||
if (request.status >= 200 && request.status < 400) { | ||
const response = JSON.parse(request.response) | ||
OC.msg.finishedAction('#documents-admin-msg', response) | ||
successCallback(response) | ||
} else { | ||
errorCallback(this.response) | ||
} | ||
} | ||
request.onerror = function() { | ||
errorCallback(this.response) | ||
} | ||
request.send(JSON.stringify(data)) | ||
}, | ||
}, | ||
} | ||
</script> | ||
|
||
<style scoped> | ||
.personal-settings { | ||
padding: 2rem; | ||
font-family: Arial, sans-serif; | ||
} | ||
|
||
.icon-folder::before { | ||
content: "\1F4C1"; | ||
} | ||
</style> |
Oops, something went wrong.