|
|
@@ -138,6 +138,52 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- Tab: Mídias -->
|
|
|
+ <div v-show="currentTab === 'midias'">
|
|
|
+ <div class="flex justify-end q-mb-sm">
|
|
|
+ <q-btn
|
|
|
+ color="primary"
|
|
|
+ icon="mdi-upload-outline"
|
|
|
+ unelevated
|
|
|
+ style="width: 40px; height: 40px"
|
|
|
+ :loading="uploadingMedia"
|
|
|
+ @click="triggerFileInput"
|
|
|
+ />
|
|
|
+ <input
|
|
|
+ ref="fileInputRef"
|
|
|
+ type="file"
|
|
|
+ style="display: none"
|
|
|
+ @change="onFileSelected"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style="
|
|
|
+ height: 100%;
|
|
|
+ max-height: 380px;
|
|
|
+ overflow-y: auto;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 8px;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <template v-if="medias.length">
|
|
|
+ <KanbanMediaCard
|
|
|
+ v-for="media in medias"
|
|
|
+ :key="media.id"
|
|
|
+ :file-name="media.file_name"
|
|
|
+ :file-url="media.file_url"
|
|
|
+ :mime-type="media.mime_type"
|
|
|
+ :created-at="media.created_at"
|
|
|
+ :user-name="media.user_name"
|
|
|
+ @delete="onDeleteMedia(media)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <div v-else class="flex flex-center full-height text-grey-5 text-body2">
|
|
|
+ Nenhuma mídia anexada.
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</q-card-section>
|
|
|
|
|
|
<q-card-actions align="right" class="q-px-md q-pb-md" style="flex-shrink: 0">
|
|
|
@@ -160,6 +206,7 @@ import DefaultInput from "src/components/defaults/DefaultInput.vue";
|
|
|
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
|
|
|
import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
|
|
|
import KanbanCommentCard from "./KanbanCommentCard.vue";
|
|
|
+import KanbanMediaCard from "./KanbanMediaCard.vue";
|
|
|
|
|
|
import { createKanban, updateKanban } from "src/api/kanban";
|
|
|
import {
|
|
|
@@ -168,6 +215,11 @@ import {
|
|
|
updateKanbanReply,
|
|
|
deleteKanbanReply,
|
|
|
} from "src/api/kanban_reply";
|
|
|
+import {
|
|
|
+ getKanbanMedias,
|
|
|
+ uploadKanbanMedia,
|
|
|
+ deleteKanbanMedia,
|
|
|
+} from "src/api/kanban_media";
|
|
|
import { getUsersByUnit } from "src/api/user";
|
|
|
|
|
|
defineEmits([...useDialogPluginComponent.emits]);
|
|
|
@@ -182,15 +234,19 @@ const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
|
|
|
|
|
|
const $q = useQuasar();
|
|
|
|
|
|
-const formRef = ref(null);
|
|
|
-const loading = ref(false);
|
|
|
-const currentTab = ref("atividade");
|
|
|
-const userOptions = ref([]);
|
|
|
-const replies = ref([]);
|
|
|
+const formRef = ref(null);
|
|
|
+const loading = ref(false);
|
|
|
+const currentTab = ref("atividade");
|
|
|
+const userOptions = ref([]);
|
|
|
+const replies = ref([]);
|
|
|
+const medias = ref([]);
|
|
|
+const uploadingMedia = ref(false);
|
|
|
+const fileInputRef = ref(null);
|
|
|
|
|
|
const tabs = computed(() => [
|
|
|
{ name: "atividade", label: "Atividade" },
|
|
|
{ name: "comentarios", label: "Comentários" },
|
|
|
+ { name: "midias", label: "Mídias" },
|
|
|
]);
|
|
|
|
|
|
const priorityOptions = [
|
|
|
@@ -267,6 +323,40 @@ const loadReplies = async () => {
|
|
|
replies.value = await getKanbanReplies(card.id);
|
|
|
};
|
|
|
|
|
|
+const loadMedias = async () => {
|
|
|
+ if (!card?.id) return;
|
|
|
+ medias.value = await getKanbanMedias(card.id);
|
|
|
+};
|
|
|
+
|
|
|
+const triggerFileInput = () => {
|
|
|
+ fileInputRef.value?.click();
|
|
|
+};
|
|
|
+
|
|
|
+const onFileSelected = async (event) => {
|
|
|
+ const file = event.target.files?.[0];
|
|
|
+ if (!file) return;
|
|
|
+ uploadingMedia.value = true;
|
|
|
+ try {
|
|
|
+ await uploadKanbanMedia(card.id, file);
|
|
|
+ await loadMedias();
|
|
|
+ } finally {
|
|
|
+ uploadingMedia.value = false;
|
|
|
+ event.target.value = "";
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const onDeleteMedia = (media) => {
|
|
|
+ $q.dialog({
|
|
|
+ title: "Excluir Mídia",
|
|
|
+ message: `Deseja excluir "${media.file_name}"?`,
|
|
|
+ cancel: { outline: true, color: "primary", label: "Cancelar" },
|
|
|
+ ok: { color: "negative", label: "Excluir" },
|
|
|
+ }).onOk(async () => {
|
|
|
+ await deleteKanbanMedia(card.id, media.id);
|
|
|
+ loadMedias();
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
const onAddComment = () => {
|
|
|
$q.dialog({
|
|
|
title: "Adicionar Comentário",
|
|
|
@@ -323,5 +413,6 @@ const onOKClick = async () => {
|
|
|
onMounted(() => {
|
|
|
loadUsers();
|
|
|
loadReplies();
|
|
|
+ loadMedias();
|
|
|
});
|
|
|
</script>
|