update AIChart, customer followup, media selector
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<div class="add-trigger">
|
||||
<t-popover
|
||||
v-model:visible="capturePopoverVisible"
|
||||
placement="left"
|
||||
theme="light"
|
||||
>
|
||||
<t-button
|
||||
class="capture"
|
||||
theme="primary"
|
||||
variant="dashed"
|
||||
:loading="busy"
|
||||
:disabled="busy"
|
||||
>
|
||||
<template #icon>
|
||||
<t-icon name="camera" />
|
||||
</template>
|
||||
拍摄
|
||||
</t-button>
|
||||
<template #content>
|
||||
<div class="add-actions">
|
||||
<t-button
|
||||
v-for="(action, index) in captureActionList"
|
||||
:key="`${action.emit}-${index}`"
|
||||
variant="text"
|
||||
:theme="action.theme"
|
||||
class="add-action"
|
||||
:disabled="busy"
|
||||
@click="handleCaptureAction(action)"
|
||||
>
|
||||
<template #icon v-if="action.icon">
|
||||
<t-icon :name="action.icon" />
|
||||
</template>
|
||||
<span v-text="action.text" />
|
||||
</t-button>
|
||||
</div>
|
||||
</template>
|
||||
</t-popover>
|
||||
<t-button
|
||||
class="file"
|
||||
theme="primary"
|
||||
variant="dashed"
|
||||
:loading="busy"
|
||||
:disabled="busy"
|
||||
@click="handleFileAction"
|
||||
>
|
||||
<template #icon>
|
||||
<t-icon name="file-attachment" />
|
||||
</template>
|
||||
<span v-text="addText" />
|
||||
</t-button>
|
||||
</div>
|
||||
<input
|
||||
v-if="uploadEnabled"
|
||||
ref="fileInput"
|
||||
class="file-input"
|
||||
type="file"
|
||||
accept="*/*"
|
||||
multiple
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
<input
|
||||
v-if="uploadEnabled"
|
||||
ref="photoFileInput"
|
||||
class="file-input"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
capture="environment"
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
<input
|
||||
v-if="uploadEnabled"
|
||||
ref="videoFileInput"
|
||||
class="file-input"
|
||||
type="file"
|
||||
accept="video/*"
|
||||
capture="environment"
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { MediaSelectorAddAction } from "./types";
|
||||
|
||||
interface Props {
|
||||
addActions: readonly MediaSelectorAddAction[];
|
||||
addText: string;
|
||||
busy: boolean;
|
||||
uploadEnabled: boolean;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<{
|
||||
(event: "add"): void;
|
||||
(event: "capture-photo"): void;
|
||||
(event: "capture-video"): void;
|
||||
(event: "file-change", value: Event): void;
|
||||
}>();
|
||||
const emitExternal = (event: string): void => {
|
||||
(emit as unknown as (eventName: string) => void)(event);
|
||||
};
|
||||
|
||||
const capturePopoverVisible = ref(false);
|
||||
const fileInput = ref<HTMLInputElement>();
|
||||
const photoFileInput = ref<HTMLInputElement>();
|
||||
const videoFileInput = ref<HTMLInputElement>();
|
||||
const captureActionList = computed<readonly MediaSelectorAddAction[]>(() => [{
|
||||
icon: "camera",
|
||||
emit: "capture-photo",
|
||||
text: "拍照片",
|
||||
theme: "primary"
|
||||
}, {
|
||||
icon: "video-camera-1",
|
||||
emit: "capture-video",
|
||||
text: "录视频",
|
||||
theme: "primary"
|
||||
}, ...props.addActions]);
|
||||
|
||||
function handleFileAction(): void {
|
||||
capturePopoverVisible.value = false;
|
||||
if (props.uploadEnabled) {
|
||||
fileInput.value?.click();
|
||||
return;
|
||||
}
|
||||
emit("add");
|
||||
}
|
||||
|
||||
function handleCaptureAction(action: MediaSelectorAddAction): void {
|
||||
capturePopoverVisible.value = false;
|
||||
if (action.emit === "capture-photo" && props.uploadEnabled) {
|
||||
photoFileInput.value?.click();
|
||||
return;
|
||||
}
|
||||
if (action.emit === "capture-video" && props.uploadEnabled) {
|
||||
videoFileInput.value?.click();
|
||||
return;
|
||||
}
|
||||
emitExternal(action.emit);
|
||||
}
|
||||
|
||||
function handleFileChange(event: Event): void {
|
||||
emit("file-change", event);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.add-trigger {
|
||||
--td-popover-padding: 0 .5rem;
|
||||
gap: .375rem;
|
||||
width: 5.5rem;
|
||||
height: 5.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.t-popover__content) {
|
||||
border-radius: .875rem;
|
||||
}
|
||||
|
||||
.capture,
|
||||
.file {
|
||||
--td-button-border-radius: .875rem;
|
||||
|
||||
width: 5.5rem;
|
||||
height: 2.5625rem;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.add-actions {
|
||||
gap: .25rem;
|
||||
display: grid;
|
||||
padding: .5rem 0;
|
||||
|
||||
.add-action {
|
||||
--td-button-medium-height: 32px;
|
||||
--td-button-medium-padding-horizontal: 10px;
|
||||
|
||||
gap: .5rem;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
font-weight: unset;
|
||||
justify-content: start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:global(html.theme-dark) {
|
||||
.capture,
|
||||
.file {
|
||||
background: rgba(37, 99, 235, .16);
|
||||
border-color: rgba(96, 165, 250, .28);
|
||||
|
||||
span {
|
||||
color: #93c5fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user