skillbox/client/src/components/content-blocks/assignment/SubmissionForm.vue

153 lines
3.6 KiB
Vue

<template>
<div class="feedback__submission form-with-border submission-form-container">
<div class="submission-form-container__inputs">
<submission-input
:input-text="userInput.text"
:saved="saved"
:readonly="isFinalOrReadOnly"
:placeholder="placeholder"
@input="saveInput"
/>
</div>
<div
class="submission-form-container__actions"
v-if="!isFinalOrReadOnly"
>
<button
class="submission-form-container__submit button button--primary button--white-bg"
data-cy="submission-form-submit"
@click="$emit('turnIn')"
>
{{ action }}
</button>
<button
class="submission-form-container__submit submission-form-container__spellcheck button button--primary button--white-bg"
data-cy="spellcheck-button"
v-if="showSpellcheckButton"
@click="$emit('spellcheck')"
>
{{ spellcheckText }}
</button>
<file-upload
:document="userInput.document"
v-if="allowsDocuments"
@change-document-url="changeDocumentUrl"
/>
<slot />
</div>
<final-submission
:user-input="userInput"
:shared-msg="sharedMsg"
:show-reopen="!readOnly"
v-if="isFinalOrReadOnly"
@reopen="reopenSubmission"
/>
</div>
</template>
<script setup lang="ts">
import { defineAsyncComponent, computed } from 'vue';
export interface Props {
userInput: {
final: boolean;
document?: string;
text: string;
};
saved: boolean;
placeholder: string;
action: string;
readOnly: boolean;
spellcheck: boolean;
spellcheckLoading: boolean;
sharedMsg: string;
}
const SubmissionInput = defineAsyncComponent(
() => import('@/components/content-blocks/assignment/SubmissionInput.vue')
);
const FinalSubmission = defineAsyncComponent(
() => import('@/components/content-blocks/assignment/FinalSubmission.vue')
);
const FileUpload = defineAsyncComponent(() => import('@/components/ui/file-upload/FileUpload.vue'));
const props = withDefaults(defineProps<Props>(), {
readOnly: false,
speelcheck: false,
spellcheckLoading: false,
});
const final = computed(() => {
return !!props.userInput && props.userInput.final;
});
const isFinalOrReadOnly = computed(() => {
return final.value || props.readOnly;
});
const allowsDocuments = computed(() => {
return 'document' in props.userInput;
});
const showSpellcheckButton = computed(() => {
return props.spellcheck && import.meta.env.VUE_APP_ENABLE_SPELLCHECK;
});
const spellcheckText = computed(() => {
if (!props.spellcheckLoading) {
return 'Rechtschreibung prüfen';
} else {
return 'Wird geprüft...';
}
});
const emit = defineEmits(['reopen', 'saveInput', 'changeDocumentUrl']);
const reopenSubmission = () => {
emit('reopen');
};
const saveInput = (input: any) => {
emit('saveInput', input);
};
const changeDocumentUrl = (documentUrl: string) => {
emit('changeDocumentUrl', documentUrl);
};
</script>
<style lang="scss">
// todo: use `scoped` once no longer on webpack
@import 'styles/helpers';
.submission-form-container {
margin-bottom: $medium-spacing;
display: none;
@include desktop {
display: block;
}
&__inputs {
margin-bottom: 12px;
}
&__submit {
margin-right: $medium-spacing;
}
&__actions {
display: flex;
align-items: center;
}
&__document {
&:hover {
cursor: pointer;
}
}
&__spellcheck {
/* so the button does not change size when changing the text */
width: 235px;
text-align: center;
display: inline-block;
}
}
</style>