Skip to content

Commit 9bf0d1e

Browse files
committed
#29 destructurize item details field
1 parent acd69d6 commit 9bf0d1e

File tree

6 files changed

+435
-0
lines changed

6 files changed

+435
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<template>
2+
<v-checkbox
3+
v-model="isChecked"
4+
:label="field.text"
5+
:disabled="field.disabled"
6+
color="primary"
7+
hide-details
8+
@change="onChange()"
9+
></v-checkbox>
10+
</template>
11+
<script>
12+
13+
export default {
14+
name: 'CheckboxField',
15+
props: [
16+
'value',
17+
'field',
18+
],
19+
data () {
20+
return {
21+
isChecked: false,
22+
}
23+
},
24+
methods: {
25+
onChange () {
26+
this.isChecked = this.isChecked ? 1 : 0
27+
this.$emit('input', this.isChecked)
28+
},
29+
},
30+
watch: {
31+
value: {
32+
immediate: true,
33+
handler (val) {
34+
this.isChecked = val
35+
},
36+
},
37+
},
38+
}
39+
</script>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<template>
2+
<v-menu
3+
v-model="datepicker"
4+
:close-on-content-click="false"
5+
:nudge-right="40"
6+
min-width="290px"
7+
transition="scale-transition"
8+
lazy
9+
offset-y
10+
full-width
11+
>
12+
<template v-slot:activator="{ on }">
13+
<v-text-field
14+
v-model="date"
15+
v-on="on"
16+
:label="field.text"
17+
prepend-icon="event"
18+
readonly
19+
@blur="onBlur()"
20+
></v-text-field>
21+
</template>
22+
<v-date-picker
23+
v-model="value"
24+
:first-day-of-week="firstDayOfWeek"
25+
:locale="locale"
26+
scrollable
27+
@input="datepicker = false"
28+
@change="onChange()"
29+
></v-date-picker>
30+
</v-menu>
31+
</template>
32+
<script>
33+
import crud from '@/config/crud'
34+
35+
export default {
36+
name: 'DateField',
37+
props: [
38+
'value',
39+
'field',
40+
],
41+
data () {
42+
return {
43+
date: undefined,
44+
datepicker: false,
45+
}
46+
},
47+
computed: {
48+
locale () {
49+
return crud.locale || 'en-us'
50+
},
51+
firstDayOfWeek () {
52+
return crud.firstDayOfWeek || 0
53+
},
54+
},
55+
methods: {
56+
onBlur () {
57+
this.emitNewValue()
58+
},
59+
onChange () {
60+
this.emitNewValue()
61+
},
62+
emitNewValue () {
63+
this.$emit('input', this.date)
64+
},
65+
},
66+
watch: {
67+
value: {
68+
immediate: true,
69+
handler (val) {
70+
this.date = val
71+
},
72+
},
73+
},
74+
}
75+
</script>
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
<template>
2+
<field-wrapper>
3+
<v-row dense>
4+
<v-col
5+
cols="12"
6+
sm="5"
7+
>
8+
<v-btn
9+
:loading="uploadLoader"
10+
:class="fileUploadBtn(uploadStatus)"
11+
class="jbtn-file"
12+
dark
13+
>
14+
{{ $t('global.details.files.upload') }}
15+
<v-icon
16+
dark
17+
right
18+
>
19+
{{ fileUploadIcon(uploadStatus) }}
20+
</v-icon>
21+
<input
22+
:id="field.name"
23+
:multiple="false"
24+
:disabled="field.disabled"
25+
type="file"
26+
accept="*"
27+
ref="fileInput"
28+
@change="fileSelected($event, field)"
29+
/>
30+
</v-btn>
31+
</v-col>
32+
<v-col
33+
cols="12"
34+
sm="7"
35+
>
36+
<v-text-field
37+
:rules="rules"
38+
:label="field.text"
39+
:value="filename"
40+
disabled
41+
hide-details
42+
></v-text-field>
43+
</v-col>
44+
</v-row>
45+
</field-wrapper>
46+
</template>
47+
<script>
48+
49+
import {
50+
mapState,
51+
mapGetters,
52+
} from 'vuex'
53+
54+
import FieldWrapper from './components/FieldWrapper.vue'
55+
56+
export default {
57+
name: 'FileField',
58+
components: {
59+
FieldWrapper,
60+
},
61+
props: [
62+
'value',
63+
'fieldType',
64+
'field',
65+
'rules',
66+
],
67+
data () {
68+
return {
69+
file: undefined,
70+
uploadStatus: 'ready',
71+
uploadLoader: false,
72+
}
73+
},
74+
computed: {
75+
...mapState('crud', [
76+
'details',
77+
'path',
78+
'prefix',
79+
]),
80+
...mapGetters('crud', ['uploadPath']),
81+
filename () {
82+
let filename
83+
if (this.fieldType === 'file' && this.file !== undefined && this.file !== null) {
84+
try {
85+
filename = JSON.parse(this.file).filename
86+
} catch (e) {
87+
return ''
88+
}
89+
}
90+
return filename
91+
},
92+
},
93+
methods: {
94+
onBlur () {
95+
this.$emit('input', this.text)
96+
this.$emit('change')
97+
},
98+
fileUploadBtn (status) {
99+
const btnClasses = {
100+
ready: 'primary',
101+
success: 'success',
102+
error: 'error',
103+
}
104+
return btnClasses[status]
105+
},
106+
fileUploadIcon (status) {
107+
const icons = {
108+
ready: 'save_alt',
109+
success: 'check',
110+
error: 'close',
111+
}
112+
return icons[status]
113+
},
114+
fileSelected (e, field) {
115+
const file = e.target.files[0]
116+
if (file) {
117+
this.uploadLoader = true
118+
const formData = new FormData()
119+
formData.append('file', file)
120+
formData.append('module', this.prefix)
121+
formData.append('table', this.path)
122+
formData.append('field', field.column)
123+
this.$http.post(this.uploadPath, formData, {}).then(
124+
(response) => {
125+
if (response.body.status === 0) {
126+
this.file = JSON.stringify({
127+
filename: file.name,
128+
mime: file.type,
129+
size: file.size,
130+
path: response.body.path,
131+
uploaded: 1,
132+
})
133+
this.$emit('input', this.file)
134+
this.uploadStatus = 'success'
135+
} else {
136+
this.uploadStatus = 'error'
137+
if (response.body.status === -1) {
138+
this.openAlertBox([
139+
'alertError',
140+
response.body.msg,
141+
])
142+
} else if (response.body.status === -2) {
143+
this.openAlertBox([
144+
'alertValidationError',
145+
response.body.msg,
146+
])
147+
}
148+
}
149+
this.uploadLoader = false
150+
},
151+
() => {
152+
this.uploadLoader = false
153+
this.uploadStatus = 'error'
154+
},
155+
)
156+
}
157+
},
158+
},
159+
watch: {
160+
value: {
161+
immediate: true,
162+
handler (val) {
163+
this.file = val
164+
},
165+
},
166+
reload: function (val) {
167+
if (val) {
168+
this.uploadLoader = false
169+
this.uploadStatus = 'ready'
170+
}
171+
},
172+
uploadStatus: function (val) {
173+
if (val !== 'ready') {
174+
setTimeout(() => {
175+
this.uploadStatus = 'ready'
176+
}, 1000)
177+
}
178+
},
179+
},
180+
}
181+
</script>
182+
183+
<style lang="scss" scoped>
184+
.jbtn-file {
185+
cursor: pointer;
186+
position: relative;
187+
overflow: hidden;
188+
margin: 0px;
189+
width: 100%;
190+
}
191+
.jbtn-file input[type='file'] {
192+
position: absolute;
193+
top: 0;
194+
right: 0;
195+
min-width: 100%;
196+
min-height: 100%;
197+
font-size: 100px;
198+
text-align: right;
199+
filter: alpha(opacity=0);
200+
opacity: 0;
201+
outline: none;
202+
cursor: inherit;
203+
display: block;
204+
}
205+
</style>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<template>
2+
<v-text-field
3+
v-model="text"
4+
:type="['number', 'decimal'].includes(fieldType) ? 'number' : 'text'"
5+
:label="field.text"
6+
:disabled="field.disabled"
7+
:rules="rules"
8+
:step="fieldType == 'decimal' ? 0.01 : 1"
9+
:mask="['date', 'time', 'datetime'].includes(fieldType) ? masks[fieldType] : undefined"
10+
:return-masked-value="['date', 'time', 'datetime'].includes(fieldType) ? true : false"
11+
min="0"
12+
hide-details
13+
@blur="onBlur()"
14+
></v-text-field>
15+
</template>
16+
17+
<script>
18+
19+
export default {
20+
name: 'TextField',
21+
props: [
22+
'value',
23+
'fieldType',
24+
'field',
25+
'rules',
26+
],
27+
data () {
28+
return {
29+
text: undefined,
30+
masks: {
31+
date: '####-##-##',
32+
time: '##:##',
33+
datetime: '####-##-## ##:##:##',
34+
},
35+
}
36+
},
37+
methods: {
38+
onBlur () {
39+
this.$emit('input', this.text)
40+
},
41+
},
42+
watch: {
43+
value: {
44+
immediate: true,
45+
handler (val) {
46+
this.text = val
47+
},
48+
},
49+
},
50+
}
51+
</script>

0 commit comments

Comments
 (0)