Skip to content

Commit

Permalink
implement dragging for available line
Browse files Browse the repository at this point in the history
  • Loading branch information
MarvinOehlerkingCap committed Apr 12, 2024
1 parent 8ff3c06 commit 98c76fd
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 235 deletions.
1 change: 1 addition & 0 deletions src/components/error-handling/ErrorHandler.composable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type BoardObjectType =
| "mediaBoard"
| "mediaLine"
| "mediaElement";
// TODO transations

export type ApiErrorHandler = (
error?: ApiResponseError | ApiValidationError
Expand Down
32 changes: 24 additions & 8 deletions src/modules/feature/media-shelf/MediaBoard.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="d-flex flex-column flex-shrink-1">
<div>
<MediaBoardAvailableLine />
<MediaBoardAvailableLine @create:element="onCreateElement" />
<Sortable
:list="board.lines"
item-key="id"
Expand Down Expand Up @@ -33,6 +33,7 @@
@update:line-title="onUpdateLineTitle(element.id, $event)"
@update:element-position="onUpdateElementPosition"
@delete:line="onDeleteLine"
@delete:element="onDeleteElement"
/>
</template>
</Sortable>
Expand All @@ -42,31 +43,38 @@
</template>

<script setup lang="ts">
// FIXME sortablejs-vue3 has a bug where the DOM is wrong when you modify the data array
import { MediaBoardResponse } from "@/serverApi/v3";
import { DeviceMediaQuery } from "@/types/enum/device-media-query.enum";
import { extractDataAttribute } from "@util-board";
import { useMediaQuery } from "@vueuse/core";
import { SortableEvent } from "sortablejs";
import { Sortable } from "sortablejs-vue3";
import { PropType } from "vue";
import { useSharedMediaBoardState } from "./data/mediaBoardState.composable";
import { ElementMove, IMediaBoard, LineMove } from "./data/types";
import { ElementCreate, ElementMove, LineMove } from "./data/types";
import { useSharedEditMode } from "./editMode.composable";
import MediaBoardAvailableLine from "./MediaBoardAvailableLine.vue";
import MediaBoardLine from "./MediaBoardLine.vue";
import MediaBoardLineGhost from "./MediaBoardLineGhost.vue";
defineProps({
board: {
type: Object as PropType<IMediaBoard>,
type: Object as PropType<MediaBoardResponse>,
required: true,
},
});
const isMobile = useMediaQuery(DeviceMediaQuery.Mobile);
const { updateLineTitle, createLine, moveLine, moveElement, deleteLine } =
useSharedMediaBoardState();
const {
updateLineTitle,
createLine,
moveLine,
moveElement,
deleteLine,
deleteElement,
createElement,
} = useSharedMediaBoardState();
const { isInEditMode } = useSharedEditMode();
Expand All @@ -78,10 +86,18 @@ const onCreateLine = async () => {
await createLine();
};
const onCreateElement = async (createOptions: ElementCreate) => {
await createElement(createOptions);
};
const onDeleteLine = (lineId: string) => {
deleteLine(lineId);
};
const onDeleteElement = (elementId: string) => {
deleteElement(elementId);
};
const onLineDragEnd = async (event: SortableEvent) => {
const { newIndex, oldIndex, item } = event;
Expand All @@ -92,13 +108,13 @@ const onLineDragEnd = async (event: SortableEvent) => {
newIndex !== undefined &&
oldIndex !== undefined
) {
const columnMove: LineMove = {
const lineMove: LineMove = {
newLineIndex: newIndex,
oldLineIndex: oldIndex,
lineId,
};
await moveLine(columnMove);
await moveLine(lineMove);
}
};
Expand Down
41 changes: 24 additions & 17 deletions src/modules/feature/media-shelf/MediaBoardAvailableLine.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div
class="line line-drag-handle mx-n4 px-4 py-2 ga-2 d-flex flex-column flex-shrink-1 rounded"
:data-line-id="availableMediaLineId"
>
<div class="line-header mb-4 rounded">
<div class="d-flex align-center py-2 px-2">
Expand All @@ -18,7 +19,7 @@
>
<VExpansionPanelText class="no-inner-padding">
<Sortable
:list="[]"
:list="availableMedia"
item-key="id"
tag="div"
:options="{
Expand All @@ -34,6 +35,7 @@
scroll: true,
forceFallback: true,
bubbleScroll: true,
sort: false,
}"
class="d-flex flex-grid flex-shrink-1 pa-2 ga-4 flex-1-1 scrollable-line"
@end="onElementDragEnd"
Expand All @@ -59,7 +61,8 @@ import { useMediaQuery } from "@vueuse/core";
import { SortableEvent } from "sortablejs";
import { Sortable } from "sortablejs-vue3";
import { Ref } from "vue";
import { ElementCreate } from "./data/types";
import { useSharedMediaBoardState } from "./data/mediaBoardState.composable";
import { availableMediaLineId, ElementCreate } from "./data/types";
import MediaBoardElement from "./MediaBoardElement.vue";
import { useCollapsableState } from "./utils/collapsable.composable";
Expand All @@ -71,29 +74,33 @@ const isMobile: Ref<boolean> = useMediaQuery(DeviceMediaQuery.Mobile);
const { openItems } = useCollapsableState("availableLinePanel");
const { availableMedia } = useSharedMediaBoardState();
const onElementDragEnd = async (event: SortableEvent) => {
const { newIndex, oldIndex, to, item } = event;
const { newIndex, oldIndex, to, from, item } = event;
const fromLineId: string | undefined = extractDataAttribute(from, "lineId");
const toLineId: string | undefined = extractDataAttribute(to, "lineId");
const elementId: string | undefined = extractDataAttribute(item, "elementId");
if (toLineId !== undefined) {
item?.parentNode?.removeChild(item);
}
if (
newIndex !== undefined &&
oldIndex !== undefined &&
elementId !== undefined
fromLineId === toLineId ||
newIndex === undefined ||
oldIndex === undefined ||
elementId === undefined
) {
const elementCreate: ElementCreate = {
toLineId,
oldElementIndex: oldIndex,
newElementIndex: newIndex,
};
emit("create:element", elementCreate);
return;
}
item?.parentNode?.removeChild(item);
const elementCreate: ElementCreate = {
toLineId,
oldElementIndex: oldIndex,
newElementIndex: newIndex,
};
emit("create:element", elementCreate);
};
</script>

Expand Down
6 changes: 3 additions & 3 deletions src/modules/feature/media-shelf/MediaBoardElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@
{{ element.title }}
</template>
<template #description>
<LineClamp :truncate="false" class="description">
<div class="description">
{{ element.description }}
</LineClamp>
</div>
</template>
</ContentElementBar>
</VCard>
Expand All @@ -47,7 +47,6 @@

<script setup lang="ts">
import ContentElementBar from "@ui-board/content-element/ContentElementBar.vue";
import LineClamp from "@ui-board/LineClamp.vue";
import { useElementHover } from "@vueuse/core";
import { PropType, ref } from "vue";
import { IMediaBoardElement } from "./data/types";
Expand Down Expand Up @@ -80,5 +79,6 @@ $card-width: 344px;
.description {
height: calc(3em * var(--line-height-md));
overflow: hidden;
}
</style>
34 changes: 18 additions & 16 deletions src/modules/feature/media-shelf/MediaBoardLine.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
:title-placeholder="titlePlaceholder"
:line-id="line.id"
:can-edit="true"
@update:title="onUpdateTitle"
@update:title="$emit('update:line-title', $event)"
>
<template #menu>
<MediaBoardLineMenu
Expand Down Expand Up @@ -60,22 +60,23 @@
</template>

<script setup lang="ts">
import { MediaLineResponse } from "@/serverApi/v3";
import { DeviceMediaQuery } from "@/types/enum/device-media-query.enum";
import { extractDataAttribute } from "@util-board";
import { useMediaQuery } from "@vueuse/core";
import { SortableEvent } from "sortablejs";
import { Sortable } from "sortablejs-vue3";
import { computed, ComputedRef, PropType, Ref, toRef } from "vue";
import { computed, ComputedRef, PropType, Ref } from "vue";
import { useI18n } from "vue-i18n";
import BoardLineHeader from "./BoardLineHeader.vue";
import { ElementMove, IMediaBoardLine } from "./data/types";
import { availableMediaLineId, ElementMove } from "./data/types";
import MediaBoardElement from "./MediaBoardElement.vue";
import MediaBoardLineMenu from "./MediaBoardLineMenu.vue";
import { useCollapsableState } from "./utils/collapsable.composable";
const props = defineProps({
line: {
type: Object as PropType<IMediaBoardLine>,
type: Object as PropType<MediaLineResponse>,
required: true,
},
index: {
Expand All @@ -88,6 +89,7 @@ const emit = defineEmits<{
(e: "update:line-title", newTitle: string): void;
(e: "update:element-position", value: ElementMove): void;
(e: "delete:line", lineId: string): void;
(e: "delete:element", elementId: string): void;
}>();
const { t } = useI18n();
Expand All @@ -100,29 +102,29 @@ const titlePlaceholder: ComputedRef<string> = computed(
() => `${t("feature.media-shelf.line.title").toString()} ${props.index + 1}`
);
const line: Ref<IMediaBoardLine> = toRef(props, "line");
const onUpdateTitle = (newTitle: string) => {
emit("update:line-title", newTitle);
};
const onElementDragEnd = async (event: SortableEvent) => {
const { newIndex, oldIndex, to, from, item } = event;
const fromLineId: string | undefined = extractDataAttribute(from, "lineId");
const toLineId: string | undefined = extractDataAttribute(to, "lineId");
const elementId: string | undefined = extractDataAttribute(item, "elementId");
if (
newIndex === undefined ||
oldIndex === undefined ||
fromLineId === undefined ||
elementId === undefined
) {
return;
}
if (toLineId !== fromLineId) {
item?.parentNode?.removeChild(item);
}
if (
newIndex !== undefined &&
oldIndex !== undefined &&
fromLineId !== undefined &&
elementId !== undefined
) {
if (toLineId === availableMediaLineId) {
emit("delete:element", elementId);
} else {
const elementMove: ElementMove = {
elementId,
oldElementIndex: oldIndex,
Expand Down
28 changes: 24 additions & 4 deletions src/modules/feature/media-shelf/data/mediaBoardApi.composable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "@/serverApi/v3";
import { $axios } from "@/utils/api";
import { AxiosResponse } from "axios";
import { IMediaBoardElement } from "./types";

export const useMediaBoardApi = () => {
const mediaBoardApi: MediaBoardApiInterface = MediaBoardApiFactory(
Expand Down Expand Up @@ -39,12 +40,23 @@ export const useMediaBoardApi = () => {
const getAvailableMedia = async (
// eslint-disable-next-line @typescript-eslint/no-unused-vars
boardId: string
): Promise<MediaLineResponse> => {
): Promise<IMediaBoardElement[]> => {
/* TODO const response: AxiosResponse<MediaLineResponse> =
await mediaBoardApi.mediaBoardControllerGetAvailableMedia(boardId);
return response.data; */
return {} as MediaLineResponse;
return [
{
title: "testTool",
id: Date.now().toString(),
description:
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
},
{
title: "testTool2",
id: Date.now().toString(),
},
];
};

const createLine = async (boardId: string): Promise<MediaLineResponse> => {
Expand Down Expand Up @@ -78,10 +90,18 @@ export const useMediaBoardApi = () => {

const createElement = async (
// eslint-disable-next-line @typescript-eslint/no-unused-vars
lineId: string
lineId: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
position: number
): Promise<MediaExternalToolElementResponse> => {
// TODO await mediaLineApi.mediaElementControllerCreateElement(lineId);
return {} as MediaExternalToolElementResponse;
const id = Date.now().toString();

return {
title: "Created Element",
id: id,
description: id,
} as unknown as MediaExternalToolElementResponse;
};

const moveElement = async (
Expand Down
Loading

0 comments on commit 98c76fd

Please sign in to comment.