Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -675,4 +675,8 @@
margin-top: -4px !important;
}

::v-deep .v-dialog__content {
z-index: 5 !important;
}

</style>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<div style="width: 100%;">
<VCard
v-if="!primaryFileMapping.length"
v-if="!primaryFileCount"
data-test="error"
flat
>
Expand All @@ -14,10 +14,32 @@
</VCardText>
</VCard>
<VLayout v-else row wrap>
<VFlex sm12 md6 lg5 xl4>
<VFlex sm12 md12 lg12 xl12>
<p>
<ContentNodeIcon :kind="node.kind" includeText />
</p>
</VFlex>
<VFlex sm12 md6 lg7 xl7 class="pr-4">
<h3>
{{ $tr('filesHeader') }}
</h3>
<VList threeLine>
<FileUploadItem
v-for="item in primaryFileMapping"
:key="item.preset.id"
:file="item.file"
:preset="item.preset"
:allowFileRemove="allowFileRemove"
:uploadCompleteHandler="handleUploadComplete"
@selected="selected = item.file.id"
@remove="showRemoveFileWarning = primaryFileCount > 1"
/>
</VList>
</VFlex>
<VFlex sm12 md6 lg5 xl5>
<h3 v-if="selectedFilename" class="mb-3">
{{ selectedFilename }}
</h3>
<div class="preview-wrapper">
<VCard v-if="!primaryFileCount" flat class="mb-2 message-card">
<VLayout align-center justify-center fill-height>
Expand All @@ -39,32 +61,19 @@
/>
</div>
</VFlex>
<VFlex sm12 md6 lg7 xl8>
<VContainer fluid>
<VLayout alignStart>
<VRadioGroup
v-model="selected"
hide-details
:label="$tr('filesHeader')"
class="subheading"
>
<VList threeLine>
<FileUploadItem
v-for="item in primaryFileMapping"
:key="item.preset.id"
:file="item.file"
:preset="item.preset"
:allowFileRemove="allowFileRemove"
:uploadCompleteHandler="handleUploadComplete"
@selected="selected = item.file.id"
@remove="handleRemoveFile"
/>
</VList>
</VRadioGroup>
</VLayout>
</VContainer>
</VFlex>
</VLayout>

<KModal
v-if="showRemoveFileWarning"
data-test="remove-file-warning"
:title="$tr('removeFile')"
:submitText="$tr('yesButton')"
:cancelText="$tr('cancelButton')"
@submit="handleRemoveFile"
@cancel="showRemoveFileWarning = false"
>
<p>{{ $tr("removeFileDescription", { fileTypes: allowedFileTypes }) }}</p>
</KModal>
</div>

</template>
Expand Down Expand Up @@ -94,6 +103,7 @@
data() {
return {
selected: null,
showRemoveFileWarning: false,
};
},
computed: {
Expand All @@ -118,22 +128,32 @@
return this.fileCount > 1;
},
primaryFileCount() {
return this.files.filter(file => !file.preset.supplementary).length;
return this.primaryFileMapping.length;
},
primaryFileMapping() {
return sortBy(
this.presets
.filter(p => !p.supplementary)
.map(preset => {
return {
preset,
order: preset.order,
file: this.files.find(file => file.preset.id === preset.id),
};
}),
const file = this.files.find(file => file.preset.id === preset.id);
if (!preset.supplementary && file) {
return { preset, order: preset.order, file };
}
return null;
})
.filter(item => item !== null),
'order'
);
},
selectedFilename() {
const file = this.files.find(f => f.id === this.selected);
return file ? file.original_filename : '';
},
allowedFileTypes() {
return this.presets
.filter(p => !p.supplementary && Array.isArray(p.allowed_formats))
.map(p => p.allowed_formats.join(', '))
.join(', ');
},
},
watch: {
'files.length'(newCount, oldCount) {
Expand Down Expand Up @@ -163,17 +183,25 @@
eventLabel: 'Related file',
});
},
handleRemoveFile(file) {
this.deleteFile(file);
if (file.id === this.selected) {
this.selectFirstFile();
handleRemoveFile() {
const selectedFile = this.files.find(f => f.id === this.selected);
if (selectedFile) {
this.deleteFile(selectedFile).then(() => {
this.selectFirstFile();
});
}
this.showRemoveFileWarning = false;
},
},
$trs: {
filesHeader: 'Preview files',
filesHeader: 'Files',
fileError: 'Unsupported file type',
noFileText: 'Missing files',
removeFile: 'Remove file',
removeFileDescription:
'Once this file is removed, this resource will only be able to include a single file from the formats: { fileTypes }. Are you sure you want to continue?',
yesButton: 'Yes',
cancelButton: 'Cancel',
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,19 @@
<VListTile
data-test="list-item"
v-bind="$attrs"
tabindex="0"
@click.stop="file ? $emit('selected') : openFileDialog()"
>
<VListTileAction>
<VRadio
v-if="file"
:key="file.id"
:value="file.id"
color="primary"
data-test="radio"
/>
</VListTileAction>
<VListTileContent>
<VListTileSubTitle>{{ translateConstant(preset.id) }}</VListTileSubTitle>
<VListTileTitle>
<ActionLink
<VListTileTitle class="file-display">
<span
v-if="fileDisplay"
class="notranslate"
:text="formattedFileDisplay"
data-test="file-link"
@click="openFileDialog"
/>
data-test="file-name"
>
{{ formattedFileDisplay }}
</span>
<ActionLink
v-else
data-test="upload-link"
Expand All @@ -53,15 +45,20 @@
</VListTileContent>
<VSpacer />
<VListTileAction v-if="fileDisplay">
<div v-if="allowFileRemove" class="remove-icon">
<IconButton
icon="clear"
color="grey"
:text="$tr('removeFileButton')"
data-test="remove"
@click="$emit('remove', file)"
/>
</div>
<KIconButton
size="small"
icon="optionsHorizontal"
appearance="flat-button"
data-test="show-file-options"
>
<template #menu>
<KDropdownMenu
:options="previewFilesOptions"
data-test="file-options"
@select="(option) => option.onClick(openFileDialog)"
/>
</template>
</KIconButton>
</VListTileAction>
</VListTile>
</FileDropzone>
Expand All @@ -72,10 +69,9 @@

<script>

import { mapGetters } from 'vuex';
import { mapActions, mapGetters } from 'vuex';
import FileStatusText from 'shared/views/files/FileStatusText';
import Uploader from 'shared/views/files/Uploader';
import IconButton from 'shared/views/IconButton';
import { constantsTranslationMixin, fileSizeMixin, fileStatusMixin } from 'shared/mixins';
import FileDropzone from 'shared/views/files/FileDropzone';

Expand All @@ -85,7 +81,6 @@
Uploader,
FileDropzone,
FileStatusText,
IconButton,
},
mixins: [constantsTranslationMixin, fileSizeMixin, fileStatusMixin],
props: {
Expand Down Expand Up @@ -150,6 +145,36 @@
}
return null;
},
previewFilesOptions() {
const options = [
{
label: this.$tr('replaceFileMenuOptionLabel'),
value: 'REPLACE_FILE',
onClick: replaceFile => {
replaceFile();
},
condition: this.fileDisplay,
},
{
label: this.$tr('downloadMenuOptionLabel'),
value: 'DOWNLOAD_FILE',
onClick: () => {
this.initiateFileDownload();
},
condition: this.fileDisplay,
},
{
label: this.$tr('removeMenuOptionLabel'),
value: 'REMOVE_FILE',
onClick: () => {
this.removeFile();
},
condition: this.fileDisplay && this.allowFileRemove,
},
];

return options.filter(option => option.condition);
},
},
watch: {
'file.id': {
Expand All @@ -159,6 +184,8 @@
},
},
methods: {
...mapActions('file', ['downloadFile']),
...mapActions(['showSnackbar']),
completeUpload(fileUpload) {
if (fileUpload.id === this.fileUploadId) {
this.uploadCompleteHandler(fileUpload);
Expand All @@ -167,11 +194,30 @@
uploadingHandler(fileUpload) {
this.fileUploadId = fileUpload.id;
},
initiateFileDownload() {
try {
this.downloadFile({
url: this.fileDisplay.url,
fileName: this.formattedFileDisplay,
});
} catch (e) {
this.showSnackbar({
text: this.$tr('downloadFailed'),
});
}
},
removeFile() {
this.$emit('remove', this.file);
},
},
$trs: {
uploadButton: 'Select file',
removeFileButton: 'Remove',
replaceFileMenuOptionLabel: 'Replace file',
downloadMenuOptionLabel: 'Download',
removeMenuOptionLabel: 'Remove',
downloadFailed: 'Failed to download file',
/* eslint-disable kolibri/vue-no-unused-translations */
removeFileButton: 'Remove',
retryUpload: 'Retry upload',
uploadFailed: 'Upload failed',
unknownFile: 'Unknown filename',
Expand All @@ -183,36 +229,32 @@

<style lang="scss" scoped>

.layout .section-header {
padding: 0 15px;
font-weight: bold;
color: var(--v-darken-3);
}

button {
margin: 0;
}

::v-deep .v-list__tile {
height: max-content !important;
min-height: 64px;
padding: 5px 16px;

.remove-icon {
display: none;
}

&:hover .remove-icon {
display: block;
&:focus {
background-color: var(--v-grey-lighten5);
outline-color: var(--v-primary-base);
}

.v-list__tile__title {
height: max-content;
height: 30px;
}

.v-list__tile__sub-title {
margin-left: 1px;
white-space: unset;
}
}

.file-display {
margin-left: 1px;

span {
font-size: 15px;
}
}

</style>
Loading