Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
29763c1
add course title to course breadcrumbs
odalys-dataport Jun 4, 2025
3f56e00
Merge branch 'main' of https://github.com/hpi-schul-cloud/nuxt-client…
odalys-dataport Sep 6, 2025
c77201b
add folderName to breadcrumbs in folder page
odalys-dataport Sep 6, 2025
2b5f4eb
correct breadcrumbs for room admin pages
odalys-dataport Sep 6, 2025
01fe080
add board title to breadcrumbs
odalys-dataport Sep 11, 2025
71bac58
page title with actual boardName
odalys-dataport Sep 11, 2025
66a517e
Merge branch 'main' of https://github.com/hpi-schul-cloud/nuxt-client…
odalys-dataport Sep 29, 2025
1921564
sort routes alphabetically by pathname
odalys-dataport Sep 29, 2025
b8a89c9
remove wrong admin breadcrumbs again from room admin pages
odalys-dataport Sep 29, 2025
28a8752
correct breadcrumbs on admin pages
odalys-dataport Sep 30, 2025
47e3e67
fix unit tests
odalys-dataport Sep 30, 2025
794eab0
fix unit tests
odalys-dataport Sep 30, 2025
a483617
refactor BoardPageInformation composable
odalys-dataport Oct 1, 2025
b2ccb8e
simplify folderName return
odalys-dataport Oct 1, 2025
d413bfa
Merge branch 'main' of https://github.com/hpi-schul-cloud/nuxt-client…
odalys-dataport Oct 1, 2025
431de31
fix static board title
odalys-dataport Oct 1, 2025
deda6aa
remove logger
odalys-dataport Oct 1, 2025
a2417fb
adjust pageTitle format
odalys-dataport Oct 1, 2025
86444c9
refactor composable computed properties
odalys-dataport Oct 2, 2025
5abcfeb
Merge branch 'main' of https://github.com/hpi-schul-cloud/nuxt-client…
odalys-dataport Oct 2, 2025
7e912f4
solve merge conflicts after eslint config changes
odalys-dataport Oct 6, 2025
ddee535
move pageTitle into Folder.state
odalys-dataport Oct 6, 2025
098ab83
add fallback for page title parent
odalys-dataport Oct 6, 2025
788b03a
correct pageTitle order on room members page
odalys-dataport Oct 6, 2025
d5f3fa6
Merge branch 'BC-9604-consistent-breadcrumbs' of https://github.com/h…
odalys-dataport Oct 8, 2025
cd16cf6
Merge branch 'main' into BC-9604-consistent-breadcrumbs
odalys-dataport Oct 10, 2025
6746b9b
Merge branch 'main' into BC-9604-consistent-breadcrumbs
odalys-dataport Oct 13, 2025
c9d98cd
simplify pageTitle.ts
odalys-dataport Oct 13, 2025
95c6054
adjust boardPageInformation composable tests
odalys-dataport Oct 13, 2025
c0ff5f9
replace pageTitle mock function
odalys-dataport Oct 13, 2025
fe958a3
fix unit tests
odalys-dataport Oct 14, 2025
fbfb7d4
add tests for new pageTitle function
odalys-dataport Oct 15, 2025
21c18d2
Make folder state a shared composable
dyedwiper Oct 17, 2025
045d533
Remove mock of buildPageTitle where not needed
dyedwiper Oct 17, 2025
5f09dcf
Remove other buildPageTitle mocks by setting up pinia
dyedwiper Oct 17, 2025
c1a2058
Move pinia setup to beforeAll
dyedwiper Oct 17, 2025
21092d0
Adjust page titles on school admin pages
dyedwiper Oct 17, 2025
2d429c4
Adjust descriptions for pageTitle tests
dyedwiper Oct 17, 2025
ee016d2
Revert "Adjust page titles on school admin pages"
dyedwiper Oct 17, 2025
0a292a8
Merge branch 'main' into BC-9604-consistent-breadcrumbs
dyedwiper Oct 17, 2025
14db379
Merge branch 'main' into BC-9604-consistent-breadcrumbs
dyedwiper Oct 17, 2025
58f503d
Fix test of folder page
dyedwiper Oct 17, 2025
46b4a9d
Fix throwApplicationError in folder state
dyedwiper Oct 17, 2025
f9b4b5b
Fix breadcrumb test in folder state
dyedwiper Oct 17, 2025
9ab5ebd
Refactor setting of pageTitle for folder
dyedwiper Oct 17, 2025
272c8fd
Fix folder test
dyedwiper Oct 17, 2025
43bd806
updated unit tests
luejoh Oct 20, 2025
f3b9f06
Merge branch 'main' into BC-9604-consistent-breadcrumbs
odalys-dataport Oct 20, 2025
dc6c2a5
add missing page title parents
odalys-dataport Oct 20, 2025
d34b465
Merge branch 'BC-9604-consistent-breadcrumbs' of https://github.com/h…
odalys-dataport Oct 20, 2025
efeccc4
use else if
odalys-dataport Oct 22, 2025
78aba85
solve merge conflict in routes
odalys-dataport Oct 22, 2025
58b337f
Merge branch 'main' into BC-9604-consistent-breadcrumbs
odalys-dataport Oct 23, 2025
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
16 changes: 0 additions & 16 deletions src/components/administration/ProvisioningOptionsPage.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,22 +93,6 @@ describe("ProvisioningOptionsPage", () => {
vi.clearAllMocks();
});

describe("breadcrumbs", () => {
it("should render static breadcrumbs", () => {
const { wrapper } = getWrapper();

const breadcrumbs = wrapper.findAll(".breadcrumbs-item");

expect(breadcrumbs[0].text()).toEqual("pages.administration.index.title");
expect(breadcrumbs[1].text()).toEqual(
"pages.administration.school.index.title"
);
expect(breadcrumbs[2].text()).toEqual(
"components.administration.provisioningOptions.page.title"
);
});
});

describe("title", () => {
it("should render static title", () => {
const { wrapper } = getWrapper();
Expand Down
31 changes: 14 additions & 17 deletions src/components/administration/ProvisioningOptionsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@

<script setup lang="ts">
import VCustomDialog from "@/components/organisms/vCustomDialog.vue";
import { Breadcrumb } from "@/components/templates/default-wireframe.types";
import DefaultWireframe from "@/components/templates/DefaultWireframe.vue";
import { injectStrict, THEME_KEY } from "@/utils/inject";
import { buildPageTitle } from "@/utils/pageTitle";
Expand All @@ -177,6 +176,7 @@ import { computed, ComputedRef, onMounted, Ref, ref } from "vue";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
import { useEnvConfig } from "@data-env";
import { Breadcrumb } from "../templates/default-wireframe.types";

type Props = {
systemId: string;
Expand Down Expand Up @@ -207,21 +207,18 @@ const pageTitle = buildPageTitle(
);
useTitle(pageTitle);

const schoolSettingsPage: Breadcrumb = {
title: t("pages.administration.school.index.title"),
to: "/administration/school-settings",
};
const breadcrumbs: Breadcrumb[] = [
{
title: t("pages.administration.index.title"),
disabled: true,
},
schoolSettingsPage,
{
title: t("components.administration.provisioningOptions.page.title"),
disabled: true,
},
];
const breadcrumbs: ComputedRef<Breadcrumb[]> = computed(() => {
return [
{
title: t("pages.administration.school.index.title"),
to: "/administration/school-settings",
},
{
title: t("components.administration.provisioningOptions.page.title"),
disabled: true,
},
];
});

const provisioningOptions: ComputedRef<ProvisioningOptions> = computed(
() => provisioningOptionsData.value
Expand Down Expand Up @@ -305,7 +302,7 @@ const onCancel = async () => {

const redirectToAdminPage = async () => {
await router.push({
path: schoolSettingsPage.to,
path: "/administration/school-settings",
query: { openPanels: "authentication" },
});
};
Expand Down
32 changes: 24 additions & 8 deletions src/modules/data/board/BoardPageInformation.composable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const useBoardPageInformation = () => {
const { getContextInfo } = useBoardApi();

const boardContext = ref<Awaited<ReturnType<typeof getContextInfo>>>();

const boardTitle = ref<string>();
const roomId = computed(() => boardContext.value?.id);
const contextType = computed(() => boardContext.value?.type);

Expand All @@ -22,14 +22,16 @@ const useBoardPageInformation = () => {
const type = unref(boardContext)?.type;

if (type === BoardContextType.Course) {
return buildPageTitle(
`${t("pages.room.boardCard.label.courseBoard")}${roomNameForPageTitle}`
);
const title =
boardTitle.value ?? t("pages.room.boardCard.label.courseBoard");

return buildPageTitle(`${title}${roomNameForPageTitle}`);
}
if (type === BoardContextType.Room) {
return buildPageTitle(
`${t("pages.roomDetails.board.defaultName")}${roomNameForPageTitle}`
);
const title =
boardTitle.value ?? t("pages.roomDetails.board.defaultName");

return buildPageTitle(`${title}${roomNameForPageTitle}`);
}
return "";
});
Expand All @@ -55,6 +57,11 @@ const useBoardPageInformation = () => {
to: `/rooms/${id}`,
disabled: false,
},
{
title:
boardTitle.value ?? t("pages.room.boardCard.label.courseBoard"),
disabled: true,
},
];
}
if (type === BoardContextType.Room) {
Expand All @@ -69,17 +76,26 @@ const useBoardPageInformation = () => {
to: `/rooms/${id}`,
disabled: false,
},
{
title: boardTitle.value ?? t("pages.roomDetails.board.defaultName"),
disabled: true,
},
];
}
return [];
});

const createPageInformation = async (id: string): Promise<void> => {
const createPageInformation = async (
id: string,
title?: string
): Promise<void> => {
boardContext.value = await getContextInfo(id);
boardTitle.value = title ?? "";
};

const resetPageInformation = (): void => {
boardContext.value = undefined;
boardTitle.value = "";
};

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe("BoardPageInformation.composable", () => {

await createPageInformation(fakeId);

expect(breadcrumbs.value).toHaveLength(2);
expect(breadcrumbs.value).toHaveLength(3);
});

it("should set page title", async () => {
Expand Down Expand Up @@ -139,7 +139,7 @@ describe("BoardPageInformation.composable", () => {

await createPageInformation(fakeId);

expect(breadcrumbs.value).toHaveLength(2);
expect(breadcrumbs.value).toHaveLength(3);
});

it("should set page title", async () => {
Expand Down
126 changes: 64 additions & 62 deletions src/modules/data/folder/Folder.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,12 @@ export const useFolderState = () => {
const fileFolderElement = ref<FileFolderElement | undefined>(undefined);
const parentNodeInfos = ref<ParentNodeInfo[]>([]);

const fetchFileFolderElement = async (fileFolderElementId: string) => {
try {
const reponse =
await boardElementApi.elementControllerGetElementWithParentHierarchy(
fileFolderElementId
);

fileFolderElement.value = castToFileFolderElement(reponse.data.element);
parentNodeInfos.value = reponse.data.parentHierarchy;
} catch (error) {
throwApplicationError(error);
}
};
const parent = computed(() => {
const indexOfDirectParent = parentNodeInfos.value.length - 1;
const parent = parentNodeInfos.value[indexOfDirectParent];

const renameFolder = async (
title: string,
fileFolderElementId: string
): Promise<void> => {
try {
await boardElementApi.elementControllerUpdateElement(
fileFolderElementId,
{ data: { content: { title }, type: ContentElementType.FileFolder } }
);
await fetchFileFolderElement(fileFolderElementId);
} catch (error) {
throwApplicationError(error);
}
};
return parent;
});

const folderName = computed(() => {
const title = fileFolderElement.value?.content.title;
Expand All @@ -70,9 +48,40 @@ export const useFolderState = () => {
});
});

breadcrumbItems.push({ title: folderName.value, disabled: true });

return breadcrumbItems;
});

const fetchFileFolderElement = async (fileFolderElementId: string) => {
try {
const response =
await boardElementApi.elementControllerGetElementWithParentHierarchy(
fileFolderElementId
);

fileFolderElement.value = castToFileFolderElement(response.data.element);
parentNodeInfos.value = response.data.parentHierarchy;
} catch (error) {
throwApplicationError(error);
}
};

const renameFolder = async (
title: string,
fileFolderElementId: string
): Promise<void> => {
try {
await boardElementApi.elementControllerUpdateElement(
fileFolderElementId,
{ data: { content: { title }, type: ContentElementType.FileFolder } }
);
await fetchFileFolderElement(fileFolderElementId);
} catch (error) {
throwApplicationError(error);
}
};

const buildRootBreadCrumbItem = (parentNodeInfos: Ref<ParentNodeInfo[]>) => {
if (!parentNodeInfos.value[0]) return;

Expand All @@ -88,49 +97,42 @@ export const useFolderState = () => {
}
};

const parent = computed(() => {
const indexOfDirectParent = parentNodeInfos.value.length - 1;
const parent = parentNodeInfos.value[indexOfDirectParent];
const castToFileFolderElement = (
element: AnyContentElement
): FileFolderElement => {
if (element.type === ContentElementType.FileFolder) {
return element as FileFolderElement;
} else {
throw createApplicationError(404);
}
};

return parent;
});
const throwApplicationError = (error: unknown): never => {
const responseError = mapAxiosErrorToResponseError(error);

throw createApplicationError(responseError.code);
};

const mapNodeTypeToPathType = (nodeType: string): string => {
switch (nodeType) {
case ParentNodeType.Course:
return "courses";
case ParentNodeType.Room:
return "rooms";
case ParentNodeType.Board:
return "boards";
default:
throw new Error(`Unknown node type: ${nodeType}`);
}
};

return {
breadcrumbs,
fileFolderElement,
folderName,
fetchFileFolderElement,
parent,
fetchFileFolderElement,
mapNodeTypeToPathType,
renameFolder,
};
};

const castToFileFolderElement = (
element: AnyContentElement
): FileFolderElement => {
if (element.type === ContentElementType.FileFolder) {
return element as FileFolderElement;
} else {
throw createApplicationError(404);
}
};

const throwApplicationError = (error: unknown): never => {
const responseError = mapAxiosErrorToResponseError(error);

throw createApplicationError(responseError.code);
};

const mapNodeTypeToPathType = (nodeType: string): string => {
switch (nodeType) {
case ParentNodeType.Course:
return "courses";
case ParentNodeType.Room:
return "rooms";
case ParentNodeType.Board:
return "boards";
default:
throw new Error(`Unknown node type: ${nodeType}`);
}
};
8 changes: 8 additions & 0 deletions src/modules/data/folder/Folder.state.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ describe("useFolderState", () => {
title: "Column Board",
to: "/boards/column-board-id",
},
{
disabled: true,
title: "title 3",
},
]);
});
});
Expand Down Expand Up @@ -183,6 +187,10 @@ describe("useFolderState", () => {
title: "Room",
to: "/rooms/room-id",
},
{
disabled: true,
title: "title 4",
},
]);
});
});
Expand Down
Loading
Loading