updated attachments

This commit is contained in:
2023-07-19 14:56:56 +10:00
parent bfacb86f35
commit 1598efac35
11 changed files with 212 additions and 196 deletions

View File

@@ -1,28 +1,32 @@
<template>
<div>
<SMHeader
v-if="props.attachments && props.attachments.length > 0"
v-if="showEditor || (modelValue && modelValue.length > 0)"
:no-copy="props.showEditor"
text="Files" />
<p v-if="props.showEditor" class="small">
{{ modelValue.length }} file{{ modelValue.length != 1 ? "s" : "" }}
</p>
<table
v-if="props.attachments && props.attachments.length > 0"
v-if="modelValue && modelValue.length > 0"
class="w-full border-1 rounded-2 bg-white text-sm mt-2">
<tbody>
<tr v-for="file of props.attachments" :key="file.id">
<td class="py-2 pl-2">
<tr v-for="file of modelValue" :key="file.id">
<td class="py-2 pl-2 hidden sm:block">
<img
:src="getFileIconImagePath(file.name || file.title)"
class="h-10 text-center" />
</td>
<td class="">
<td class="pl-2 py-4 w-full">
<a :href="file.url">{{ file.title || file.name }}</a>
</td>
<td class="">
<td class="pr-2">
<a :href="file.url + '?download=1'"
><svg
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="h-5 text-gray">
class="h-7 pt-1 text-gray">
<path
d="M12 10V20M12 20L9.5 17.5M12 20L14.5 17.5"
stroke="currentColor"
@@ -37,12 +41,20 @@
</svg>
</a>
</td>
<td class="text-xs text-gray">
<td
class="text-xs text-gray whitespace-nowrap pr-2 py-2 hidden sm:table-cell">
({{ bytesReadable(file.size) }})
</td>
</tr>
</tbody>
</table>
<button
v-if="props.showEditor"
type="button"
class="font-medium mt-4 px-6 py-1.5 rounded-md hover:shadow-md transition text-sm bg-sky-600 hover:bg-sky-500 text-white cursor-pointer"
@click="handleClickAdd">
Add File
</button>
</div>
</template>
@@ -50,16 +62,53 @@
import { bytesReadable } from "../helpers/types";
import { getFileIconImagePath } from "../helpers/utils";
import SMHeader from "../components/SMHeader.vue";
import { openDialog } from "../components/SMDialog";
import SMDialogMedia from "./dialogs/SMDialogMedia.vue";
import { Media } from "../helpers/api.types";
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
attachments: {
type: Object,
modelValue: {
type: Array,
default: () => [],
required: true,
},
showEditor: {
type: Boolean,
default: false,
required: false,
},
});
/**
* Handle the user adding a new media item.
*/
const handleClickAdd = async () => {
let result = await openDialog(SMDialogMedia, {
mime: "",
accepts: "",
allowUpload: true,
multiple: true,
});
if (result) {
const mediaResult = result as Media[];
let newValue = props.modelValue;
let mediaIds = new Set(newValue.map((item) => item.id));
mediaResult.forEach((item) => {
if (!mediaIds.has(item.id)) {
newValue.push(item);
mediaIds.add(item.id);
}
});
emits("update:modelValue", newValue);
}
};
</script>
<style lang="scss">
<!-- <style lang="scss">
.attachment-list {
border: 1px solid var(--base-color);
border-collapse: collapse;
@@ -154,4 +203,4 @@ const props = defineProps({
}
}
}
</style>
</style> -->

View File

@@ -2,10 +2,12 @@
<component
:is="`h${props.size}`"
:id="id"
class="sm-header cursor-pointer"
:class="['sm-header', props.noCopy ? '' : 'cursor-pointer']"
@click.prevent="copyAnchor">
{{ props.text }}
<span class="pl-2 text-sky-5 opacity-75 hidden">#</span>
<span v-if="!props.noCopy" class="pl-2 text-sky-5 opacity-75 hidden"
>#</span
>
</component>
</template>
@@ -28,6 +30,11 @@ const props = defineProps({
default: "",
required: false,
},
noCopy: {
type: Boolean,
default: false,
required: false,
},
});
const computedHeaderId = (text: string): string => {
@@ -35,29 +42,32 @@ const computedHeaderId = (text: string): string => {
};
const id = ref(
props.id && props.id.length > 0 ? props.id : computedHeaderId(props.text)
props.id && props.id.length > 0 ? props.id : computedHeaderId(props.text),
);
const copyAnchor = () => {
const currentUrl = window.location.href.replace(/#.*/, "");
const newUrl = currentUrl + "#" + id.value;
if (props.noCopy === false) {
const currentUrl = window.location.href.replace(/#.*/, "");
const newUrl = currentUrl + "#" + id.value;
navigator.clipboard
.writeText(newUrl)
.then(() => {
useToastStore().addToast({
title: "Copied to Clipboard",
content: "The heading URL has been copied to the clipboard.",
type: "success",
navigator.clipboard
.writeText(newUrl)
.then(() => {
useToastStore().addToast({
title: "Copied to Clipboard",
content:
"The heading URL has been copied to the clipboard.",
type: "success",
});
})
.catch(() => {
useToastStore().addToast({
title: "Copy to Clipboard",
content: "Failed to copy the heading URL to the clipboard.",
type: "danger",
});
});
})
.catch(() => {
useToastStore().addToast({
title: "Copy to Clipboard",
content: "Failed to copy the heading URL to the clipboard.",
type: "danger",
});
});
}
};
</script>

View File

@@ -1,6 +1,5 @@
<template>
<div class="input-attachments">
<label>Files</label>
<ul>
<li v-if="mediaItems.length == 0" class="attachments-none">
<ion-icon name="sad-outline"></ion-icon>

View File

@@ -41,7 +41,7 @@
:model-value="article.gallery" />
<SMAttachments
v-if="article.attachments.length > 0"
:attachments="article.attachments || []" />
:model-value="article.attachments || []" />
</div>
</template>
</template>
@@ -136,6 +136,8 @@ const handleLoad = async () => {
"large",
);
applicationStore.setDynamicTitle(article.value.title);
console.log(article.value);
} else {
pageStatus.value = 404;
}

View File

@@ -56,7 +56,10 @@
</p>
<SMImageGallery show-editor v-model:model-value="gallery" />
</div>
<SMInputAttachments v-model:model-value="attachments" />
<SMAttachments
class="mb-8"
show-editor
v-model:model-value="attachments" />
<div class="flex flex-justify-end">
<input
type="submit"
@@ -75,7 +78,7 @@ import SMEditor from "../../components/SMEditor.vue";
import SMForm from "../../components/SMForm.vue";
import SMInput from "../../components/SMInput.vue";
import SMDropdown from "../../components/SMDropdown.vue";
import SMInputAttachments from "../../components/SMInputAttachments.vue";
import SMAttachments from "../../components/SMAttachments.vue";
import { api } from "../../helpers/api";
import { ArticleResponse, UserCollection } from "../../helpers/api.types";
import { SMDate } from "../../helpers/datetime";
@@ -181,12 +184,7 @@ const loadData = async () => {
form.controls.content.value = data.article.content;
form.controls.hero.value = data.article.hero;
attachments.value = (data.article.attachments || []).map(
function (attachment) {
return attachment.id.toString();
},
);
attachments.value = data.article.attachments;
gallery.value = data.article.gallery;
} else {
pageError.value = 404;
@@ -211,6 +209,7 @@ const handleSubmit = async () => {
content: form.controls.content.value,
hero: form.controls.hero.value.id,
gallery: gallery.value.map((item) => item.id),
attachments: attachments.value.map((item) => item.id),
};
let article_id = "";
@@ -236,13 +235,6 @@ const handleSubmit = async () => {
}
}
await api.put({
url: `/articles/${article_id}/attachments`,
body: {
attachments: attachments.value,
},
});
useToastStore().addToast({
title: route.params.id ? "Article Updated" : "Article Created",
content: route.params.id