mirror of
https://github.com/frappe/books.git
synced 2025-02-08 23:18:31 +00:00
fix(ux): allow attach image clear
- refactor attach image
This commit is contained in:
parent
87971b8a6b
commit
b24fd1123d
@ -1,27 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="relative bg-white border rounded-full flex-center overflow-hidden"
|
class="
|
||||||
|
relative
|
||||||
|
bg-white
|
||||||
|
border
|
||||||
|
rounded-full
|
||||||
|
flex-center
|
||||||
|
overflow-hidden
|
||||||
|
group
|
||||||
|
"
|
||||||
:class="{
|
:class="{
|
||||||
'w-20 h-20': size !== 'small',
|
'w-20 h-20': size !== 'small',
|
||||||
'w-12 h-12': size === 'small',
|
'w-12 h-12': size === 'small',
|
||||||
'cursor-pointer': !isReadOnly,
|
|
||||||
}"
|
}"
|
||||||
@mouseover="showEdit = true"
|
|
||||||
@mouseleave="showEdit = false"
|
|
||||||
@click="openFileSelector"
|
|
||||||
>
|
>
|
||||||
<template v-if="!value">
|
<img :src="value" v-if="value" />
|
||||||
|
<div :class="[!isReadOnly ? 'group-hover:opacity-90' : '']" v-else>
|
||||||
<div
|
<div
|
||||||
v-if="letterPlaceholder"
|
v-if="letterPlaceholder"
|
||||||
class="
|
class="
|
||||||
bg-gray-500
|
|
||||||
flex
|
flex
|
||||||
h-full
|
h-full
|
||||||
items-center
|
items-center
|
||||||
justify-center
|
justify-center
|
||||||
text-white
|
text-gray-400
|
||||||
|
font-semibold
|
||||||
w-full
|
w-full
|
||||||
text-4xl
|
text-4xl
|
||||||
|
select-none
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ letterPlaceholder }}
|
{{ letterPlaceholder }}
|
||||||
@ -38,48 +44,52 @@
|
|||||||
fill-rule="nonzero"
|
fill-rule="nonzero"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
|
||||||
<div v-else>
|
|
||||||
<img :src="value" />
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-show="showEdit"
|
class="hidden w-full h-full absolute justify-center items-end"
|
||||||
class="
|
:class="[!isReadOnly ? 'group-hover:flex' : '']"
|
||||||
absolute
|
style="background: rgba(0, 0, 0, 0.2); backdrop-filter: blur(2px)"
|
||||||
bottom-0
|
|
||||||
text-gray-500 text-center text-xs
|
|
||||||
pt-3
|
|
||||||
pb-1
|
|
||||||
select-none
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ !isReadOnly ? t`Edit` : '' }}
|
<button class="bg-gray-300 p-0.5 rounded mb-1" @click="handleClick">
|
||||||
|
<FeatherIcon
|
||||||
|
:name="shouldClear ? 'x' : 'upload'"
|
||||||
|
class="w-4 h-4 text-gray-600"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
<script>
|
|
||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
import { fyo } from 'src/initFyo';
|
import { fyo } from 'src/initFyo';
|
||||||
import { getDataURL } from 'src/utils/misc';
|
import { getDataURL } from 'src/utils/misc';
|
||||||
import { IPC_ACTIONS } from 'utils/messages';
|
import { IPC_ACTIONS } from 'utils/messages';
|
||||||
import Base from './Base';
|
import { defineComponent } from 'vue';
|
||||||
|
import FeatherIcon from '../FeatherIcon.vue';
|
||||||
|
import Base from './Base.vue';
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'AttachImage',
|
name: 'AttachImage',
|
||||||
extends: Base,
|
extends: Base,
|
||||||
props: ['letterPlaceholder'],
|
props: {
|
||||||
data() {
|
letterPlaceholder: { type: String, default: '' },
|
||||||
return {
|
value: { type: String, default: '' },
|
||||||
showEdit: false,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async openFileSelector() {
|
async handleClick() {
|
||||||
|
if (this.value) {
|
||||||
|
return await this.clearImage();
|
||||||
|
}
|
||||||
|
return await this.selectImage();
|
||||||
|
},
|
||||||
|
async clearImage() {
|
||||||
|
// @ts-ignore
|
||||||
|
this.triggerChange(null);
|
||||||
|
},
|
||||||
|
async selectImage() {
|
||||||
if (this.isReadOnly) {
|
if (this.isReadOnly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
title: fyo.t`Select Image`,
|
title: fyo.t`Select Image`,
|
||||||
properties: ['openFile'],
|
properties: ['openFile'],
|
||||||
@ -87,21 +97,27 @@ export default {
|
|||||||
{ name: 'Image', extensions: ['png', 'jpg', 'jpeg', 'webp'] },
|
{ name: 'Image', extensions: ['png', 'jpg', 'jpeg', 'webp'] },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const { name, success, data } = await ipcRenderer.invoke(
|
const { name, success, data } = await ipcRenderer.invoke(
|
||||||
IPC_ACTIONS.GET_FILE,
|
IPC_ACTIONS.SELECT_FILE,
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const extension = name.split('.').at(-1);
|
const extension = name.split('.').at(-1);
|
||||||
const type = 'image/' + extension;
|
const type = 'image/' + extension;
|
||||||
const dataURL = await getDataURL(type, data);
|
const dataURL = await getDataURL(type, data);
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
this.triggerChange(dataURL);
|
this.triggerChange(dataURL);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
computed: {
|
||||||
|
shouldClear() {
|
||||||
|
return !!this.value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: { FeatherIcon },
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
:value="doc[imageField.fieldname]"
|
:value="doc[imageField.fieldname]"
|
||||||
@change="(value) => valueChange(imageField, value)"
|
@change="(value) => valueChange(imageField, value)"
|
||||||
size="small"
|
size="small"
|
||||||
:letter-placeholder="doc[titleField.fieldname]?.[0] ?? null"
|
:letter-placeholder="doc[titleField.fieldname]?.[0] ?? ''"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<FormControl
|
||||||
input-class="text-center h-8 bg-transparent"
|
input-class="text-center h-8 bg-transparent"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user