Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-8396 - Adjust BoardTile design #3464

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
20905f8
extract RoomMenu component
odalys-dataport Nov 26, 2024
b2d33b6
separate RoomDetailsPage from switch logic
odalys-dataport Nov 26, 2024
71594eb
adjust room variable usage
odalys-dataport Nov 28, 2024
3b6ddb4
Merge branch 'main' into BC-8396-board-card-design
odalys-dataport Nov 28, 2024
afbfdef
remove RoomDetails component
odalys-dataport Nov 28, 2024
462537b
adjust boardtile design
odalys-dataport Nov 28, 2024
8c3ca7d
emit events in RoomMenu instead of linking directly
odalys-dataport Nov 29, 2024
94e64be
solve merge conflict in RoomDetailsPage
odalys-dataport Nov 29, 2024
b10b3da
keep loading state in RoomDetailsSwitchPage
odalys-dataport Nov 29, 2024
83b93f3
add sidebar highlight for room boards
odalys-dataport Nov 29, 2024
961286a
two columns for tablet sizes
odalys-dataport Nov 29, 2024
a8a0d05
fix board-tile-title data-testid index
odalys-dataport Nov 29, 2024
b7822a3
fix routing bug & rename route
odalys-dataport Dec 2, 2024
53680f1
add id regex to room routes
odalys-dataport Dec 2, 2024
c3098e7
correct router import
odalys-dataport Dec 2, 2024
768ac34
use card variants instead of classes
odalys-dataport Dec 2, 2024
0c78095
use bg-surface-light
odalys-dataport Dec 2, 2024
f47a645
fix RoomColor enum imports
odalys-dataport Dec 4, 2024
59c158d
Merge branch 'main' into BC-8396-board-card-design
odalys-dataport Dec 4, 2024
8f33964
Merge branch 'BC-8396-board-card-design' of https://github.com/hpi-sc…
odalys-dataport Dec 4, 2024
95f424f
adjust opacity
odalys-dataport Dec 4, 2024
accf780
use line clamp component
odalys-dataport Dec 4, 2024
0342763
use LineClamp on RoomTile
odalys-dataport Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/modules/feature/room/RoomMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<KebabMenu
class="mx-2"
:aria-label="$t('pages.roomDetails.ariaLabels.menu')"
data-testid="room-menu"
>
<VListItem
role="menuitem"
:to="`/rooms/${roomId}/edit`"
data-testid="room-action-edit"
:aria-label="$t('pages.roomDetails.ariaLabels.menu.action.edit')"
>
<template #prepend>
<VIcon :icon="mdiPencilOutline" />
</template>
<VListItemTitle>
{{ $t("common.actions.edit") }}
</VListItemTitle>
</VListItem>
<VListItem
role="menuitem"
:to="`/rooms/${roomId}/members`"
data-testid="room-action-manage-participants"
:aria-label="$t('pages.rooms.members.manage')"
>
<template #prepend>
<VIcon :icon="mdiAccountGroupOutline" />
</template>
<VListItemTitle>
{{ $t("pages.rooms.members.manage") }}
</VListItemTitle>
</VListItem>
<VListItem
role="menuitem"
data-testid="room-action-delete"
:aria-label="$t('pages.roomDetails.ariaLabels.menu.action.delete')"
@click="() => $emit('room:delete')"
>
<template #prepend>
<VIcon :icon="mdiTrashCanOutline" />
</template>
<VListItemTitle>
{{ $t("common.actions.delete") }}
</VListItemTitle>
</VListItem>
</KebabMenu>
</template>

<script setup lang="ts">
import { KebabMenu } from "@ui-kebab-menu";
import {
mdiPencilOutline,
mdiTrashCanOutline,
mdiAccountGroupOutline,
} from "@icons/material";

defineProps({
roomId: { type: String, required: true },
});

defineEmits(["room:delete"]);
</script>
3 changes: 2 additions & 1 deletion src/modules/feature/room/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import RoomGrid from "./RoomGrid.vue";
import RoomDetails from "./RoomDetails.vue";
import RoomForm from "./RoomForm.vue";
import RoomMenu from "./RoomMenu.vue";
import MembersTable from "./RoomMembers/MembersTable.vue";
import AddMembers from "./RoomMembers/AddMembers.vue";

export { RoomGrid, RoomDetails, RoomForm, MembersTable, AddMembers };
export { RoomGrid, RoomDetails, RoomForm, RoomMenu, MembersTable, AddMembers };
214 changes: 60 additions & 154 deletions src/modules/page/room/RoomDetails.page.vue
Original file line number Diff line number Diff line change
@@ -1,158 +1,98 @@
<template>
<div v-if="isLoading" />
<template v-else>
<template v-if="isRoom">
<DefaultWireframe
max-width="full"
:breadcrumbs="breadcrumbs"
:fabItems="fabItems"
@onFabItemClick="fabItemClickHandler"
>
<template #header v-if="room">
<div class="d-flex align-items-center">
<h1 class="text-h3 mb-4" data-testid="room-title">
{{ room.name }}
</h1>
<KebabMenu
class="mx-2"
:aria-label="$t('pages.roomDetails.ariaLabels.menu')"
data-testid="room-menu"
>
<VListItem
role="menuitem"
:to="`/rooms/${room.id}/edit`"
data-testid="room-action-edit"
:aria-label="
$t('pages.roomDetails.ariaLabels.menu.action.edit')
"
>
<template v-slot:prepend>
<VIcon :icon="mdiPencilOutline" />
</template>
<VListItemTitle>
{{ $t("common.actions.edit") }}
</VListItemTitle>
</VListItem>

<VListItem
role="menuitem"
:to="`/rooms/${room.id}/members`"
data-testid="room-action-manage-participants"
:aria-label="t('pages.rooms.members.manage')"
>
<template #prepend>
<VIcon :icon="mdiAccountGroupOutline" />
</template>
<VListItemTitle>
{{ t("pages.rooms.members.manage") }}
</VListItemTitle>
</VListItem>

<VListItem
role="menuitem"
data-testid="room-action-delete"
:aria-label="
$t('pages.roomDetails.ariaLabels.menu.action.delete')
"
@click="onDelete"
>
<template v-slot:prepend>
<VIcon :icon="mdiTrashCanOutline" />
</template>
<VListItemTitle>
{{ $t("common.actions.delete") }}
</VListItemTitle>
</VListItem>
</KebabMenu>
</div>
</template>
<RoomDetails v-if="room" :room="room" :room-boards="roomBoards" />
<ConfirmationDialog />
<SelectBoardLayoutDialog
v-if="boardLayoutsEnabled"
v-model="boardLayoutDialogIsOpen"
@select:multi-column="createBoard(BoardLayout.Columns)"
@select:single-column="createBoard(BoardLayout.List)"
/>
</DefaultWireframe>
<DefaultWireframe
v-else
max-width="full"
:breadcrumbs="breadcrumbs"
:fabItems="fabItems"
@onFabItemClick="fabItemClickHandler"
>
<template #header>
<div class="d-flex align-items-center">
<h1 class="text-h3 mb-4" data-testid="room-title">
{{ room.name }}
</h1>
<RoomMenu :room-id="room.id" @room:delete="onDelete" />
</div>
</template>
<template v-else>
<CourseRoomDetailsPage />
</template>
</template>
<RoomDetails :room="room" :room-boards="roomBoards" />
<ConfirmationDialog />
<SelectBoardLayoutDialog
v-if="boardLayoutsEnabled"
v-model="boardLayoutDialogIsOpen"
@select:multi-column="createBoard(BoardLayout.Columns)"
@select:single-column="createBoard(BoardLayout.List)"
/>
</DefaultWireframe>
</template>

<script setup lang="ts">
import { Breadcrumb } from "@/components/templates/default-wireframe.types";
import DefaultWireframe from "@/components/templates/DefaultWireframe.vue";
import CourseRoomDetailsPage from "@/pages/course-rooms/CourseRoomDetails.page.vue";
import router from "@/router";
import {
AUTH_MODULE_KEY,
ENV_CONFIG_MODULE_KEY,
injectStrict,
} from "@/utils/inject";
BoardLayout,
BoardApiFactory,
CreateBoardBodyParams,
BoardParentType,
ImportUserResponseRoleNamesEnum as Roles,
} from "@/serverApi/v3";
import { envConfigModule, authModule } from "@/store";
import { $axios } from "@/utils/api";
import { buildPageTitle } from "@/utils/pageTitle";
import { RoomVariant, useRoomDetailsStore, useRoomsState } from "@data-room";
import { RoomDetails } from "@feature-room";
import { useRoomDetailsStore, useRoomsState } from "@data-room";
import { RoomDetails, RoomMenu } from "@feature-room";
import {
mdiPencilOutline,
mdiTrashCanOutline,
mdiAccountGroupOutline,
mdiViewGridPlusOutline,
mdiViewDashboardOutline,
mdiPlus,
} from "@icons/material";
import {
ConfirmationDialog,
useDeleteConfirmationDialog,
} from "@ui-confirmation-dialog";
import { KebabMenu } from "@ui-kebab-menu";
import { SelectBoardLayoutDialog } from "@ui-room-details";
import { useTitle } from "@vueuse/core";
import { storeToRefs } from "pinia";
import { computed, ComputedRef, onUnmounted, ref, watch } from "vue";
import { computed, ComputedRef, ref } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute, useRouter } from "vue-router";
import {
mdiPlus,
mdiViewGridPlusOutline,
mdiViewDashboardOutline,
} from "@icons/material";
import {
BoardApiFactory,
BoardLayout,
BoardParentType,
CreateBoardBodyParams,
ImportUserResponseRoleNamesEnum as Roles,
} from "@/serverApi/v3";
import { $axios } from "@/utils/api";

const envConfigModule = injectStrict(ENV_CONFIG_MODULE_KEY);
const authModule = injectStrict(AUTH_MODULE_KEY);

const route = useRoute();
const router = useRouter();

const roomDetailsStore = useRoomDetailsStore();
const { isLoading, room, roomVariant, roomBoards } =
storeToRefs(roomDetailsStore);
const { deactivateRoom, fetchRoom, resetState } = roomDetailsStore;

const { t } = useI18n();
const { deleteRoom } = useRoomsState();
const { askDeleteConfirmation } = useDeleteConfirmationDialog();

const { isLoading, room, roomBoards } = storeToRefs(useRoomDetailsStore());

const pageTitle = computed(() =>
buildPageTitle(`${room.value?.name} - ${t("pages.roomDetails.title")}`)
);
useTitle(pageTitle);

const onDelete = async () => {
if (!room) return;

const shouldDelete = await askDeleteConfirmation(
room.value?.name,
"common.labels.room"
);

if (shouldDelete) {
await deleteRoom(room.value!.id);
router.push({
name: "rooms",
});
}
};

const breadcrumbs: ComputedRef<Breadcrumb[]> = computed(() => {
if (room.value != null) {
if (room != null) {
odalys-dataport marked this conversation as resolved.
Show resolved Hide resolved
return [
{
title: t("pages.rooms.title"),
to: "/rooms",
},
{
title: room.value.name,
title: room.value!.name,
odalys-dataport marked this conversation as resolved.
Show resolved Hide resolved
disabled: true,
},
];
Expand All @@ -167,13 +107,13 @@ const boardLayoutsEnabled = computed(
const boardLayoutDialogIsOpen = ref(false);

const createBoard = async (layout: BoardLayout) => {
if (!room.value) return;
if (!room) return;
odalys-dataport marked this conversation as resolved.
Show resolved Hide resolved

const boardApi = BoardApiFactory(undefined, "/v3", $axios);

const params: CreateBoardBodyParams = {
title: t("pages.roomDetails.board.defaultName"),
parentId: room.value.id,
parentId: room.value!.id,
parentType: BoardParentType.Room,
layout,
};
Expand Down Expand Up @@ -226,38 +166,4 @@ const fabItemClickHandler = (event: string) => {
createBoard(BoardLayout.Columns);
}
};

watch(
() => route.params.id,
async () => {
if (envConfigModule.getEnv["FEATURE_ROOMS_ENABLED"]) {
await fetchRoom(route.params.id as string);
} else {
deactivateRoom();
}
},
{ immediate: true }
);

const isRoom = computed(() => roomVariant.value === RoomVariant.ROOM);

const onDelete = async () => {
if (!room.value) return;

const shouldDelete = await askDeleteConfirmation(
room.value.name,
"common.labels.room"
);

if (shouldDelete) {
await deleteRoom(room.value.id);
router.push({
name: "rooms",
});
}
};

onUnmounted(() => {
resetState();
});
</script>
43 changes: 43 additions & 0 deletions src/modules/page/room/RoomDetailsSwitch.page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<div v-if="isLoading" />
<template v-else>
<RoomDetailsPage v-if="isRoom" />
<CourseRoomDetailsPage v-else />
</template>
</template>

<script setup lang="ts">
import CourseRoomDetailsPage from "@/pages/course-rooms/CourseRoomDetails.page.vue";
import { RoomDetailsPage } from "@page-room";
import { ENV_CONFIG_MODULE_KEY, injectStrict } from "@/utils/inject";
import { RoomVariant, useRoomDetailsStore } from "@data-room";
import { storeToRefs } from "pinia";
import { computed, onUnmounted, watch } from "vue";
import { useRoute } from "vue-router";

const envConfigModule = injectStrict(ENV_CONFIG_MODULE_KEY);

const route = useRoute();

const roomDetailsStore = useRoomDetailsStore();
const { isLoading, roomVariant } = storeToRefs(roomDetailsStore);
const { deactivateRoom, fetchRoom, resetState } = roomDetailsStore;

watch(
() => route.params.id,
async () => {
if (envConfigModule.getEnv["FEATURE_ROOMS_ENABLED"]) {
await fetchRoom(route.params.id as string);
} else {
deactivateRoom();
}
},
{ immediate: true }
);

const isRoom = computed(() => roomVariant.value === RoomVariant.ROOM);

onUnmounted(() => {
resetState();
});
</script>
Loading
Loading