2020-02-18 08:57:00 +01:00
|
|
|
<template>
|
2021-11-07 14:59:20 +01:00
|
|
|
<div class="resource-wrapper" dir="auto">
|
2020-02-18 08:57:00 +01:00
|
|
|
<router-link
|
|
|
|
:to="{
|
|
|
|
name: RouteName.RESOURCE_FOLDER,
|
|
|
|
params: {
|
2022-07-12 10:55:28 +02:00
|
|
|
path: resourcePathArray(resource),
|
2020-02-18 08:57:00 +01:00
|
|
|
preferredUsername: usernameWithDomain(group),
|
|
|
|
},
|
|
|
|
}"
|
|
|
|
>
|
2022-08-26 16:08:58 +02:00
|
|
|
<div class="preview text-mbz-purple dark:text-mbz-purple-300">
|
2022-07-12 10:55:28 +02:00
|
|
|
<Folder :size="48" />
|
2020-02-18 08:57:00 +01:00
|
|
|
</div>
|
|
|
|
<div class="body">
|
|
|
|
<h3>{{ resource.title }}</h3>
|
2022-07-12 10:55:28 +02:00
|
|
|
<span class="host" v-if="inline && resource.updatedAt">{{
|
|
|
|
formatDateTimeString(resource.updatedAt?.toString())
|
2020-11-30 10:24:11 +01:00
|
|
|
}}</span>
|
2020-02-18 08:57:00 +01:00
|
|
|
</div>
|
2022-09-20 16:53:26 +02:00
|
|
|
<draggable
|
2020-02-18 08:57:00 +01:00
|
|
|
v-if="!inline"
|
|
|
|
class="dropzone"
|
|
|
|
v-model="list"
|
2022-07-12 10:55:28 +02:00
|
|
|
itemKey="id"
|
2020-02-18 08:57:00 +01:00
|
|
|
:sort="false"
|
|
|
|
:group="groupObject"
|
|
|
|
@change="onChange"
|
2022-09-20 16:53:26 +02:00
|
|
|
/>
|
2020-02-18 08:57:00 +01:00
|
|
|
</router-link>
|
|
|
|
<resource-dropdown
|
|
|
|
class="actions"
|
|
|
|
v-if="!inline"
|
2022-07-12 10:55:28 +02:00
|
|
|
@delete="emit('delete', resource.id as string)"
|
|
|
|
@move="emit('move', resource)"
|
|
|
|
@rename="emit('rename', resource)"
|
2020-02-18 08:57:00 +01:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</template>
|
2022-07-12 10:55:28 +02:00
|
|
|
<script lang="ts" setup>
|
|
|
|
import { useRouter } from "vue-router";
|
2022-09-20 16:53:26 +02:00
|
|
|
import Draggable, { ChangeEvent } from "vuedraggable";
|
2022-07-12 10:55:28 +02:00
|
|
|
import { IResource } from "@/types/resource";
|
|
|
|
import RouteName from "@/router/name";
|
|
|
|
import { IGroup, usernameWithDomain } from "@/types/actor";
|
2020-02-18 08:57:00 +01:00
|
|
|
import ResourceDropdown from "./ResourceDropdown.vue";
|
2022-07-12 10:55:28 +02:00
|
|
|
import { UPDATE_RESOURCE } from "@/graphql/resources";
|
2022-09-20 16:53:26 +02:00
|
|
|
import { inject, ref } from "vue";
|
2022-07-12 10:55:28 +02:00
|
|
|
import { formatDateTimeString } from "@/filters/datetime";
|
|
|
|
import { useMutation } from "@vue/apollo-composable";
|
|
|
|
import { resourcePathArray } from "@/components/Resource/utils";
|
|
|
|
import Folder from "vue-material-design-icons/Folder.vue";
|
2022-09-20 16:53:26 +02:00
|
|
|
import { Snackbar } from "@/plugins/snackbar";
|
2022-07-12 10:55:28 +02:00
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
defineProps<{
|
|
|
|
resource: IResource;
|
|
|
|
group: IGroup;
|
|
|
|
inline?: boolean;
|
|
|
|
}>(),
|
|
|
|
{ inline: false }
|
|
|
|
);
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
(e: "move", resource: IResource): void;
|
|
|
|
(e: "rename", resource: IResource): void;
|
|
|
|
(e: "delete", resourceID: string): void;
|
|
|
|
}>();
|
|
|
|
|
|
|
|
const list = ref([]);
|
|
|
|
|
|
|
|
const groupObject: Record<string, unknown> = {
|
|
|
|
name: `folder-${props.resource?.title}`,
|
|
|
|
pull: false,
|
|
|
|
put: ["resources"],
|
|
|
|
};
|
|
|
|
|
|
|
|
const onChange = async (evt: ChangeEvent<IResource>) => {
|
|
|
|
if (evt.added && evt.added.element) {
|
2022-09-20 16:53:26 +02:00
|
|
|
// const movedResource = evt.added.element as IResource;
|
2022-07-12 10:55:28 +02:00
|
|
|
moveResource({
|
|
|
|
id: props.resource.id,
|
|
|
|
path: `${props.resource.path}/${props.resource.title}`,
|
|
|
|
parentId: props.resource.id,
|
|
|
|
});
|
2020-02-18 08:57:00 +01:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
return undefined;
|
|
|
|
};
|
|
|
|
|
|
|
|
const {
|
|
|
|
mutate: moveResource,
|
|
|
|
onDone: onMovedResource,
|
|
|
|
onError: onMovedResourceError,
|
|
|
|
} = useMutation<{ updateResource: IResource }>(UPDATE_RESOURCE);
|
|
|
|
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
onMovedResource(({ data }) => {
|
|
|
|
if (data?.updateResource && props.resource.path) {
|
|
|
|
return router.push({
|
|
|
|
name: RouteName.RESOURCE_FOLDER,
|
|
|
|
params: {
|
2022-09-20 16:53:26 +02:00
|
|
|
path: resourcePathArray(props.resource),
|
2022-07-12 10:55:28 +02:00
|
|
|
preferredUsername: props.group.preferredUsername,
|
|
|
|
},
|
|
|
|
});
|
2020-02-18 08:57:00 +01:00
|
|
|
}
|
2022-07-12 10:55:28 +02:00
|
|
|
});
|
2022-09-20 16:53:26 +02:00
|
|
|
const snackbar = inject<Snackbar>("snackbar");
|
2022-07-12 10:55:28 +02:00
|
|
|
|
|
|
|
onMovedResourceError((e) => {
|
2022-09-20 16:53:26 +02:00
|
|
|
snackbar?.open({
|
|
|
|
message: e.message,
|
|
|
|
variant: "danger",
|
|
|
|
position: "bottom",
|
|
|
|
});
|
2022-07-12 10:55:28 +02:00
|
|
|
return undefined;
|
|
|
|
});
|
2020-02-18 08:57:00 +01:00
|
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.resource-wrapper {
|
|
|
|
display: flex;
|
|
|
|
flex: 1;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
.actions {
|
|
|
|
flex: 0;
|
|
|
|
display: block;
|
|
|
|
margin: auto 1rem auto 2rem;
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.dropzone {
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
z-index: 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
a {
|
|
|
|
display: flex;
|
|
|
|
font-size: 14px;
|
2022-07-12 10:55:28 +02:00
|
|
|
// color: #444b5d;
|
2020-02-18 08:57:00 +01:00
|
|
|
text-decoration: none;
|
|
|
|
overflow: hidden;
|
|
|
|
flex: 1;
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
.preview {
|
2020-07-09 17:24:28 +02:00
|
|
|
flex: 0 0 50px;
|
2020-02-18 08:57:00 +01:00
|
|
|
position: relative;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.body {
|
2021-06-14 15:13:08 +02:00
|
|
|
padding: 8px;
|
2020-02-18 08:57:00 +01:00
|
|
|
flex: 1 1 auto;
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
h3 {
|
|
|
|
white-space: nowrap;
|
|
|
|
display: block;
|
|
|
|
font-weight: 500;
|
|
|
|
margin-bottom: 5px;
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
text-decoration: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|