@farm-investimentos/front-mfe-components-vue3 1.1.1 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/front-mfe-components.common.js +1349 -401
- package/dist/front-mfe-components.common.js.map +1 -1
- package/dist/front-mfe-components.css +1 -1
- package/dist/front-mfe-components.umd.js +1349 -401
- package/dist/front-mfe-components.umd.js.map +1 -1
- package/dist/front-mfe-components.umd.min.js +1 -1
- package/dist/front-mfe-components.umd.min.js.map +1 -1
- package/package.json +102 -102
- package/src/components/DialogFooter/DialogFooter.vue +62 -67
- package/src/components/MultipleFilePicker/MultipleFilePicker.vue +153 -166
- package/src/components/MultipleFilePicker/__tests__/MultipleFilePicker.spec.js +66 -148
- package/src/scss/CollapseFX.scss +15 -0
|
@@ -1,37 +1,66 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<section
|
|
2
|
+
<section
|
|
3
|
+
ref="container"
|
|
4
|
+
id="droparea-container"
|
|
5
|
+
>
|
|
3
6
|
<input
|
|
4
7
|
type="file"
|
|
5
8
|
name="file"
|
|
6
9
|
multiple
|
|
7
10
|
ref="upload"
|
|
8
|
-
:accept="acceptedFileTypes"
|
|
9
|
-
@change="
|
|
11
|
+
:accept="props.acceptedFileTypes"
|
|
12
|
+
@change="handleFileChange"
|
|
10
13
|
/>
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
v-if="!hasFiles"
|
|
17
|
+
class="selectfile-container"
|
|
18
|
+
>
|
|
19
|
+
<farm-icon
|
|
20
|
+
class="upload-icon"
|
|
21
|
+
color="primary"
|
|
22
|
+
size="lg"
|
|
23
|
+
@click="addMoreFiles"
|
|
24
|
+
>
|
|
13
25
|
cloud-upload-outline
|
|
14
26
|
</farm-icon>
|
|
15
|
-
<farm-subtitle
|
|
27
|
+
<farm-subtitle
|
|
28
|
+
:type="2"
|
|
29
|
+
variation="regular"
|
|
30
|
+
color="primary"
|
|
31
|
+
>
|
|
16
32
|
Arraste e solte o arquivo <br />
|
|
17
33
|
ou clique aqui
|
|
18
34
|
</farm-subtitle>
|
|
19
35
|
</div>
|
|
20
36
|
|
|
21
37
|
<ul
|
|
22
|
-
v-if="downloadFiles.length"
|
|
38
|
+
v-if="props.downloadFiles.length"
|
|
23
39
|
class="listFilesStyled listFilesStyled--download"
|
|
24
40
|
:class="{
|
|
25
41
|
'listFilesStyled--margin-bottom': files.length === 0,
|
|
26
42
|
}"
|
|
27
43
|
>
|
|
28
|
-
<li
|
|
44
|
+
<li
|
|
45
|
+
class="itemFilesStyled"
|
|
46
|
+
v-for="file in props.downloadFiles"
|
|
47
|
+
:key="file.id"
|
|
48
|
+
>
|
|
29
49
|
<div class="itemFilesContentStyled">
|
|
30
50
|
<div class="fileDocumentStyled">
|
|
31
|
-
<farm-icon
|
|
51
|
+
<farm-icon
|
|
52
|
+
color="black"
|
|
53
|
+
variation="50"
|
|
54
|
+
size="sm"
|
|
55
|
+
>
|
|
56
|
+
attachment
|
|
57
|
+
</farm-icon>
|
|
32
58
|
</div>
|
|
33
59
|
<div>
|
|
34
|
-
<farm-bodysmall
|
|
60
|
+
<farm-bodysmall
|
|
61
|
+
color="black"
|
|
62
|
+
color-variation="50"
|
|
63
|
+
>
|
|
35
64
|
Arquivo selecionado: {{ file.name }} ({{ sizeOf(file.size) }})
|
|
36
65
|
</farm-bodysmall>
|
|
37
66
|
</div>
|
|
@@ -45,24 +74,42 @@
|
|
|
45
74
|
title="Baixar Arquivo"
|
|
46
75
|
@click.prevent="onDownload(file.id)"
|
|
47
76
|
>
|
|
48
|
-
<farm-icon
|
|
49
|
-
|
|
77
|
+
<farm-icon
|
|
78
|
+
class="download-button__icon mr-sm-3"
|
|
79
|
+
size="md"
|
|
50
80
|
>
|
|
51
|
-
|
|
81
|
+
download
|
|
82
|
+
</farm-icon>
|
|
52
83
|
<span class="download-button__text">Baixar Arquivo</span>
|
|
53
84
|
</farm-btn>
|
|
54
85
|
</div>
|
|
55
86
|
</li>
|
|
56
87
|
</ul>
|
|
57
88
|
|
|
58
|
-
<ul
|
|
59
|
-
|
|
89
|
+
<ul
|
|
90
|
+
class="listFilesStyled"
|
|
91
|
+
v-if="files.length > 0"
|
|
92
|
+
>
|
|
93
|
+
<li
|
|
94
|
+
class="itemFilesStyled"
|
|
95
|
+
v-for="(file, index) in files"
|
|
96
|
+
:key="index"
|
|
97
|
+
>
|
|
60
98
|
<div class="itemFilesContentStyled">
|
|
61
99
|
<div class="fileDocumentStyled">
|
|
62
|
-
<farm-icon
|
|
100
|
+
<farm-icon
|
|
101
|
+
color="black"
|
|
102
|
+
variation="50"
|
|
103
|
+
size="sm"
|
|
104
|
+
>
|
|
105
|
+
attachment
|
|
106
|
+
</farm-icon>
|
|
63
107
|
</div>
|
|
64
108
|
<div>
|
|
65
|
-
<farm-bodysmall
|
|
109
|
+
<farm-bodysmall
|
|
110
|
+
color="black"
|
|
111
|
+
color-variation="50"
|
|
112
|
+
>
|
|
66
113
|
Arquivo selecionado: {{ file.name }} ({{ sizeOf(file.size) }})
|
|
67
114
|
</farm-bodysmall>
|
|
68
115
|
</div>
|
|
@@ -78,10 +125,17 @@
|
|
|
78
125
|
>
|
|
79
126
|
<farm-icon size="md">close</farm-icon>
|
|
80
127
|
</farm-btn>
|
|
81
|
-
<farm-icon
|
|
128
|
+
<farm-icon
|
|
129
|
+
size="md"
|
|
130
|
+
color="neutral"
|
|
131
|
+
v-if="file.success === true"
|
|
132
|
+
>
|
|
133
|
+
check
|
|
134
|
+
</farm-icon>
|
|
82
135
|
</div>
|
|
83
136
|
</li>
|
|
84
137
|
</ul>
|
|
138
|
+
|
|
85
139
|
<farm-btn
|
|
86
140
|
v-if="canAddMoreFiles && hasFiles"
|
|
87
141
|
outlined
|
|
@@ -94,169 +148,102 @@
|
|
|
94
148
|
</farm-btn>
|
|
95
149
|
</section>
|
|
96
150
|
</template>
|
|
97
|
-
|
|
98
|
-
|
|
151
|
+
|
|
152
|
+
<script setup lang="ts">
|
|
153
|
+
import { ref, computed, watch, defineEmits } from 'vue';
|
|
99
154
|
|
|
100
155
|
import { sizeOf } from '@farm-investimentos/front-mfe-libs-ts';
|
|
101
156
|
|
|
102
|
-
|
|
157
|
+
type DownloadFiles = {
|
|
103
158
|
id: number | string;
|
|
104
159
|
name: string;
|
|
105
160
|
size: number;
|
|
106
161
|
};
|
|
107
162
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
* Accepted file types
|
|
114
|
-
*/
|
|
115
|
-
acceptedFileTypes: {
|
|
116
|
-
type: String,
|
|
117
|
-
default: '*',
|
|
118
|
-
},
|
|
119
|
-
/**
|
|
120
|
-
* Max file size (in MB)
|
|
121
|
-
*/
|
|
122
|
-
maxFileSize: {
|
|
123
|
-
default: 0,
|
|
124
|
-
},
|
|
125
|
-
/**
|
|
126
|
-
* Max files number
|
|
127
|
-
*/
|
|
128
|
-
maxFilesNumber: {
|
|
129
|
-
type: Number,
|
|
130
|
-
default: 0,
|
|
131
|
-
},
|
|
132
|
-
/**
|
|
133
|
-
* File List from files who could be download
|
|
134
|
-
*/
|
|
135
|
-
downloadFiles: {
|
|
136
|
-
type: Array as PropType<Array<DownloadFiles>>,
|
|
137
|
-
default: () => [],
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
data() {
|
|
141
|
-
return {
|
|
142
|
-
dropArea: null,
|
|
143
|
-
files: [],
|
|
144
|
-
sizeOf,
|
|
145
|
-
};
|
|
146
|
-
},
|
|
147
|
-
computed: {
|
|
148
|
-
hasFiles(): boolean {
|
|
149
|
-
return this.files.length > 0 || this.downloadFiles.length > 0;
|
|
150
|
-
},
|
|
151
|
-
canAddMoreFiles(): boolean {
|
|
152
|
-
return this.filesLength < this.maxFilesNumber;
|
|
153
|
-
},
|
|
154
|
-
filesLength(): number {
|
|
155
|
-
return this.files.length + this.downloadFiles.length;
|
|
156
|
-
},
|
|
157
|
-
disabledButton(): boolean {
|
|
158
|
-
if (this.maxFilesNumber === 0) return false;
|
|
159
|
-
return this.filesLength >= this.maxFilesNumber;
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
mounted() {
|
|
163
|
-
this.dropArea = this.$refs.container;
|
|
164
|
-
this.addListeners();
|
|
165
|
-
},
|
|
166
|
-
methods: {
|
|
167
|
-
addMoreFiles(): void {
|
|
168
|
-
this.$refs.container.querySelector('input').click();
|
|
169
|
-
},
|
|
170
|
-
reset(): void {
|
|
171
|
-
this.$refs.container.querySelector('input').value = '';
|
|
172
|
-
this.files = [];
|
|
173
|
-
},
|
|
174
|
-
fileChange(fileList): void {
|
|
175
|
-
this.files.push(...fileList);
|
|
176
|
-
},
|
|
177
|
-
handlerFunctionHighlight(): void {
|
|
178
|
-
this.dropArea.classList.add('highlight');
|
|
179
|
-
},
|
|
180
|
-
handlerFunctionUnhighlight(): void {
|
|
181
|
-
this.dropArea.classList.remove('highlight');
|
|
182
|
-
},
|
|
183
|
-
addListeners(): void {
|
|
184
|
-
this.dropArea.addEventListener('dragenter', this.handlerFunctionHighlight, false);
|
|
185
|
-
this.dropArea.addEventListener('dragleave', this.handlerFunctionUnhighlight, false);
|
|
186
|
-
this.dropArea.addEventListener('dragover', this.handlerFunctionHighlight, false);
|
|
187
|
-
this.dropArea.addEventListener('drop', this.handlerFunctionUnhighlight, false);
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
remove(index: number): void {
|
|
191
|
-
if (this.files.length === 1) this.reset();
|
|
192
|
-
this.files.splice(index, 1);
|
|
193
|
-
},
|
|
194
|
-
|
|
195
|
-
onDownload(id: number): void {
|
|
196
|
-
this.$emit('onDownload', id);
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
watch: {
|
|
200
|
-
files(newValue) {
|
|
201
|
-
if (newValue.length === 0 && this.downloadFiles.length === 0) {
|
|
202
|
-
this.$emit('onFileChange', newValue);
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
const invalidTypeArray = newValue.filter(file => {
|
|
206
|
-
const type = file.type;
|
|
207
|
-
|
|
208
|
-
return (
|
|
209
|
-
this.acceptedFileTypes !== '*' &&
|
|
210
|
-
(this.acceptedFileTypes.indexOf(file.type) === -1 || !type)
|
|
211
|
-
);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
if (invalidTypeArray.length > 0) {
|
|
215
|
-
const validTypeArray = newValue.filter(file => {
|
|
216
|
-
const type = file.type;
|
|
217
|
-
if (this.acceptedFileTypes.indexOf(file.type) === -1 || !type) {
|
|
218
|
-
return false;
|
|
219
|
-
}
|
|
220
|
-
return true;
|
|
221
|
-
});
|
|
222
|
-
this.$emit('onInvalidFiles', [...invalidTypeArray]);
|
|
223
|
-
this.files = validTypeArray;
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
163
|
+
type ExtendedFile = {
|
|
164
|
+
name: string;
|
|
165
|
+
size: number;
|
|
166
|
+
success?: boolean;
|
|
167
|
+
};
|
|
226
168
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
169
|
+
defineOptions({
|
|
170
|
+
name: 'farm-multiple-filepicker',
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const props = defineProps({
|
|
174
|
+
acceptedFileTypes: { type: String, default: '*' },
|
|
175
|
+
maxFileSize: { type: Number, default: 0 },
|
|
176
|
+
maxFilesNumber: { type: Number, default: 0 },
|
|
177
|
+
downloadFiles: { type: Array as () => DownloadFiles[], default: () => [] },
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const emit = defineEmits([
|
|
181
|
+
'onFileChange',
|
|
182
|
+
'onInvalidFiles',
|
|
183
|
+
'onMaxFilesNumberWarning',
|
|
184
|
+
'onDownload',
|
|
185
|
+
'onReset',
|
|
186
|
+
]);
|
|
187
|
+
|
|
188
|
+
const files = ref<ExtendedFile[]>([]);
|
|
189
|
+
const dropArea = ref<HTMLElement | null>(null);
|
|
190
|
+
const container = ref<HTMLElement | null>(null);
|
|
191
|
+
|
|
192
|
+
const hasFiles = computed(() => files.value.length > 0 || props.downloadFiles.length > 0);
|
|
193
|
+
const canAddMoreFiles = computed(() => files.value.length < props.maxFilesNumber);
|
|
194
|
+
const disabledButton = computed(() =>
|
|
195
|
+
props.maxFilesNumber === 0 ? false : files.value.length >= props.maxFilesNumber
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const addMoreFiles = () => {
|
|
199
|
+
const input = dropArea.value?.querySelector('input[type="file"]') as HTMLInputElement;
|
|
200
|
+
if (input) input.click();
|
|
201
|
+
};
|
|
235
202
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
203
|
+
// const reset = () => {
|
|
204
|
+
// const input = container.value?.querySelector('input[type="file"]') as HTMLInputElement;
|
|
205
|
+
// if (input) input.value = '';
|
|
206
|
+
// files.value = [];
|
|
207
|
+
// emit('onReset');
|
|
208
|
+
// };
|
|
240
209
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const sizeInMB = file.size / (1024 * 1024);
|
|
246
|
-
if (sizeInMB < this.maxFileSize) return true;
|
|
210
|
+
const remove = (index: number) => {
|
|
211
|
+
files.value.splice(index, 1);
|
|
212
|
+
emit('onFileChange', files.value);
|
|
213
|
+
};
|
|
247
214
|
|
|
248
|
-
|
|
249
|
-
|
|
215
|
+
const handleFileChange = (event: Event) => {
|
|
216
|
+
const target = event.target as HTMLInputElement;
|
|
217
|
+
const fileList = target.files ? Array.from(target.files) : [];
|
|
218
|
+
if (fileList.length) {
|
|
219
|
+
files.value = [...files.value, ...fileList];
|
|
220
|
+
emit('onFileChange', files.value);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
250
223
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
this.$emit('onFileChange', this.files);
|
|
256
|
-
},
|
|
257
|
-
},
|
|
224
|
+
const onDownload = (id: number | string) => {
|
|
225
|
+
emit('onDownload', id);
|
|
258
226
|
};
|
|
227
|
+
|
|
228
|
+
watch(files, newValue => {
|
|
229
|
+
if (newValue.length > props.maxFilesNumber && props.maxFilesNumber > 0) {
|
|
230
|
+
files.value = newValue.slice(0, props.maxFilesNumber);
|
|
231
|
+
emit('onMaxFilesNumberWarning');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (props.maxFileSize > 0) {
|
|
235
|
+
const validFiles = newValue.filter(file => file.size / (1024 * 1024) <= props.maxFileSize);
|
|
236
|
+
if (validFiles.length !== newValue.length) {
|
|
237
|
+
emit(
|
|
238
|
+
'onInvalidFiles',
|
|
239
|
+
newValue.filter(file => !validFiles.includes(file))
|
|
240
|
+
);
|
|
241
|
+
files.value = validFiles;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
259
245
|
</script>
|
|
246
|
+
|
|
260
247
|
<style scoped lang="scss">
|
|
261
248
|
@import './MultipleFilePicker.scss';
|
|
262
249
|
</style>
|
|
@@ -1,184 +1,102 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
2
|
|
|
3
3
|
import MultipleFilePicker from '../index';
|
|
4
4
|
|
|
5
5
|
describe('MultipleFilePicker component', () => {
|
|
6
6
|
let wrapper;
|
|
7
|
-
let component;
|
|
8
7
|
|
|
9
8
|
beforeEach(() => {
|
|
10
|
-
wrapper =
|
|
11
|
-
|
|
9
|
+
wrapper = mount(MultipleFilePicker, {
|
|
10
|
+
props: {
|
|
12
11
|
maxFileSize: 1,
|
|
13
12
|
maxFilesNumber: 10,
|
|
14
13
|
downloadFiles: [],
|
|
15
14
|
acceptedFileTypes: 'application/pdf,image/jpeg,image/jpg,image/png',
|
|
16
15
|
},
|
|
16
|
+
global: {
|
|
17
|
+
mocks: {
|
|
18
|
+
'farm-icon': { template: '<i></i>' },
|
|
19
|
+
'farm-btn': { template: '<button><slot /></button>' },
|
|
20
|
+
'farm-subtitle': { template: '<div><slot /></div>' },
|
|
21
|
+
'farm-bodysmall': { template: '<span><slot /></span>' },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
17
24
|
});
|
|
18
|
-
component = wrapper.vm;
|
|
19
25
|
});
|
|
20
26
|
|
|
21
|
-
test('MultipleFilePicker created', () => {
|
|
22
|
-
expect(wrapper).
|
|
27
|
+
test('MultipleFilePicker is created', () => {
|
|
28
|
+
expect(wrapper.exists()).toBe(true);
|
|
23
29
|
});
|
|
24
30
|
|
|
25
31
|
describe('Methods', () => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
wrapper.vm.handlerFunctionHighlight();
|
|
30
|
-
expect(spyObj).toHaveBeenCalled();
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe('handlerFunctionUnhighlight', () => {
|
|
35
|
-
it('Should add class', () => {
|
|
36
|
-
const spyObj = jest.spyOn(wrapper.vm.dropArea.classList, 'remove');
|
|
37
|
-
wrapper.vm.handlerFunctionUnhighlight();
|
|
38
|
-
expect(spyObj).toHaveBeenCalled();
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe('addListeners', () => {
|
|
43
|
-
it('Should add listeners', () => {
|
|
44
|
-
const spyObj = jest.spyOn(wrapper.vm.dropArea, 'addEventListener');
|
|
45
|
-
wrapper.vm.addListeners();
|
|
46
|
-
expect(spyObj).toHaveBeenCalled();
|
|
47
|
-
});
|
|
48
|
-
});
|
|
32
|
+
it('handleFileChange should update files and emit event', async () => {
|
|
33
|
+
const file = new File(['file content'], 'test.pdf', { type: 'application/pdf' });
|
|
34
|
+
const input = wrapper.find('input[type="file"]');
|
|
49
35
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const file = new File([], 'test');
|
|
53
|
-
component.fileChange([file]);
|
|
54
|
-
expect(component.files).toEqual([file]);
|
|
36
|
+
Object.defineProperty(input.element, 'files', {
|
|
37
|
+
value: [file],
|
|
55
38
|
});
|
|
39
|
+
|
|
40
|
+
await input.trigger('change');
|
|
41
|
+
expect(wrapper.vm.files).toHaveLength(1);
|
|
42
|
+
expect(wrapper.emitted().onFileChange).toBeTruthy();
|
|
56
43
|
});
|
|
44
|
+
|
|
57
45
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
expect(component.files.length).toEqual(0);
|
|
64
|
-
});
|
|
46
|
+
it('remove should remove file and emit onFileChange', () => {
|
|
47
|
+
wrapper.vm.files = [{ name: 'test.pdf', size: 1000 }];
|
|
48
|
+
wrapper.vm.remove(0);
|
|
49
|
+
expect(wrapper.vm.files).toHaveLength(0);
|
|
50
|
+
expect(wrapper.emitted().onFileChange).toBeTruthy();
|
|
65
51
|
});
|
|
66
52
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
component.files = [file];
|
|
72
|
-
component.remove(0);
|
|
73
|
-
expect(component.files).toEqual([]);
|
|
74
|
-
expect(spy).toHaveBeenCalled();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should remove an item', () => {
|
|
78
|
-
const spy = jest.spyOn(component, 'reset');
|
|
79
|
-
const file = new File([], 'test');
|
|
80
|
-
const file2 = new File([], 'test2');
|
|
81
|
-
component.files = [file, file2];
|
|
82
|
-
component.remove(0);
|
|
83
|
-
expect(component.files).toEqual([file2]);
|
|
84
|
-
expect(spy).not.toHaveBeenCalled();
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
describe('onDownload', () => {
|
|
88
|
-
it('should remove an item', () => {
|
|
89
|
-
component.onDownload(1);
|
|
90
|
-
expect(wrapper.emitted().onDownload[0][0]).toBe(1);
|
|
91
|
-
});
|
|
53
|
+
it('addMoreFiles should trigger input click', async () => {
|
|
54
|
+
const input = wrapper.find('input[type="file"]');
|
|
55
|
+
await wrapper.vm.addMoreFiles();
|
|
56
|
+
expect(input.exists()).toBe(true);
|
|
92
57
|
});
|
|
58
|
+
|
|
93
59
|
});
|
|
94
60
|
|
|
95
61
|
describe('Computed', () => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should return true when files length is more than zero', () => {
|
|
102
|
-
component.files = [new File([], 'test')];
|
|
103
|
-
expect(component.hasFiles).toBeTruthy();
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should return true when files length is more than zero', async () => {
|
|
107
|
-
await wrapper.setProps({
|
|
108
|
-
downloadFiles: [new File([], 'test')],
|
|
109
|
-
});
|
|
110
|
-
expect(component.hasFiles).toBeTruthy();
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
describe('filesLength', () => {
|
|
114
|
-
it('should return files and downloadFiles length', async () => {
|
|
115
|
-
await wrapper.setProps({
|
|
116
|
-
downloadFiles: [new File([], 'test')],
|
|
117
|
-
});
|
|
118
|
-
component.files = [new File([], 'test2')];
|
|
119
|
-
expect(component.filesLength).toBe(2);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
describe('disabledButton', () => {
|
|
123
|
-
it('should return files and downloadFiles length', async () => {
|
|
124
|
-
await wrapper.setProps({
|
|
125
|
-
maxFilesNumber: 0,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
expect(component.disabledButton).toBeFalsy();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('should return files and downloadFiles length', async () => {
|
|
132
|
-
await wrapper.setProps({
|
|
133
|
-
maxFilesNumber: 2,
|
|
134
|
-
downloadFiles: [new File([], 'test')],
|
|
135
|
-
});
|
|
136
|
-
component.files = [new File([], 'test2')];
|
|
137
|
-
|
|
138
|
-
expect(component.disabledButton).toBeTruthy();
|
|
139
|
-
});
|
|
62
|
+
it('hasFiles should return true if there are files', () => {
|
|
63
|
+
wrapper.vm.files = [{ name: 'test.pdf', size: 1000 }];
|
|
64
|
+
expect(wrapper.vm.hasFiles).toBe(true);
|
|
140
65
|
});
|
|
141
66
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
maxFilesNumber: 2,
|
|
146
|
-
downloadFiles: [new File([], 'test')],
|
|
147
|
-
});
|
|
148
|
-
component.files = [new File([], 'test2')];
|
|
149
|
-
|
|
150
|
-
expect(component.canAddMoreFiles).toBeFalsy();
|
|
151
|
-
});
|
|
67
|
+
it('canAddMoreFiles should return false if maxFilesNumber is reached', () => {
|
|
68
|
+
wrapper.vm.files = Array(10).fill({ name: 'test.pdf', size: 1000 });
|
|
69
|
+
expect(wrapper.vm.canAddMoreFiles).toBe(false);
|
|
152
70
|
});
|
|
153
71
|
});
|
|
154
72
|
|
|
155
|
-
describe('
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
await wrapper.setProps({
|
|
167
|
-
maxFileSize: 3,
|
|
168
|
-
});
|
|
169
|
-
wrapper.vm.$options.watch.files.call(component, [
|
|
170
|
-
{ size: 4145728, type: 'image/jpeg' },
|
|
171
|
-
]);
|
|
172
|
-
expect(wrapper.emitted().onMaxFileSizeWarning).toBeDefined();
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('should not add invalid types files', () => {
|
|
176
|
-
wrapper.vm.$options.watch.files.call(
|
|
177
|
-
component,
|
|
178
|
-
Array.from(Array(1).keys()).map(() => ({ type: 'image/test' }))
|
|
179
|
-
);
|
|
180
|
-
expect(component.files).toEqual([]);
|
|
181
|
-
});
|
|
73
|
+
describe('Watchers', () => {
|
|
74
|
+
it('should emit onMaxFilesNumberWarning if maxFilesNumber is exceeded', async () => {
|
|
75
|
+
wrapper.setProps({ maxFilesNumber: 10 });
|
|
76
|
+
|
|
77
|
+
const files = Array(11).fill(new File(['content'], 'test.pdf', { type: 'application/pdf' }));
|
|
78
|
+
const input = wrapper.find('input[type="file"]');
|
|
79
|
+
Object.defineProperty(input.element, 'files', { value: files });
|
|
80
|
+
|
|
81
|
+
await input.trigger('change');
|
|
82
|
+
expect(wrapper.vm.files).toHaveLength(10);
|
|
83
|
+
expect(wrapper.emitted().onMaxFilesNumberWarning).toBeTruthy();
|
|
182
84
|
});
|
|
85
|
+
|
|
86
|
+
it('should emit onInvalidFiles if a file exceeds maxFileSize', async () => {
|
|
87
|
+
wrapper.setProps({ maxFileSize: 1 });
|
|
88
|
+
|
|
89
|
+
//cria um arquivo de 3MB
|
|
90
|
+
const file = new File(['a'.repeat(3 * 1024 * 1024)], 'test.pdf', { type: 'application/pdf' });
|
|
91
|
+
const input = wrapper.find('input[type="file"]');
|
|
92
|
+
|
|
93
|
+
Object.defineProperty(input.element, 'files', { value: [file] });
|
|
94
|
+
|
|
95
|
+
await input.trigger('change');
|
|
96
|
+
expect(wrapper.vm.files).toHaveLength(0);
|
|
97
|
+
expect(wrapper.emitted().onInvalidFiles).toBeTruthy();
|
|
98
|
+
});
|
|
99
|
+
|
|
183
100
|
});
|
|
101
|
+
|
|
184
102
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.collapse-enter-active,
|
|
2
|
+
.collapse-leave-active {
|
|
3
|
+
overflow: hidden;
|
|
4
|
+
transition: max-height 0.5s ease;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.collapse-enter-from,
|
|
8
|
+
.collapse-leave-to {
|
|
9
|
+
max-height: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.collapse-enter-to,
|
|
13
|
+
.collapse-leave-from {
|
|
14
|
+
max-height: 400px;
|
|
15
|
+
}
|