Skip to main content

CnRichSubmitDialog

Single-screen rich-submit modal with a reason taxonomy, optional free-text notes, and optional file attachments (with accept / max-files / max-size constraints). For "submit work" / "submit excuse" / "submit appeal" flows where the submission carries a reason from a closed taxonomy plus context.

Use CnFormDialog for schema-driven forms, CnWizardDialog for multi-step flows.

Try it

<template>
<div>
<NcButton @click="show = true">Submit work</NcButton>

<CnRichSubmitDialog
v-if="show"
ref="submit"
dialog-title="Submit work"
:reasons="reasons"
:show-files="true"
:files-required="true"
:files-accept="'.pdf,.docx,.zip'"
:max-files="3"
:max-size-mb="20"
:late-warning="lateWarning"
@confirm="onSubmit"
@close="show = false" />
</div>
</template>

<script>
import { CnRichSubmitDialog } from '@conduction/nextcloud-vue'

export default {
components: { CnRichSubmitDialog },
data() {
return {
show: false,
reasons: [
{ value: 'complete', label: 'Final submission' },
{ value: 'draft', label: 'Draft (request feedback)' },
{ value: 'resubmit', label: 'Resubmission after feedback' },
],
}
},
computed: {
lateWarning() {
return this.assignment.deadline < Date.now()
? 'This submission is past the deadline; a late penalty may apply.'
: ''
},
},
methods: {
async onSubmit({ reason, notes, files }) {
const fd = new FormData()
fd.append('reason', reason)
fd.append('notes', notes)
files.forEach((f) => fd.append('files', f))
try {
const { data } = await axios.post(`/api/assignments/${id}/submissions`, fd)
this.$refs.submit.setResult({ success: true, message: 'Submitted.' })
} catch (e) {
this.$refs.submit.setResult({ error: e.message })
}
},
},
}
</script>

Props

PropTypeDefaultDescription
dialogTitleString'Submit'Dialog header.
descriptionString''Optional intro text.
reasonsArray<string|{value,label,description?}>[]Reason taxonomy entries.
reasonRequiredBooleanfalseWhether a reason must be picked to enable Submit.
reasonLabelString'Reason'Label preceding the reason list.
showNotesBooleantrueWhether to render the notes textarea.
notesRequiredBooleanfalseWhether notes are required to enable Submit.
notesLabelString'Notes'Notes textarea label.
notesPlaceholderString''Notes textarea placeholder.
showFilesBooleanfalseWhether to render the file input.
filesRequiredBooleanfalseWhether at least one file is required.
filesLabelString'Attachments'Files field label.
filesHintString''Files field hint text.
filesAcceptString''accept attribute for the file input.
maxFilesNumber0Max number of files (1 = single-file; 0 = unlimited).
maxSizeMbNumber0Per-file max size in MB (0 = no limit).
lateWarningString''Warning banner text rendered above the form. Empty string hides the banner.
confirmLabelString'Submit'Confirm-button label.
cancelLabelString'Cancel'Cancel-button label.
closeLabelString'Close'Close-button label (result phase).
successTextString'Submitted.'Default success banner text.
defaultsObject{}Seed values for reason / notes.

Events

EventPayloadDescription
confirm{ reason, notes, files }User clicked Submit. loading is set; the parent calls setResult() to flip into the result phase.
closeDialog dismissed.

Public methods

MethodSignatureDescription
setResult(result)({ success?, message?, error? })Flip into the result phase + clear loading.

File-input semantics

  • maxFiles > 0: rejects a selection containing more than N files with a typed banner.
  • maxSizeMb > 0: rejects a selection containing any file larger than the limit, naming the offending file.
  • Rejections clear the input and surface as validationError text; the form remains in the form phase.

See also