From de6fdfe18084cbb81f35bbe84c8173a6e7b5c20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=98vre=20Sygard?= <56266980+magsyg@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:57:42 +0100 Subject: [PATCH 1/7] feat: add error text on lacking text (#1642) * feat: add error text on lacking text * restrucure error messages --------- Co-authored-by: magsyg --- frontend/src/hooks.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/frontend/src/hooks.ts b/frontend/src/hooks.ts index 70512a9c5..ad7635cb8 100644 --- a/frontend/src/hooks.ts +++ b/frontend/src/hooks.ts @@ -10,6 +10,7 @@ import type { TextItemValue } from './constants/TextItems'; import { useAuthContext } from './context/AuthContext'; import { useGlobalContext } from './context/GlobalContextProvider'; import type { TextItemDto } from './dto'; +import { STATUS } from './http_status_codes'; import { LANGUAGES } from './i18n/types'; // Make typescript happy. @@ -75,9 +76,19 @@ export function useTextItem(key: TextItemValue, language?: string): string | und const { i18n } = useTranslation(); const isNorwegian = (language || i18n.language) === LANGUAGES.NB; useEffect(() => { - getTextItem(key).then((data) => { - setTextItem(data); - }); + getTextItem(key) + .then((data) => { + setTextItem(data); + }) + .catch((error) => { + if (error.request.status === STATUS.HTTP_404_NOT_FOUND) { + } + setTextItem({ + key: 'MISSING_TEXTITEM', + text_nb: 'ERROR ERROR Manglende tekst, kontakt redaksjon@samfundet.no ERROR ERROR', + text_en: 'ERROR ERROR Missing text, contact redaksjon@samfundet.no ERROR ERROR', + }); + }); }, [key]); return isNorwegian ? textItem?.text_nb : textItem?.text_en; } From 3f5e6528b0a8c3d5f81b63e0a8de0f1fa18fc834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=98vre=20Sygard?= <56266980+magsyg@users.noreply.github.com> Date: Tue, 10 Dec 2024 23:58:18 +0100 Subject: [PATCH 2/7] rename separategangpositoion to separate position (#1634) * rename separategangpositoion to separate position * biomefix --------- Co-authored-by: magsyg --- .../GangSeparatePositions/GangSeparatePositions.tsx | 2 +- .../RecruitmentGangOverviewPage.tsx | 2 +- .../components/AppletContainer/AppletContainer.tsx | 4 +++- frontend/src/i18n/constants.ts | 2 +- frontend/src/i18n/translations.ts | 4 ++-- frontend/src/router/router.tsx | 4 ++-- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/frontend/src/Pages/OrganizationRecruitmentPage/Components/GangSeparatePositions/GangSeparatePositions.tsx b/frontend/src/Pages/OrganizationRecruitmentPage/Components/GangSeparatePositions/GangSeparatePositions.tsx index 3e21da1a7..309fd1c82 100644 --- a/frontend/src/Pages/OrganizationRecruitmentPage/Components/GangSeparatePositions/GangSeparatePositions.tsx +++ b/frontend/src/Pages/OrganizationRecruitmentPage/Components/GangSeparatePositions/GangSeparatePositions.tsx @@ -14,7 +14,7 @@ export function GangSeparatePositions({ recruitmentSeparatePositions }: GangSepa return ( {recruitmentSeparatePositions.map((pos) => ( diff --git a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/RecruitmentGangOverviewPage.tsx b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/RecruitmentGangOverviewPage.tsx index f39c9c12f..3820c12ef 100644 --- a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/RecruitmentGangOverviewPage.tsx +++ b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/RecruitmentGangOverviewPage.tsx @@ -121,7 +121,7 @@ export function RecruitmentGangOverviewPage() { { key: 1, label: t(KEY.common_gangs), value: }, { key: 2, - label: t(KEY.recruitment_gangs_with_separate_positions), + label: t(KEY.recruitment_positions_with_separate_recruitment), value:
, }, { key: 3, label: t(KEY.recruitment_interview_groups), value: }, diff --git a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/AppletContainer/AppletContainer.tsx b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/AppletContainer/AppletContainer.tsx index cfb6fee0d..8eea77d3d 100644 --- a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/AppletContainer/AppletContainer.tsx +++ b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/AppletContainer/AppletContainer.tsx @@ -63,7 +63,9 @@ export function AppletContainer({ recruitmentId }: Props) { ( - {t(KEY.common_create)} {t(KEY.recruitment_gangs_with_separate_positions)} + {t(KEY.common_create)} {t(KEY.recruitment_positions_with_separate_recruitment)} ), }} @@ -482,7 +482,7 @@ export const router = createBrowserRouter( handle={{ crumb: ({ pathname }: UIMatch, { separatePosition }: SeparatePositionLoader) => ( - {t(KEY.common_edit)} {t(KEY.recruitment_gangs_with_separate_positions)} -{' '} + {t(KEY.common_edit)} {t(KEY.recruitment_positions_with_separate_recruitment)} -{' '} {separatePosition ? dbT(separatePosition, 'name') : t(KEY.common_unknown)} ), From f6f38b8bff5a7185b1902cbb934ce84f5e6312e6 Mon Sep 17 00:00:00 2001 From: Robin <16273164+robines@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:48:36 +0100 Subject: [PATCH 3/7] Implement role page (#1579) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Begin implementing RoleAdminPage * Format date * Fix errors * Missing date convert * Show created_by * Add getFullDisplayName for displaying full name with username Falls back to just username if user doesn't have name * Add formatDateYMDWithTime to also display timestamp * Improve RoleAdminPage a bit * Django admin: show created_at/by for user roles --------- Co-authored-by: Snorre Sæther <112980079+Snorre98@users.noreply.github.com> --- backend/samfundet/admin.py | 6 +- .../RoleAdminPage/RoleAdminPage.tsx | 107 +++++++++++++++++- frontend/src/api.ts | 8 ++ frontend/src/dto.ts | 28 +++-- frontend/src/i18n/constants.ts | 3 + frontend/src/i18n/translations.ts | 6 + frontend/src/queryKeys.ts | 1 + frontend/src/utils.ts | 12 ++ 8 files changed, 158 insertions(+), 13 deletions(-) diff --git a/backend/samfundet/admin.py b/backend/samfundet/admin.py index a29e3de55..ee77f5861 100644 --- a/backend/samfundet/admin.py +++ b/backend/samfundet/admin.py @@ -171,17 +171,17 @@ class RoleAdmin(admin.ModelAdmin): @admin.register(UserOrgRole) class UserOrgRoleAdmin(admin.ModelAdmin): - list_display = ('user', 'role', 'obj') + list_display = ('user', 'role', 'obj', 'created_at', 'created_by') @admin.register(UserGangRole) class UserGangRoleAdmin(admin.ModelAdmin): - list_display = ('user', 'role', 'obj') + list_display = ('user', 'role', 'obj', 'created_at', 'created_by') @admin.register(UserGangSectionRole) class UserGangSectionRoleAdmin(admin.ModelAdmin): - list_display = ('user', 'role', 'obj') + list_display = ('user', 'role', 'obj', 'created_at', 'created_by') @admin.register(Permission) diff --git a/frontend/src/PagesAdmin/RoleAdminPage/RoleAdminPage.tsx b/frontend/src/PagesAdmin/RoleAdminPage/RoleAdminPage.tsx index c57ce479a..b00d959e8 100644 --- a/frontend/src/PagesAdmin/RoleAdminPage/RoleAdminPage.tsx +++ b/frontend/src/PagesAdmin/RoleAdminPage/RoleAdminPage.tsx @@ -1,16 +1,119 @@ +import { useQuery } from '@tanstack/react-query'; +import { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import { useRouteLoaderData } from 'react-router-dom'; +import { H1, Link, Table } from '~/Components'; import { AdminPageLayout } from '~/PagesAdmin/AdminPageLayout/AdminPageLayout'; +import { getRoleUsers } from '~/api'; +import type { RoleDto, RoleUsersDto } from '~/dto'; import { useTitle } from '~/hooks'; import { KEY } from '~/i18n/constants'; +import { reverse } from '~/named-urls'; +import { roleKeys } from '~/queryKeys'; +import type { RoleLoader } from '~/router/loaders'; +import { ROUTES_FRONTEND } from '~/routes/frontend'; +import { dbT, formatDateYMDWithTime, getFullDisplayName } from '~/utils'; + +function getCreatedInfo(ru: RoleUsersDto) { + const roleData = ru.org_role || ru.gang_role || ru.section_role; + return { + createdAt: roleData?.created_at ? formatDateYMDWithTime(new Date(roleData.created_at)) : '', + createdBy: roleData?.created_by ? getFullDisplayName(roleData.created_by) : '', + }; +} export function RoleAdminPage() { const { t } = useTranslation(); - const title = t(KEY.common_role); + const { role } = useRouteLoaderData('role') as RoleLoader; + + const title = `${t(KEY.common_role)}: ${role?.name}`; + useTitle(title); + const { data, isLoading } = useQuery({ + queryKey: roleKeys.users((role as RoleDto).id), + queryFn: () => (role ? getRoleUsers(role.id) : undefined), + enabled: !!role, + }); + + const usersColumns = [ + t(KEY.common_name), + t(KEY.admin_role_page_orggangsection), + t(KEY.admin_role_page_role_since), + t(KEY.admin_role_page_given_by), + ]; + + const getRoleInfo = useCallback( + (ru: RoleUsersDto) => { + if (ru.org_role) { + return { + content: ( + <> + {t(KEY.recruitment_organization)}: {ru.org_role.organization.name} + + ), + value: ru.org_role.organization.name, + }; + } + + if (ru.gang_role) { + return { + content: ( + + {t(KEY.common_gang)}: {dbT(ru.gang_role.gang, 'name')} + + ), + value: dbT(ru.gang_role.gang, 'name'), + }; + } + + if (ru.section_role) { + return { + content: ( + <> + {t(KEY.common_section)}: {dbT(ru.section_role.section, 'name')} + + ), + value: dbT(ru.section_role.section, 'name'), + }; + } + + // We'll never end up here, but just in case the API changes... + return { content: '', value: '' }; + }, + [t], + ); + + const usersData = useMemo(() => { + if (!data) { + return []; + } + return data.map((ru) => { + const fullName = getFullDisplayName(ru.user); + const roleInfo = getRoleInfo(ru); + const { createdAt, createdBy } = getCreatedInfo(ru); + + return { + cells: [ + { content: fullName, value: fullName }, + { content: roleInfo.content, value: roleInfo.value }, + { content: createdAt, value: createdAt }, + { content: createdBy, value: createdBy }, + ], + }; + }); + }, [data, getRoleInfo]); + return ( -
+

{t(KEY.common_users)}

+ + {isLoading ? Loading :
} ); } diff --git a/frontend/src/api.ts b/frontend/src/api.ts index e77eb2fb9..59bde6871 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -39,6 +39,7 @@ import type { RecruitmentUserDto, RegistrationDto, RoleDto, + RoleUsersDto, SaksdokumentDto, TextItemDto, UserDto, @@ -574,6 +575,13 @@ export async function getRecruitmentPositions(recruitmentId: string): Promise { + const url = BACKEND_DOMAIN + reverse({ pattern: ROUTES.backend.samfundet__role_users, urlParams: { pk: id } }); + const response = await axios.get(url, { withCredentials: true }); + + return response.data; +} + export async function getRecruitmentPositionsGangForApplicant( recruitmentId: number | string, gangId: number | string | undefined, diff --git a/frontend/src/dto.ts b/frontend/src/dto.ts index c7e5fd1f4..0b8d77e6d 100644 --- a/frontend/src/dto.ts +++ b/frontend/src/dto.ts @@ -383,19 +383,31 @@ export type RoleDto = { content_type?: string | null; }; -export type UserGangRoleDto = { +export type UserRole = { id: number; - obj: GangDto; + user: UserDto; + created_at: Date; + obj: OrganizationDto | GangDto | GangSectionDto; + created_by?: UserDto; }; -export type UserGangSectionRoleDto = { - id: number; - obj: GangSectionDto; +export type UserGangRoleDto = Omit & { + gang: GangDto; }; -export type UserOrganizationRoleDto = { - id: number; - obj: OrganizationDto; +export type UserGangSectionRoleDto = Omit & { + section: GangSectionDto; +}; + +export type UserOrganizationRoleDto = Omit & { + organization: OrganizationDto; +}; + +export type RoleUsersDto = { + user: UserDto; + org_role?: UserOrganizationRoleDto; + gang_role?: UserGangRoleDto; + section_role?: UserGangSectionRoleDto; }; // ############################################################ diff --git a/frontend/src/i18n/constants.ts b/frontend/src/i18n/constants.ts index 996fa3c28..2c1566ca0 100644 --- a/frontend/src/i18n/constants.ts +++ b/frontend/src/i18n/constants.ts @@ -429,6 +429,9 @@ export const KEY = { admin_saksdokumenter_cannot_reupload: 'admin_saksdokumenter_cannot_reupload', admin_impersonate: 'admin_impersonate', admin_stop_impersonate: 'admin_stop_impersonate', + admin_role_page_orggangsection: 'admin_role_page_orggangsection', + admin_role_page_role_since: 'admin_role_page_role_since', + admin_role_page_given_by: 'admin_role_page_given_by', // CommandMenu: command_menu_label: 'command_menu_label', diff --git a/frontend/src/i18n/translations.ts b/frontend/src/i18n/translations.ts index 97698d16b..603fdc1da 100644 --- a/frontend/src/i18n/translations.ts +++ b/frontend/src/i18n/translations.ts @@ -211,6 +211,9 @@ export const nb = prepareTranslations({ [KEY.new_password]: 'Nytt passord', [KEY.admin_impersonate]: 'Stjel identitet', [KEY.admin_stop_impersonate]: 'Stopp identitetstyveri', + [KEY.admin_role_page_orggangsection]: 'Org/Gjeng/Seksjon', + [KEY.admin_role_page_role_since]: 'Hatt rollen siden', + [KEY.admin_role_page_given_by]: 'Gitt av', // LoginPage: [KEY.loginpage_register]: 'Lag bruker', @@ -704,6 +707,9 @@ export const en = prepareTranslations({ [KEY.new_password]: 'New password', [KEY.admin_impersonate]: 'Impersonate', [KEY.admin_stop_impersonate]: 'Stop impersonation', + [KEY.admin_role_page_orggangsection]: 'Org/Gang/Section', + [KEY.admin_role_page_role_since]: 'Had role since', + [KEY.admin_role_page_given_by]: 'Given by', // LoginPage: [KEY.loginpage_register]: 'Create user', diff --git a/frontend/src/queryKeys.ts b/frontend/src/queryKeys.ts index 50e009dee..a65b085e6 100644 --- a/frontend/src/queryKeys.ts +++ b/frontend/src/queryKeys.ts @@ -4,6 +4,7 @@ export const roleKeys = { list: (filters: unknown[]) => [...roleKeys.lists(), { filters }] as const, details: () => [...roleKeys.all, 'detail'] as const, detail: (id: number) => [...roleKeys.details(), id] as const, + users: (id: number) => [...roleKeys.detail(id), 'users'] as const, }; export const infoPageKeys = { diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts index 3f455f46c..cf36b5ade 100644 --- a/frontend/src/utils.ts +++ b/frontend/src/utils.ts @@ -155,6 +155,14 @@ export function getFullName(u: UserDto): string { return `${u.first_name} ${u.last_name}`.trim(); } +export function getFullDisplayName(u: UserDto): string { + const fullName = getFullName(u); + if (!fullName) { + return u.username; + } + return `${fullName} (${u.username})`; +} + /** Helper to determine if a KeyValue is truthy. */ export function isTruthy(value = ''): boolean { const falsy = ['', 'no', 'zero', '0']; @@ -253,6 +261,10 @@ export function formatDateYMD(d: Date): string { return format(d, 'yyyy.LL.dd'); } +export function formatDateYMDWithTime(d: Date): string { + return format(d, 'yyyy.LL.dd HH:mm'); +} + /** * Generic query function for DTOs. Returns elements from array matching query. * @param query String query to search with From 5cd8ee90c77f2493f364704a1436db32185fd4fc Mon Sep 17 00:00:00 2001 From: Robin <16273164+robines@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:00:35 +0100 Subject: [PATCH 4/7] Use Biome unused imports and top-level hooks rules (#1626) * Use unused import and top-level hooks rule * Remove unused imports * Remove enabled argument from UserFeedback (fixes top-level hooks error) It's also better to disable the component by just not rendering it, instead of dealing with enabled state. --- biome.jsonc | 6 +++++- frontend/src/App.tsx | 2 +- frontend/src/Components/DatePicker/DatePicker.tsx | 2 +- frontend/src/Components/Dropdown/Dropdown.stories.tsx | 2 +- .../RecruitmentApplicantsStatus.tsx | 3 +-- .../Components/UserFeedback/UserFeedback.stories.tsx | 2 +- frontend/src/Components/UserFeedback/UserFeedback.tsx | 10 +--------- .../RecruitmentInterviewGroupsList.tsx | 4 ++-- .../RecruitmentInterviewGroupComponent.tsx | 2 +- 9 files changed, 14 insertions(+), 19 deletions(-) diff --git a/biome.jsonc b/biome.jsonc index f8edeb4c7..af4601097 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -28,7 +28,11 @@ "linter": { "enabled": true, "rules": { - "recommended": true + "recommended": true, + "correctness": { + "noUnusedImports": "error", + "useHookAtTopLevel": "error" + } } }, "formatter": { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 05f886d01..e65530c9e 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -28,7 +28,7 @@ export function App() { return ( - + {goatCounterCode && ( {/* Helmet is linked to . Used to add scripts. */} diff --git a/frontend/src/Components/DatePicker/DatePicker.tsx b/frontend/src/Components/DatePicker/DatePicker.tsx index e978c5f38..f4b2433f4 100644 --- a/frontend/src/Components/DatePicker/DatePicker.tsx +++ b/frontend/src/Components/DatePicker/DatePicker.tsx @@ -1,7 +1,7 @@ import { Icon } from '@iconify/react'; import classNames from 'classnames'; import { format } from 'date-fns'; -import React, { forwardRef, useMemo } from 'react'; +import { forwardRef, useMemo } from 'react'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { MiniCalendar } from '~/Components'; diff --git a/frontend/src/Components/Dropdown/Dropdown.stories.tsx b/frontend/src/Components/Dropdown/Dropdown.stories.tsx index efa82ab29..4f17df4d0 100644 --- a/frontend/src/Components/Dropdown/Dropdown.stories.tsx +++ b/frontend/src/Components/Dropdown/Dropdown.stories.tsx @@ -1,4 +1,4 @@ -import type { ComponentMeta, ComponentStory, Meta, StoryObj } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { Dropdown } from './Dropdown'; // Local component config. diff --git a/frontend/src/Components/RecruitmentApplicantsStatus/RecruitmentApplicantsStatus.tsx b/frontend/src/Components/RecruitmentApplicantsStatus/RecruitmentApplicantsStatus.tsx index 23103e743..49ddad243 100644 --- a/frontend/src/Components/RecruitmentApplicantsStatus/RecruitmentApplicantsStatus.tsx +++ b/frontend/src/Components/RecruitmentApplicantsStatus/RecruitmentApplicantsStatus.tsx @@ -1,10 +1,9 @@ import { useTranslation } from 'react-i18next'; -import { InputField, TimeDisplay } from '~/Components'; +import { TimeDisplay } from '~/Components'; import { CrudButtons } from '~/Components/CrudButtons/CrudButtons'; import { Dropdown, type DropdownOption } from '~/Components/Dropdown/Dropdown'; import { Table } from '~/Components/Table'; import { Text } from '~/Components/Text/Text'; -import { putRecruitmentApplicationForGang } from '~/api'; import type { RecruitmentApplicationDto, RecruitmentApplicationStateDto } from '~/dto'; import { useCustomNavigate } from '~/hooks'; import { KEY } from '~/i18n/constants'; diff --git a/frontend/src/Components/UserFeedback/UserFeedback.stories.tsx b/frontend/src/Components/UserFeedback/UserFeedback.stories.tsx index fc0feae02..03aae52a0 100644 --- a/frontend/src/Components/UserFeedback/UserFeedback.stories.tsx +++ b/frontend/src/Components/UserFeedback/UserFeedback.stories.tsx @@ -8,7 +8,7 @@ export default { } as ComponentMeta; const Template: ComponentStory = () => { - return ; + return ; }; export const Primary = Template.bind({}); diff --git a/frontend/src/Components/UserFeedback/UserFeedback.tsx b/frontend/src/Components/UserFeedback/UserFeedback.tsx index 711b3172d..d9b3a537a 100644 --- a/frontend/src/Components/UserFeedback/UserFeedback.tsx +++ b/frontend/src/Components/UserFeedback/UserFeedback.tsx @@ -10,23 +10,15 @@ import { useTextItem } from '~/hooks'; import { KEY } from '~/i18n/constants'; import styles from './UserFeedback.module.scss'; -type UserFeedbackProps = { - enabled: boolean; -}; - type FormProps = { text: string; contact_email?: string; }; -export function UserFeedback({ enabled }: UserFeedbackProps) { +export function UserFeedback() { const { t } = useTranslation(); const [isOpen, setIsOpen] = useState(false); - if (!enabled) { - return
; - } - const handleFormSubmit = (formData: FormProps) => { postFeedback({ ...formData, diff --git a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/RecruitmentInterviewGroupsList.tsx b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/RecruitmentInterviewGroupsList.tsx index 9f0ef8c96..96dcc3d1d 100644 --- a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/RecruitmentInterviewGroupsList.tsx +++ b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/RecruitmentInterviewGroupsList.tsx @@ -2,8 +2,8 @@ import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; import { toast } from 'react-toastify'; -import { getRecruitmentSharedInterviewGroups, getRecruitmentStats } from '~/api'; -import type { RecruitmentSharedInterviewGroupDto, RecruitmentStatsDto } from '~/dto'; +import { getRecruitmentSharedInterviewGroups } from '~/api'; +import type { RecruitmentSharedInterviewGroupDto } from '~/dto'; import { KEY } from '~/i18n/constants'; import styles from './RecruitmentInterviewGroupsList.module.scss'; import { RecruitmentInterviewGroupComponent } from './components/RecruitmentInterviewGroupComponent/RecruitmentInterviewGroupComponent'; diff --git a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/components/RecruitmentInterviewGroupComponent/RecruitmentInterviewGroupComponent.tsx b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/components/RecruitmentInterviewGroupComponent/RecruitmentInterviewGroupComponent.tsx index 471c8260f..27dec86bb 100644 --- a/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/components/RecruitmentInterviewGroupComponent/RecruitmentInterviewGroupComponent.tsx +++ b/frontend/src/PagesAdmin/RecruitmentGangOverviewPage/components/RecruitmentInterviewGroupsList/components/RecruitmentInterviewGroupComponent/RecruitmentInterviewGroupComponent.tsx @@ -1,5 +1,5 @@ import { ExpandableHeader, Table } from '~/Components'; -import type { RecruitmentSharedInterviewGroupDto, RecruitmentStatsDto } from '~/dto'; +import type { RecruitmentSharedInterviewGroupDto } from '~/dto'; import { dbT } from '~/utils'; import styles from './RecruitmentInterviewGroupComponent.module.scss'; From 2d28bf5f4ce2bf9cce15201122fe3b6c97be38e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=98vre=20Sygard?= <56266980+magsyg@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:23:02 +0100 Subject: [PATCH 5/7] Remove the use of getOrganization (#1628) * remove unecessary extra calls to organization * fixes * fixups * biome fix --------- Co-authored-by: magsyg --- .../OrganizationRecruitmentPage.tsx | 53 ++++++------ .../Components/PersonalRow/PersonalRow.tsx | 2 +- .../RecruitmentCard/RecruitmentCard.tsx | 84 +++++++------------ .../Pages/RecruitmentPage/RecruitmentPage.tsx | 10 +-- .../RecruitmentFormAdminPage.tsx | 6 +- frontend/src/api.ts | 5 +- frontend/src/dto.ts | 6 +- 7 files changed, 72 insertions(+), 94 deletions(-) diff --git a/frontend/src/Pages/OrganizationRecruitmentPage/OrganizationRecruitmentPage.tsx b/frontend/src/Pages/OrganizationRecruitmentPage/OrganizationRecruitmentPage.tsx index f567826df..6413c9e83 100644 --- a/frontend/src/Pages/OrganizationRecruitmentPage/OrganizationRecruitmentPage.tsx +++ b/frontend/src/Pages/OrganizationRecruitmentPage/OrganizationRecruitmentPage.tsx @@ -4,18 +4,33 @@ import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; import { Button, Logo, OccupiedFormModal, Page, SamfundetLogoSpinner, Text, Video } from '~/Components'; import { PersonalRow } from '~/Pages/RecruitmentPage'; -import { getOrganization, getRecruitment } from '~/api'; +import { getRecruitment } from '~/api'; import { useOrganizationContext } from '~/context/OrgContextProvider'; import type { RecruitmentDto } from '~/dto'; import { useDesktop, useTitle } from '~/hooks'; import { KEY } from '~/i18n/constants'; import { OrgNameType, type OrgNameTypeValue } from '~/types'; -import { dbT, getObjectFieldOrNumber } from '~/utils'; +import { dbT } from '~/utils'; import { GangSeparatePositions, GangTypeContainer, RecruitmentTabs } from './Components'; import styles from './OrganizationRecruitmentPage.module.scss'; type ViewMode = 'list' | 'tab'; +const ORG_STYLES = { + [OrgNameType.SAMFUNDET_NAME]: { + subHeaderStyle: styles.samfRecruitmentSubHeader, + }, + [OrgNameType.UKA_NAME]: { + subHeaderStyle: styles.ukaRecruitmentSubHeader, + }, + [OrgNameType.ISFIT_NAME]: { + subHeaderStyle: styles.isfitRecruitmentSubHeader, + }, + [OrgNameType.FALLBACK]: { + subHeaderStyle: '', + }, +}; + export function OrganizationRecruitmentPage() { const isDesktop = useDesktop(); const { recruitmentId } = useParams<{ recruitmentId: string }>(); @@ -23,7 +38,6 @@ export function OrganizationRecruitmentPage() { const { t } = useTranslation(); const { changeOrgTheme, organizationTheme } = useOrganizationContext(); const [recruitment, setRecruitment] = useState(); - const [organizationName, setOrganizationName] = useState(OrgNameType.FALLBACK); const [loading, setLoading] = useState(true); const [positionsViewMode, setViewMode] = useState('list'); @@ -43,25 +57,10 @@ export function OrganizationRecruitmentPage() { useEffect(() => { if (recruitment) { - getOrganization(getObjectFieldOrNumber(recruitment.organization, 'id')) - .then((response) => { - if (Object.values(OrgNameType).includes(response.name as OrgNameTypeValue)) { - setOrganizationName(response.name as OrgNameTypeValue); - } - }) - .catch((error) => { - console.log(error); - setOrganizationName(OrgNameType.FALLBACK); - }); + changeOrgTheme(recruitment.organization.name as OrgNameTypeValue); } setLoading(false); - }, [recruitment]); - - useEffect(() => { - if (organizationName) { - changeOrgTheme(organizationName); - } - }, [organizationName, changeOrgTheme]); + }, [recruitment, changeOrgTheme]); function toggleViewAll() { const toggledValue = !viewAllPositions; @@ -75,7 +74,11 @@ export function OrganizationRecruitmentPage() { ) : (
- + {dbT(recruitment, 'name')} @@ -83,14 +86,12 @@ export function OrganizationRecruitmentPage() { {recruitment?.promo_media &&