From 1903f747641d6a9f2eb28e6d9cff3744438bd862 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Thu, 14 Nov 2024 13:31:12 +0200 Subject: [PATCH 01/11] [PageTitle] Center by default and add optional subtitle --- .../src/components/material/PageTitle/index.tsx | 14 ++++++++++---- services/frontend/src/pages/Feedback/index.tsx | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/services/frontend/src/components/material/PageTitle/index.tsx b/services/frontend/src/components/material/PageTitle/index.tsx index f15d78575..89f96fe2c 100644 --- a/services/frontend/src/components/material/PageTitle/index.tsx +++ b/services/frontend/src/components/material/PageTitle/index.tsx @@ -1,16 +1,22 @@ -import { Box, Typography } from '@mui/material' +import { Stack, Typography } from '@mui/material' /** * A title text displayed at the top of the page. * + * @param {string} [subtitle] - The subtitle of the page. * @param {string} title - The main title of the page. */ -export const PageTitle = ({ title }: { title: string }) => { +export const PageTitle = ({ subtitle, title }: { subtitle?: string; title: string }) => { return ( - + {title} - + {subtitle && ( + + {subtitle} + + )} + ) } diff --git a/services/frontend/src/pages/Feedback/index.tsx b/services/frontend/src/pages/Feedback/index.tsx index ac2276702..6fa979996 100644 --- a/services/frontend/src/pages/Feedback/index.tsx +++ b/services/frontend/src/pages/Feedback/index.tsx @@ -60,8 +60,8 @@ export const Feedback = () => { open={showError} severity="error" /> + - We are constantly improving Oodikone. Please share your thoughts using the form below, or contact us at
From f6d8ca87f1df2bb7786441aaaa7b7cd8b8ebc675 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 09:02:15 +0200 Subject: [PATCH 02/11] [Redux] Convert changelogApi to TypeScript --- services/frontend/src/redux/{changelog.js => changelog.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename services/frontend/src/redux/{changelog.js => changelog.ts} (100%) diff --git a/services/frontend/src/redux/changelog.js b/services/frontend/src/redux/changelog.ts similarity index 100% rename from services/frontend/src/redux/changelog.js rename to services/frontend/src/redux/changelog.ts From 779c1a96277a37af5d77ae589d51cf697fba7ee8 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 09:40:44 +0200 Subject: [PATCH 03/11] [Changelog] Extract ChangelogData and type changelogApi --- services/frontend/src/redux/changelog.ts | 3 ++- services/shared/types/changelog.ts | 5 +++++ services/shared/types/index.ts | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 services/shared/types/changelog.ts diff --git a/services/frontend/src/redux/changelog.ts b/services/frontend/src/redux/changelog.ts index bd726e5ce..26c86e4c3 100644 --- a/services/frontend/src/redux/changelog.ts +++ b/services/frontend/src/redux/changelog.ts @@ -1,8 +1,9 @@ import { RTKApi } from '@/apiConnection' +import { ChangelogData } from '@/shared/types' const changelogApi = RTKApi.injectEndpoints({ endpoints: builder => ({ - getChangelog: builder.query({ + getChangelog: builder.query({ query: () => 'changelog', }), }), diff --git a/services/shared/types/changelog.ts b/services/shared/types/changelog.ts new file mode 100644 index 000000000..336948570 --- /dev/null +++ b/services/shared/types/changelog.ts @@ -0,0 +1,5 @@ +export type ChangelogData = { + description: string + time: Date + title: string +} diff --git a/services/shared/types/index.ts b/services/shared/types/index.ts index 32b3dd8a2..23679aadf 100644 --- a/services/shared/types/index.ts +++ b/services/shared/types/index.ts @@ -1 +1,2 @@ +export type { ChangelogData } from './changelog' export type { Name } from './name' From d37228e68e30cfc601b770d7f26b34ffa6245672 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 09:54:15 +0200 Subject: [PATCH 04/11] [Changelog] Rename ChangelogData to Release --- services/frontend/src/redux/changelog.ts | 4 ++-- services/shared/types/index.ts | 2 +- services/shared/types/{changelog.ts => release.ts} | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename services/shared/types/{changelog.ts => release.ts} (63%) diff --git a/services/frontend/src/redux/changelog.ts b/services/frontend/src/redux/changelog.ts index 26c86e4c3..c2f7802e4 100644 --- a/services/frontend/src/redux/changelog.ts +++ b/services/frontend/src/redux/changelog.ts @@ -1,9 +1,9 @@ import { RTKApi } from '@/apiConnection' -import { ChangelogData } from '@/shared/types' +import { Release } from '@/shared/types' const changelogApi = RTKApi.injectEndpoints({ endpoints: builder => ({ - getChangelog: builder.query({ + getChangelog: builder.query({ query: () => 'changelog', }), }), diff --git a/services/shared/types/index.ts b/services/shared/types/index.ts index 23679aadf..80438c9cb 100644 --- a/services/shared/types/index.ts +++ b/services/shared/types/index.ts @@ -1,2 +1,2 @@ -export type { ChangelogData } from './changelog' export type { Name } from './name' +export type { Release } from './release' diff --git a/services/shared/types/changelog.ts b/services/shared/types/release.ts similarity index 63% rename from services/shared/types/changelog.ts rename to services/shared/types/release.ts index 336948570..992275c6b 100644 --- a/services/shared/types/changelog.ts +++ b/services/shared/types/release.ts @@ -1,4 +1,4 @@ -export type ChangelogData = { +export type Release = { description: string time: Date title: string From ff25524d32c56c10553dc68a0d7eee4d14bf0a24 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 15:51:07 +0200 Subject: [PATCH 05/11] [Frontpage] Rewrite with Material UI --- .../src/pages/FrontPage/FeatureItem.tsx | 14 +++ .../src/pages/FrontPage/ReleaseItem.tsx | 31 ++++++ .../src/pages/FrontPage/SectionTitle.tsx | 11 +++ .../frontend/src/pages/FrontPage/index.tsx | 94 +++++++++++++++++++ services/shared/types/release.ts | 2 +- 5 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 services/frontend/src/pages/FrontPage/FeatureItem.tsx create mode 100644 services/frontend/src/pages/FrontPage/ReleaseItem.tsx create mode 100644 services/frontend/src/pages/FrontPage/SectionTitle.tsx create mode 100644 services/frontend/src/pages/FrontPage/index.tsx diff --git a/services/frontend/src/pages/FrontPage/FeatureItem.tsx b/services/frontend/src/pages/FrontPage/FeatureItem.tsx new file mode 100644 index 000000000..758c0d70d --- /dev/null +++ b/services/frontend/src/pages/FrontPage/FeatureItem.tsx @@ -0,0 +1,14 @@ +import { Box, Typography } from '@mui/material' + +export const FeatureItem = ({ content, title }: { content: JSX.Element | string; title: string }) => { + return ( + + + {title} + + + {content} + + + ) +} diff --git a/services/frontend/src/pages/FrontPage/ReleaseItem.tsx b/services/frontend/src/pages/FrontPage/ReleaseItem.tsx new file mode 100644 index 000000000..d62c87a79 --- /dev/null +++ b/services/frontend/src/pages/FrontPage/ReleaseItem.tsx @@ -0,0 +1,31 @@ +import { Box, Typography } from '@mui/material' +import ReactMarkdown from 'react-markdown' + +import { DISPLAY_DATE_FORMAT } from '@/constants/date' +import { Release } from '@/shared/types' +import { reformatDate } from '@/util/timeAndDate' + +export const ReleaseItem = ({ isLoading, release }: { isLoading: boolean; release: Release }) => { + const getDescription = (description: string) => { + const lines = description.split('\n') + const internalIndex = lines.findIndex(line => line.toLowerCase().includes('internal')) + if (internalIndex === -1 || internalIndex === 0) { + return description + } + return lines.slice(0, internalIndex).join('\n') + } + + return ( + + + {isLoading ? 'Loading title...' : release.title} + + + {isLoading ? 'Loading date...' : reformatDate(release.time, DISPLAY_DATE_FORMAT)} + + + {isLoading ? 'Loading description...' : getDescription(release.description)} + + + ) +} diff --git a/services/frontend/src/pages/FrontPage/SectionTitle.tsx b/services/frontend/src/pages/FrontPage/SectionTitle.tsx new file mode 100644 index 000000000..4d35a92d5 --- /dev/null +++ b/services/frontend/src/pages/FrontPage/SectionTitle.tsx @@ -0,0 +1,11 @@ +import { Box, Typography } from '@mui/material' + +export const SectionTitle = ({ title }: { title: string }) => { + return ( + + + {title} + + + ) +} diff --git a/services/frontend/src/pages/FrontPage/index.tsx b/services/frontend/src/pages/FrontPage/index.tsx new file mode 100644 index 000000000..117d695a6 --- /dev/null +++ b/services/frontend/src/pages/FrontPage/index.tsx @@ -0,0 +1,94 @@ +import { Button, Container, Divider, List, ListItem, Stack } from '@mui/material' +import { useEffect, useState } from 'react' + +import { checkUserAccess, getFullStudyProgrammeRights, isDefaultServiceProvider } from '@/common' +import { useTitle } from '@/common/hooks' +import { PageTitle } from '@/components/material/PageTitle' +import { useGetAuthorizedUserQuery } from '@/redux/auth' +import { useGetChangelogQuery } from '@/redux/changelog' +import { Release } from '@/shared/types' +import { FeatureItem } from './FeatureItem' +import { ReleaseItem } from './ReleaseItem' +import { SectionTitle } from './SectionTitle' + +export const FrontPage = () => { + useTitle() + + const { data: releaseData, isLoading } = useGetChangelogQuery() + const { roles, programmeRights } = useGetAuthorizedUserQuery() + const fullStudyProgrammeRights = getFullStudyProgrammeRights(programmeRights) + const [visibleReleases, setVisibleReleases] = useState([]) + + const featureItems = [ + { + show: true, + title: 'University', + content: 'View tables and diagrams about study progress of different faculties', + }, + { + show: checkUserAccess(['admin', 'fullSisuAccess'], roles) || programmeRights.length > 0, + title: 'Programmes', + content: ( + + Class statistics: View details of a specific year of a study programme + Overview: View statistics of a programme across all years + + ), + }, + { + show: checkUserAccess(['courseStatistics', 'admin'], roles) || fullStudyProgrammeRights.length > 0, + title: 'Courses', + content: 'View statistics about course attempts, completions and grades', + }, + { + show: checkUserAccess(['studyGuidanceGroups', 'admin'], roles) || fullStudyProgrammeRights.length > 0, + title: 'Students', + content: 'View detailed information for a given student', + }, + { + show: isDefaultServiceProvider(), + title: 'Feedback', + content: ( +

+ For questions and suggestions, please use the{' '} + feedback form or shoot an email to{' '} + grp-toska@helsinki.fi. +

+ ), + }, + ] + + const filterInternalReleases = (release: Release) => !release.title.startsWith('Internal:') + + useEffect(() => { + if (!releaseData) { + return + } + setVisibleReleases([...releaseData.filter(filterInternalReleases).slice(0, 2)]) + }, [releaseData]) + + return ( + + + } gap={3}> + + + } gap={2}> + {featureItems.map( + item => item.show && + )} + + + + + } gap={2}> + {visibleReleases.map(release => ( + + ))} + + + + + + ) +} diff --git a/services/shared/types/release.ts b/services/shared/types/release.ts index 992275c6b..2e34a7e52 100644 --- a/services/shared/types/release.ts +++ b/services/shared/types/release.ts @@ -1,5 +1,5 @@ export type Release = { description: string - time: Date + time: string title: string } From b6a99dda83e29f6ec7c5e4e32baafaac1bb04879 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 15:53:35 +0200 Subject: [PATCH 06/11] [Backend] Update fake changelog data --- services/backend/src/routes/changelog.ts | 35 ++++++++++++++---------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/services/backend/src/routes/changelog.ts b/services/backend/src/routes/changelog.ts index a48ef1dda..01b268e8e 100644 --- a/services/backend/src/routes/changelog.ts +++ b/services/backend/src/routes/changelog.ts @@ -2,39 +2,44 @@ import axios from 'axios' import { Request, Response, Router } from 'express' import { isDev } from '../config' +import { Release } from '../shared/types' const router = Router() -type ChangeLogData = { - description: string - time: Date - title: string -} - -const changelog: { data?: ChangeLogData[] } = {} +const changelog: { data?: Release[] } = {} router.get('/', async (_req: Request, res: Response) => { if (changelog.data) { return res.status(200).send(changelog.data) } if (isDev) { - const fakeChangeLogData: ChangeLogData[] = [ + const fakeRelease: Release[] = [ + { + description: '**Feature 1**\n- Added a fancy new feature \n\n**Feature 2**\n- Fixed a bug\n- Fixed another bug', + title: 'Release 1', + time: new Date().toISOString(), + }, + { + description: "Let's not spam the GitHub API in development!", + title: 'Release 2', + time: new Date().toISOString(), + }, { - description: "### Fake release\nLet's not spam the GitHub API in development!", - title: 'Fake title for fake release', - time: new Date(), + description: 'This release should not be visible on the frontpage', + title: 'Release 3', + time: new Date().toISOString(), }, ] - return res.status(200).json(fakeChangeLogData) + return res.status(200).json(fakeRelease) } const response = await axios.get('https://api.github.com/repos/UniversityOfHelsinkiCS/oodikone/releases') - const newChangelogData = response.data.map((release: Record) => ({ + const releasesFromAPI: Release[] = response.data.map((release: Record) => ({ description: release.body, time: release.created_at, title: release.name, })) - changelog.data = newChangelogData - res.status(200).send(newChangelogData) + changelog.data = releasesFromAPI + res.status(200).json(releasesFromAPI) }) export default router From 39b77e43d7d76a6cb7a34224462790bd02e048c6 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 15:57:00 +0200 Subject: [PATCH 07/11] [Frontend] Update FrontPage route --- services/frontend/src/common/index.js | 5 ++++- services/frontend/src/components/Routes/index.jsx | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/services/frontend/src/common/index.js b/services/frontend/src/common/index.js index 2fc3782fa..916038d26 100644 --- a/services/frontend/src/common/index.js +++ b/services/frontend/src/common/index.js @@ -434,7 +434,10 @@ export const getEnrollmentTypeTextForExcel = (type, statutoryAbsence) => { } export const isDefaultServiceProvider = () => { - return serviceProvider && serviceProvider === 'toska' + if (!serviceProvider) { + return false + } + return serviceProvider === 'toska' } export const formatContent = content => content.replace(/\n +/g, '\n') diff --git a/services/frontend/src/components/Routes/index.jsx b/services/frontend/src/components/Routes/index.jsx index 328cc7a78..135d61626 100644 --- a/services/frontend/src/components/Routes/index.jsx +++ b/services/frontend/src/components/Routes/index.jsx @@ -10,7 +10,6 @@ import { CustomPopulation } from '@/components/CustomPopulation' import { EvaluationOverview } from '@/components/EvaluationOverview' import { UniversityViewPage } from '@/components/EvaluationOverview/UniversityView' import { FacultyStatistics } from '@/components/FacultyStatistics' -import { FrontPage } from '@/components/Frontpage' import { LanguageCenterView } from '@/components/LanguageCenterView' import { PopulationStatistics } from '@/components/PopulationStatistics' import { SegmentDimmer } from '@/components/SegmentDimmer' @@ -22,6 +21,7 @@ import { Updater } from '@/components/Updater' import { Users } from '@/components/Users' import { languageCenterViewEnabled } from '@/conf' import { Feedback } from '@/pages/Feedback' +import { FrontPage } from '@/pages/FrontPage' import { ProtectedRoute } from './ProtectedRoute' const routes = { From 04715e4503d89aa2943d9b429d0f429fa83e9796 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 16:48:28 +0200 Subject: [PATCH 08/11] [Changelog] Create a new page for changelog --- services/frontend/src/common/index.js | 11 ++++++ .../frontend/src/components/Routes/index.jsx | 3 ++ .../src/pages/Changelog/ReleaseCard.tsx | 21 ++++++++++++ .../frontend/src/pages/Changelog/index.tsx | 34 +++++++++++++++++++ .../src/pages/FrontPage/ReleaseItem.tsx | 10 +----- .../src/pages/FrontPage/SectionTitle.tsx | 2 +- .../frontend/src/pages/FrontPage/index.tsx | 27 ++++++++++----- 7 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 services/frontend/src/pages/Changelog/ReleaseCard.tsx create mode 100644 services/frontend/src/pages/Changelog/index.tsx diff --git a/services/frontend/src/common/index.js b/services/frontend/src/common/index.js index 916038d26..bf5f5b5bb 100644 --- a/services/frontend/src/common/index.js +++ b/services/frontend/src/common/index.js @@ -450,3 +450,14 @@ export const getCalendarYears = years => { return all.concat(Number(year.slice(0, 4))) }, []) } + +export const filterInternalReleases = release => !release.title.startsWith('Internal:') + +export const getDescription = description => { + const lines = description.split('\n') + const internalIndex = lines.findIndex(line => line.toLowerCase().includes('internal')) + if (internalIndex === -1 || internalIndex === 0) { + return description + } + return lines.slice(0, internalIndex).join('\n') +} diff --git a/services/frontend/src/components/Routes/index.jsx b/services/frontend/src/components/Routes/index.jsx index 135d61626..43ef3f5f1 100644 --- a/services/frontend/src/components/Routes/index.jsx +++ b/services/frontend/src/components/Routes/index.jsx @@ -20,6 +20,7 @@ import { Teachers } from '@/components/Teachers' import { Updater } from '@/components/Updater' import { Users } from '@/components/Users' import { languageCenterViewEnabled } from '@/conf' +import { Changelog } from '@/pages/Changelog' import { Feedback } from '@/pages/Feedback' import { FrontPage } from '@/pages/FrontPage' import { ProtectedRoute } from './ProtectedRoute' @@ -43,12 +44,14 @@ const routes = { closeToGraduation: '/close-to-graduation', populations: '/populations', studyProgramme: '/study-programme/:studyProgrammeId?', + changelog: '/changelog', } export const Routes = () => ( }> + {isDefaultServiceProvider() && } { + return ( + + + {isLoading ? 'Loading title...' : release.title} + + + {isLoading ? 'Loading date...' : `Released on ${reformatDate(release.time, DISPLAY_DATE_FORMAT)}`} + + {isLoading ? 'Loading description...' : getDescription(release.description)} + + ) +} diff --git a/services/frontend/src/pages/Changelog/index.tsx b/services/frontend/src/pages/Changelog/index.tsx new file mode 100644 index 000000000..e2de61f0c --- /dev/null +++ b/services/frontend/src/pages/Changelog/index.tsx @@ -0,0 +1,34 @@ +import { Container, Divider, Stack } from '@mui/material' +import { useEffect, useState } from 'react' + +import { filterInternalReleases } from '@/common' +import { useTitle } from '@/common/hooks' +import { PageTitle } from '@/components/material/PageTitle' +import { useGetChangelogQuery } from '@/redux/changelog' +import { Release } from '@/shared/types' +import { ReleaseCard } from './ReleaseCard' + +export const Changelog = () => { + useTitle('Changelog') + + const { data: releaseData, isLoading } = useGetChangelogQuery() + const [visibleReleases, setVisibleReleases] = useState([]) + + useEffect(() => { + if (!releaseData) { + return + } + setVisibleReleases([...releaseData.filter(filterInternalReleases).slice(0, 10)]) + }, [releaseData]) + + return ( + + + } gap={1}> + {visibleReleases.map(release => ( + + ))} + + + ) +} diff --git a/services/frontend/src/pages/FrontPage/ReleaseItem.tsx b/services/frontend/src/pages/FrontPage/ReleaseItem.tsx index d62c87a79..395aec0e0 100644 --- a/services/frontend/src/pages/FrontPage/ReleaseItem.tsx +++ b/services/frontend/src/pages/FrontPage/ReleaseItem.tsx @@ -1,20 +1,12 @@ import { Box, Typography } from '@mui/material' import ReactMarkdown from 'react-markdown' +import { getDescription } from '@/common' import { DISPLAY_DATE_FORMAT } from '@/constants/date' import { Release } from '@/shared/types' import { reformatDate } from '@/util/timeAndDate' export const ReleaseItem = ({ isLoading, release }: { isLoading: boolean; release: Release }) => { - const getDescription = (description: string) => { - const lines = description.split('\n') - const internalIndex = lines.findIndex(line => line.toLowerCase().includes('internal')) - if (internalIndex === -1 || internalIndex === 0) { - return description - } - return lines.slice(0, internalIndex).join('\n') - } - return ( diff --git a/services/frontend/src/pages/FrontPage/SectionTitle.tsx b/services/frontend/src/pages/FrontPage/SectionTitle.tsx index 4d35a92d5..6519d13b5 100644 --- a/services/frontend/src/pages/FrontPage/SectionTitle.tsx +++ b/services/frontend/src/pages/FrontPage/SectionTitle.tsx @@ -3,7 +3,7 @@ import { Box, Typography } from '@mui/material' export const SectionTitle = ({ title }: { title: string }) => { return ( - + {title} diff --git a/services/frontend/src/pages/FrontPage/index.tsx b/services/frontend/src/pages/FrontPage/index.tsx index 117d695a6..6373c359e 100644 --- a/services/frontend/src/pages/FrontPage/index.tsx +++ b/services/frontend/src/pages/FrontPage/index.tsx @@ -1,7 +1,13 @@ -import { Button, Container, Divider, List, ListItem, Stack } from '@mui/material' +import { Box, Button, Container, Divider, Stack } from '@mui/material' import { useEffect, useState } from 'react' +import { Link } from 'react-router-dom' -import { checkUserAccess, getFullStudyProgrammeRights, isDefaultServiceProvider } from '@/common' +import { + checkUserAccess, + filterInternalReleases, + getFullStudyProgrammeRights, + isDefaultServiceProvider, +} from '@/common' import { useTitle } from '@/common/hooks' import { PageTitle } from '@/components/material/PageTitle' import { useGetAuthorizedUserQuery } from '@/redux/auth' @@ -19,6 +25,7 @@ export const FrontPage = () => { const fullStudyProgrammeRights = getFullStudyProgrammeRights(programmeRights) const [visibleReleases, setVisibleReleases] = useState([]) + // TODO: Add missing features and extract access right checking const featureItems = [ { show: true, @@ -29,10 +36,10 @@ export const FrontPage = () => { show: checkUserAccess(['admin', 'fullSisuAccess'], roles) || programmeRights.length > 0, title: 'Programmes', content: ( - - Class statistics: View details of a specific year of a study programme - Overview: View statistics of a programme across all years - +
    +
  • Class statistics: View details of a specific year of a study programme
  • +
  • Overview: View statistics of a programme across all years
  • +
), }, { @@ -58,8 +65,6 @@ export const FrontPage = () => { }, ] - const filterInternalReleases = (release: Release) => !release.title.startsWith('Internal:') - useEffect(() => { if (!releaseData) { return @@ -86,7 +91,11 @@ export const FrontPage = () => { ))} - + + + From faba796303f29d67fcdc93b08933fc237ae56f52 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 16:56:21 +0200 Subject: [PATCH 09/11] [FrontPage] Remove old Semantic UI implementation --- .../src/components/Frontpage/Changelog.jsx | 72 ---------- .../src/components/Frontpage/index.jsx | 123 ------------------ 2 files changed, 195 deletions(-) delete mode 100644 services/frontend/src/components/Frontpage/Changelog.jsx delete mode 100644 services/frontend/src/components/Frontpage/index.jsx diff --git a/services/frontend/src/components/Frontpage/Changelog.jsx b/services/frontend/src/components/Frontpage/Changelog.jsx deleted file mode 100644 index 44e980fd3..000000000 --- a/services/frontend/src/components/Frontpage/Changelog.jsx +++ /dev/null @@ -1,72 +0,0 @@ -import { useEffect, useState } from 'react' -import ReactMarkdown from 'react-markdown' -import { Divider, Header, Loader } from 'semantic-ui-react' - -import { builtAt } from '@/conf' -import { useGetChangelogQuery } from '@/redux/changelog' - -export const Changelog = ({ showFullChangelog }) => { - const [itemsToShow, setItemsToShow] = useState([]) - const { data, isLoading } = useGetChangelogQuery() - - const filterInternalReleases = release => !release.title.startsWith('Internal:') - - useEffect(() => { - if (!data) return - setItemsToShow( - showFullChangelog - ? [...data.filter(filterInternalReleases).slice(0, 20)] - : [...data.filter(filterInternalReleases).slice(0, 2)] - ) - }, [data, showFullChangelog]) - - const formatDate = dateString => { - const date = new Date(dateString) - const dateFormatter = new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'medium' }) - return dateFormatter.format(date) - } - - /** - * Strips the internal part of the changelog description. It doesn't matter how - * the keyword is spelled in the changelog, but using **Internal** is recommended. - * - * @param {string} string - The description to parse. - * @returns string - The description without the internal part. - */ - const getDescription = string => { - const lines = string.split('\n') - const internalIndex = lines.findIndex(line => line.toLowerCase().includes('internal')) - if (internalIndex === -1 || internalIndex === 0) { - return string - } - return lines.slice(0, internalIndex).join('\n') - } - - const getReleaseString = release => { - const date = formatDate(release.time) - const description = getDescription(release.description) - const releaseString = showFullChangelog - ? `## ${release.title}\n${date}\n\n${description}` - : `#### ${release.title}\n${description}` - return releaseString - } - - if (isLoading || itemsToShow.length === 0) return - - return ( -
- {!showFullChangelog && ( - <> -
Updates
-

Last update on: {builtAt ? formatDate(builtAt) : formatDate(itemsToShow[0].time)}

- - )} - {itemsToShow.map(release => ( -
- - {getReleaseString(release)} -
- ))} -
- ) -} diff --git a/services/frontend/src/components/Frontpage/index.jsx b/services/frontend/src/components/Frontpage/index.jsx deleted file mode 100644 index 9cd72f0ef..000000000 --- a/services/frontend/src/components/Frontpage/index.jsx +++ /dev/null @@ -1,123 +0,0 @@ -import { Fragment, useState } from 'react' -import { Button, Container, Divider, Grid, Header, Image, Icon, List } from 'semantic-ui-react' -import { checkUserAccess, getFullStudyProgrammeRights, images, isDefaultServiceProvider } from '@/common' -import { useTitle } from '@/common/hooks' -import { useGetAuthorizedUserQuery } from '@/redux/auth' -import { Changelog } from './Changelog' - -const FrontPageItem = ({ title, content }) => { - return ( - <> -
{title}
- {content} - - ) -} - -export const FrontPage = () => { - const { roles, programmeRights } = useGetAuthorizedUserQuery() - const fullStudyProgrammeRights = getFullStudyProgrammeRights(programmeRights) - - const [showFullChangelog, setShowFullChangelog] = useState(false) - - useTitle() - - const items = [ - { - show: true, - title: 'University', - content:

View tables and diagrams about study progress of different faculties

, - }, - { - show: checkUserAccess(['admin', 'fullSisuAccess'], roles) || programmeRights.length > 0, - title: 'Programmes', - content: ( - - - Class statistics: View details of a specific year of a study programme - - - Overview: View statistics of a programme across all years - - - ), - }, - { - show: checkUserAccess(['courseStatistics', 'admin'], roles) || fullStudyProgrammeRights.length > 0, - title: 'Courses', - content:

View statistics about course attempts, completions and grades

, - }, - { - show: checkUserAccess(['studyGuidanceGroups', 'admin'], roles) || fullStudyProgrammeRights.length > 0, - title: 'Students', - content:

View detailed information for a given student

, - }, - { - show: isDefaultServiceProvider(), - title: 'Feedback', - content: ( -

- For questions and suggestions, please use the{' '} - feedback form or shoot an email to{' '} - grp-toska@helsinki.fi. -

- ), - }, - ] - - return ( -
- - {showFullChangelog ? ( - <> -
- Latest updates -
- - - - - ) : ( - <> -
- Oodikone -
-
- Exploratory Research on Study Data -
- - - - {items.map( - (item, index) => - item.show && ( - - - {index !== items.length - 1 ? : null} - - ) - )} - - - - - - - - - )} -
- - Logo of Toska - -
- ) -} From 8ea1308c774ffd86bf0fbc85ba9e3fcf9d6e8f91 Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 16:59:51 +0200 Subject: [PATCH 10/11] [Frontend] Remove build at Each release has an associated time stamp now. This could still be used in a possible footer? --- services/frontend/src/conf.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/services/frontend/src/conf.js b/services/frontend/src/conf.js index 158eb5a41..0ee400936 100644 --- a/services/frontend/src/conf.js +++ b/services/frontend/src/conf.js @@ -13,9 +13,6 @@ export const runningInCypress = typeof window !== 'undefined' && !!window.Cypres export const basePath = process.env.PUBLIC_URL || '' export const apiBasePath = `${basePath}/api` -// Update time for frontpage -export const builtAt = process.env.REACT_APP_BUILT_AT || '' - // Service provider depending this hiding some not needed features default value toska export const serviceProvider = process.env.REACT_APP_SERVICE_PROVIDER ? process.env.REACT_APP_SERVICE_PROVIDER.toLowerCase() From 2b5bf095147e951b79ec8e2fac84d38f1280d05f Mon Sep 17 00:00:00 2001 From: Riku Rauhala Date: Fri, 15 Nov 2024 17:08:39 +0200 Subject: [PATCH 11/11] [PageTitle] Tweak subtitle --- services/frontend/src/components/material/PageTitle/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/frontend/src/components/material/PageTitle/index.tsx b/services/frontend/src/components/material/PageTitle/index.tsx index 89f96fe2c..fa6743489 100644 --- a/services/frontend/src/components/material/PageTitle/index.tsx +++ b/services/frontend/src/components/material/PageTitle/index.tsx @@ -13,7 +13,7 @@ export const PageTitle = ({ subtitle, title }: { subtitle?: string; title: strin {title}
{subtitle && ( - + {subtitle} )}