Skip to content

Commit 759df12

Browse files
committed
feat: add DocMDP settings UI and validation display
Add DocMDP admin configuration component and enhance validation view: Settings.vue: - Import and register DocMDP component - Add to admin settings panel Validation.vue: - Display document certification level - Show modification validation status - Add collapsible DocMDP details section - Visual indicators for modification status (success/warning/error) - Icons: mdiShieldCheck, mdiShieldOff, mdiInformationOutline - Revision count display with pluralization Modification status mapping (File::MODIFICATION_*): - 1 (unmodified) → green checkmark - 2 (allowed modifications) → yellow alert - 3 (violations) → red cancel - 0 (unchecked) → help icon Signed-off-by: Vitor Mattos <[email protected]>
1 parent f77d22b commit 759df12

2 files changed

Lines changed: 111 additions & 1 deletion

File tree

src/views/Settings/Settings.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<IdentificationFactors />
1515
<ExpirationRules />
1616
<Validation />
17+
<DocMDP />
1718
<AllowedGroups />
1819
<LegalInformation />
1920
<IdentificationDocuments />
@@ -34,6 +35,7 @@ import CertificateEngine from './CertificateEngine.vue'
3435
import CollectMetadata from './CollectMetadata.vue'
3536
import ConfigureCheck from './ConfigureCheck.vue'
3637
import DefaultUserFolder from './DefaultUserFolder.vue'
38+
import DocMDP from './DocMDP.vue'
3739
import DownloadBinaries from './DownloadBinaries.vue'
3840
import ExpirationRules from './ExpirationRules.vue'
3941
import IdentificationDocuments from './IdentificationDocuments.vue'
@@ -56,6 +58,7 @@ export default {
5658
CollectMetadata,
5759
ConfigureCheck,
5860
DefaultUserFolder,
61+
DocMDP,
5962
DownloadBinaries,
6063
ExpirationRules,
6164
IdentificationDocuments,

src/views/Validation.vue

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,81 @@
272272
</template>
273273
</NcListItem>
274274
</div>
275+
<NcListItem v-if="signer.opened && hasDocMdpInfo(signer)"
276+
class="extra"
277+
compact
278+
:name="t('libresign', 'Document certification')"
279+
:aria-expanded="docMdpOpenState[signerIndex] ? 'true' : 'false'"
280+
:aria-label="docMdpOpenState[signerIndex] ? t('libresign', 'Document certification, expanded. Click to collapse') : t('libresign', 'Document certification, collapsed. Click to expand')"
281+
role="button"
282+
@click="toggleState(docMdpOpenState, signerIndex)">
283+
<template #name>
284+
<strong>{{ t('libresign', 'Document certification') }}</strong>
285+
</template>
286+
<template #extra-actions>
287+
<NcButton variant="tertiary"
288+
:aria-label="docMdpOpenState[signerIndex] ? t('libresign', 'Collapse certification details') : t('libresign', 'Expand certification details')"
289+
@click.stop="toggleState(docMdpOpenState, signerIndex)">
290+
<template #icon>
291+
<NcIconSvgWrapper v-if="docMdpOpenState[signerIndex]"
292+
:path="mdiUnfoldLessHorizontal"
293+
:size="20" />
294+
<NcIconSvgWrapper v-else
295+
:path="mdiUnfoldMoreHorizontal"
296+
:size="20" />
297+
</template>
298+
</NcButton>
299+
</template>
300+
<template #indicator>
301+
<NcIconSvgWrapper v-if="getModificationStatusIcon(signer)"
302+
:path="getModificationStatusIcon(signer)"
303+
:class="getModificationStatusClass(signer)"
304+
:size="20" />
305+
</template>
306+
</NcListItem>
307+
<div v-if="signer.opened && docMdpOpenState[signerIndex] && hasDocMdpInfo(signer)"
308+
role="region"
309+
:aria-label="t('libresign', 'Document certification details')">
310+
<NcListItem v-if="signer.docmdp"
311+
class="extra-chain"
312+
compact>
313+
<template #icon>
314+
<NcIconSvgWrapper :path="signer.docmdp.isCertifying ? mdiShieldCheck : mdiShieldOff" />
315+
</template>
316+
<template #name>
317+
<strong>{{ t('libresign', 'Certification level:') }}</strong>
318+
{{ signer.docmdp.label }}
319+
</template>
320+
</NcListItem>
321+
<NcListItem v-if="signer.docmdp && signer.docmdp.description"
322+
class="extra-chain"
323+
compact>
324+
<template #name>
325+
{{ signer.docmdp.description }}
326+
</template>
327+
</NcListItem>
328+
<NcListItem v-if="signer.modification_validation"
329+
class="extra-chain"
330+
compact>
331+
<template #icon>
332+
<NcIconSvgWrapper :path="getModificationStatusIcon(signer)"
333+
:class="getModificationStatusClass(signer)" />
334+
</template>
335+
<template #name>
336+
{{ signer.modification_validation.message }}
337+
</template>
338+
</NcListItem>
339+
<NcListItem v-if="signer.modifications && signer.modifications.modified"
340+
class="extra-chain"
341+
compact>
342+
<template #icon>
343+
<NcIconSvgWrapper :path="mdiInformationOutline" />
344+
</template>
345+
<template #name>
346+
{{ n('libresign', 'Document has %n revision', 'Document has %n revisions', signer.modifications.revisionCount) }}
347+
</template>
348+
</NcListItem>
349+
</div>
275350
<NcListItem v-if="signer.opened && signer.signatureTypeSN"
276351
class="extra"
277352
compact
@@ -615,8 +690,11 @@ import {
615690
mdiCheckboxMarkedCircle,
616691
mdiCheckCircle,
617692
mdiHelpCircle,
693+
mdiInformationOutline,
618694
mdiInformationSlabCircle,
619695
mdiKey,
696+
mdiShieldCheck,
697+
mdiShieldOff,
620698
mdiSignatureFreehand,
621699
mdiUnfoldLessHorizontal,
622700
mdiUnfoldMoreHorizontal,
@@ -627,7 +705,7 @@ import JSConfetti from 'js-confetti'
627705
import axios from '@nextcloud/axios'
628706
import { formatFileSize } from '@nextcloud/files'
629707
import { loadState } from '@nextcloud/initial-state'
630-
import { translate as t } from '@nextcloud/l10n'
708+
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
631709
import Moment from '@nextcloud/moment'
632710
import { generateUrl, generateOcsUrl } from '@nextcloud/router'
633711
@@ -672,8 +750,11 @@ export default {
672750
mdiCheckboxMarkedCircle,
673751
mdiCheckCircle,
674752
mdiHelpCircle,
753+
mdiInformationOutline,
675754
mdiInformationSlabCircle,
676755
mdiKey,
756+
mdiShieldCheck,
757+
mdiShieldOff,
677758
mdiSignatureFreehand,
678759
mdiUnfoldLessHorizontal,
679760
mdiUnfoldMoreHorizontal,
@@ -696,6 +777,7 @@ export default {
696777
tsaOpenState: {},
697778
chainOpenState: {},
698779
notificationsOpenState: {},
780+
docMdpOpenState: {},
699781
validationErrorMessage: null,
700782
documentValidMessage: null,
701783
}
@@ -994,6 +1076,31 @@ export default {
9941076
}
9951077
return false
9961078
},
1079+
hasDocMdpInfo(signer) {
1080+
return signer.docmdp || signer.modifications || signer.modification_validation
1081+
},
1082+
getModificationStatusIcon(signer) {
1083+
if (!signer.modification_validation) {
1084+
return null
1085+
}
1086+
// Based on File::MODIFICATION_* constants
1087+
// 0=unchecked, 1=unmodified, 2=modified(allowed), 3=modified(violation)
1088+
const status = signer.modification_validation.status
1089+
if (status === 1) return this.mdiCheckCircle
1090+
if (status === 2) return this.mdiAlertCircle
1091+
if (status === 3) return this.mdiCancel
1092+
return this.mdiHelpCircle
1093+
},
1094+
getModificationStatusClass(signer) {
1095+
if (!signer.modification_validation) {
1096+
return ''
1097+
}
1098+
const status = signer.modification_validation.status
1099+
if (status === 1) return 'icon-success'
1100+
if (status === 2) return 'icon-warning'
1101+
if (status === 3) return 'icon-error'
1102+
return ''
1103+
},
9971104
formatTimestamp(timestamp) {
9981105
return timestamp ? new Date(timestamp * 1000).toLocaleString() : ''
9991106
},

0 commit comments

Comments
 (0)