diff --git a/frontend/src/Pages/AdminPage/applets.ts b/frontend/src/Pages/AdminPage/applets.ts index 821c92f69..e3eda63e2 100644 --- a/frontend/src/Pages/AdminPage/applets.ts +++ b/frontend/src/Pages/AdminPage/applets.ts @@ -15,7 +15,7 @@ export const appletCategories: AppletCategory[] = [ url: ROUTES.frontend.admin_events, }, { - title_nb: 'Informasjons­­sider', + title_nb: 'Informasjonssider', title_en: 'Information pages', perm: PERM.SAMFUNDET_ADD_INFORMATIONPAGE, icon: 'ph:note-pencil-light', @@ -56,6 +56,13 @@ export const appletCategories: AppletCategory[] = [ icon: 'mdi:person-search', url: ROUTES.frontend.admin_users, }, + { + title_nb: 'Roller', + title_en: 'Roles', + perm: PERM.SAMFUNDET_VIEW_ROLE, + icon: 'ph:user-circle-gear', + url: ROUTES.frontend.admin_roles, + }, { title_nb: 'Gjenger', title_en: 'Gangs', diff --git a/frontend/src/PagesAdmin/RolesAdminPage/RolesAdminPage.tsx b/frontend/src/PagesAdmin/RolesAdminPage/RolesAdminPage.tsx new file mode 100644 index 000000000..528f0403b --- /dev/null +++ b/frontend/src/PagesAdmin/RolesAdminPage/RolesAdminPage.tsx @@ -0,0 +1,66 @@ +import { useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; +import { CrudButtons } from '~/Components'; +import { Table } from '~/Components/Table'; +import { AdminPageLayout } from '~/PagesAdmin/AdminPageLayout/AdminPageLayout'; +import type { RoleDto } from '~/dto'; +import { KEY } from '~/i18n/constants'; +import { lowerCapitalize } from '~/utils'; + +export function RolesAdminPage() { + const { t } = useTranslation(); + + const navigate = useNavigate(); + + const [roles, setRoles] = useState([ + { + id: 1, + name: 'Opptaksansvarlig', + permissions: ['samfundet.test_permission', 'samfundet.user_create'], + }, + { + id: 2, + name: 'Intervjuer', + permissions: [], + }, + ]); + const [loading, setLoading] = useState(false); + + const columns = [ + { content: t(KEY.common_name), sortable: true }, + { content: lowerCapitalize(`${t(KEY.common_count)} ${t(KEY.common_permissions)}`), sortable: true }, + { content: lowerCapitalize(`${t(KEY.common_count)} ${t(KEY.common_users)}`), sortable: true }, + { content: '' }, + ]; + + // biome-ignore lint/correctness/useExhaustiveDependencies: navigate does not need to be in deplist + const data = useMemo(() => { + if (!roles) return []; + return roles.map((r) => { + return [ + { + content: r.name, + value: r.name, + }, + { + content: r.permissions.length, + value: r.permissions.length, + }, + { + content: 0, + value: 0, + }, + { + content: navigate('#')} />, + }, + ]; + }); + }, [roles]); + + return ( + + + + ); +} diff --git a/frontend/src/PagesAdmin/RolesAdminPage/index.ts b/frontend/src/PagesAdmin/RolesAdminPage/index.ts new file mode 100644 index 000000000..c22ccd910 --- /dev/null +++ b/frontend/src/PagesAdmin/RolesAdminPage/index.ts @@ -0,0 +1 @@ +export { RolesAdminPage } from './RolesAdminPage'; diff --git a/frontend/src/PagesAdmin/index.ts b/frontend/src/PagesAdmin/index.ts index e084ff490..2994f6282 100644 --- a/frontend/src/PagesAdmin/index.ts +++ b/frontend/src/PagesAdmin/index.ts @@ -25,6 +25,7 @@ export { RecruitmentPositionOverviewPage } from './RecruitmentPositionOverviewPa export { RecruitmentUnprocessedApplicantsPage } from './RecruitmentUnprocessedApplicantsPage'; export { RecruitmentUsersWithoutInterviewGangPage } from './RecruitmentUsersWithoutInterviewGangPage'; export { RecruitmentUsersWithoutThreeInterviewCriteriaPage } from './RecruitmentUsersWithoutThreeInterviewCriteriaPage'; +export { RolesAdminPage } from './RolesAdminPage'; export { SaksdokumentAdminPage } from './SaksdokumentAdminPage'; export { SaksdokumentFormAdminPage } from './SaksdokumentFormAdminPage'; export { SultenMenuAdminPage } from './SultenMenuAdminPage'; diff --git a/frontend/src/dto.ts b/frontend/src/dto.ts index 4e164a43d..aabd01caa 100644 --- a/frontend/src/dto.ts +++ b/frontend/src/dto.ts @@ -322,6 +322,14 @@ export type GangTypeDto = { gangs: GangDto[]; }; +export type GangSectionDto = { + id: number; + name_nb: string; + name_en: string; + logo?: string; + gang: GangDto; +}; + export type ClosedPeriodDto = { id: number; message_no: string; @@ -359,6 +367,31 @@ export type KeyValueDto = { value: string; }; +// ############################################################ +// Roles +// ############################################################ + +export type RoleDto = { + id: number; + name: string; + permissions: string[]; +}; + +export type UserGangRoleDto = { + id: number; + obj: GangDto; +}; + +export type UserGangSectionRoleDto = { + id: number; + obj: GangSectionDto; +}; + +export type UserOrganizationRoleDto = { + id: number; + obj: OrganizationDto; +}; + // ############################################################ // Recruitment // ############################################################ diff --git a/frontend/src/i18n/constants.ts b/frontend/src/i18n/constants.ts index 319af276e..7cca42f5e 100644 --- a/frontend/src/i18n/constants.ts +++ b/frontend/src/i18n/constants.ts @@ -118,6 +118,7 @@ export const KEY = { common_users: 'common_users', common_email: 'common_email', common_total: 'common_total', + common_roles: 'common_roles', common_guests: 'common_guests', common_occasion: 'common_occasion', common_phonenumber: 'common_phonenumber', @@ -138,6 +139,7 @@ export const KEY = { common_contact_us: 'common_contact_us', common_doors_date: 'common_doors_date', common_restaurant: 'common_restaurant', + common_permissions: 'common_permissions', common_member: 'common_member', common_membership: 'common_membership', common_select_all: 'common_select_all', diff --git a/frontend/src/i18n/translations.ts b/frontend/src/i18n/translations.ts index e2896f8e2..ab8940c7f 100644 --- a/frontend/src/i18n/translations.ts +++ b/frontend/src/i18n/translations.ts @@ -79,6 +79,7 @@ export const nb = prepareTranslations({ [KEY.common_title]: 'Tittel', [KEY.common_login]: 'Logg inn', [KEY.common_users]: 'Brukere', + [KEY.common_roles]: 'Roller', [KEY.common_active]: 'Aktiv', [KEY.common_event]: 'Arrangement', [KEY.common_repeat]: 'Repeter', @@ -120,6 +121,7 @@ export const nb = prepareTranslations({ [KEY.common_member]: 'Medlem', [KEY.common_membership]: 'Medlemskap', [KEY.common_doors_date]: 'Dørene åpner', + [KEY.common_permissions]: 'Tilganger', [KEY.common_restaurant]: 'Restaurant', [KEY.common_contact_us]: 'Kontakt oss', [KEY.common_select_all]: 'Velg alle', @@ -501,6 +503,7 @@ export const en = prepareTranslations({ [KEY.common_title]: 'Title', [KEY.common_login]: 'Log in', [KEY.common_users]: 'Users', + [KEY.common_roles]: 'Roles', [KEY.common_active]: 'Active', [KEY.common_cancel]: 'Cancel', [KEY.common_venues]: 'Venues', @@ -553,6 +556,7 @@ export const en = prepareTranslations({ [KEY.common_opening_hours]: 'Opening hours', [KEY.common_general]: 'General', [KEY.common_doors_date]: 'Doors', + [KEY.common_permissions]: 'Permissions', [KEY.common_long_description]: 'Long description', [KEY.common_short_description]: 'Short description', [KEY.common_back_to_samfundet]: 'Back to samfundet.no', diff --git a/frontend/src/permissions/permissions.ts b/frontend/src/permissions/permissions.ts index 06b68baf8..0f01b2d7e 100644 --- a/frontend/src/permissions/permissions.ts +++ b/frontend/src/permissions/permissions.ts @@ -1,11 +1,11 @@ /** -""" -THIS FILE IS AUTOGENERATED. -DO NOT WRITE IN THIS FILE, AS IT WILL BE OVERWRITTEN ON NEXT UPDATE. + """ + THIS FILE IS AUTOGENERATED. + DO NOT WRITE IN THIS FILE, AS IT WILL BE OVERWRITTEN ON NEXT UPDATE. -THIS FILE WAS GENERATED BY: root.management.commands.generate_permissions -""" -*/ + THIS FILE WAS GENERATED BY: root.management.commands.generate_permissions + """ + */ // ############################################################ @@ -183,11 +183,6 @@ export const SAMFUNDET_CHANGE_NONMEMBEREMAILREGISTRATION = 'samfundet.change_non export const SAMFUNDET_DELETE_NONMEMBEREMAILREGISTRATION = 'samfundet.delete_nonmemberemailregistration'; export const SAMFUNDET_VIEW_NONMEMBEREMAILREGISTRATION = 'samfundet.view_nonmemberemailregistration'; -export const SAMFUNDET_ADD_NOTIFICATION = 'samfundet.add_notification'; -export const SAMFUNDET_CHANGE_NOTIFICATION = 'samfundet.change_notification'; -export const SAMFUNDET_DELETE_NOTIFICATION = 'samfundet.delete_notification'; -export const SAMFUNDET_VIEW_NOTIFICATION = 'samfundet.view_notification'; - export const SAMFUNDET_ADD_OCCUPIEDTIMESLOT = 'samfundet.add_occupiedtimeslot'; export const SAMFUNDET_CHANGE_OCCUPIEDTIMESLOT = 'samfundet.change_occupiedtimeslot'; export const SAMFUNDET_DELETE_OCCUPIEDTIMESLOT = 'samfundet.delete_occupiedtimeslot'; @@ -282,6 +277,11 @@ export const SAMFUNDET_CHANGE_RESERVATION = 'samfundet.change_reservation'; export const SAMFUNDET_DELETE_RESERVATION = 'samfundet.delete_reservation'; export const SAMFUNDET_VIEW_RESERVATION = 'samfundet.view_reservation'; +export const SAMFUNDET_ADD_ROLE = 'samfundet.add_role'; +export const SAMFUNDET_CHANGE_ROLE = 'samfundet.change_role'; +export const SAMFUNDET_DELETE_ROLE = 'samfundet.delete_role'; +export const SAMFUNDET_VIEW_ROLE = 'samfundet.view_role'; + export const SAMFUNDET_ADD_SAKSDOKUMENT = 'samfundet.add_saksdokument'; export const SAMFUNDET_CHANGE_SAKSDOKUMENT = 'samfundet.change_saksdokument'; export const SAMFUNDET_DELETE_SAKSDOKUMENT = 'samfundet.delete_saksdokument'; @@ -314,6 +314,21 @@ export const SAMFUNDET_CHANGE_USERFEEDBACKMODEL = 'samfundet.change_userfeedback export const SAMFUNDET_DELETE_USERFEEDBACKMODEL = 'samfundet.delete_userfeedbackmodel'; export const SAMFUNDET_VIEW_USERFEEDBACKMODEL = 'samfundet.view_userfeedbackmodel'; +export const SAMFUNDET_ADD_USERGANGROLE = 'samfundet.add_usergangrole'; +export const SAMFUNDET_CHANGE_USERGANGROLE = 'samfundet.change_usergangrole'; +export const SAMFUNDET_DELETE_USERGANGROLE = 'samfundet.delete_usergangrole'; +export const SAMFUNDET_VIEW_USERGANGROLE = 'samfundet.view_usergangrole'; + +export const SAMFUNDET_ADD_USERGANGSECTIONROLE = 'samfundet.add_usergangsectionrole'; +export const SAMFUNDET_CHANGE_USERGANGSECTIONROLE = 'samfundet.change_usergangsectionrole'; +export const SAMFUNDET_DELETE_USERGANGSECTIONROLE = 'samfundet.delete_usergangsectionrole'; +export const SAMFUNDET_VIEW_USERGANGSECTIONROLE = 'samfundet.view_usergangsectionrole'; + +export const SAMFUNDET_ADD_USERORGROLE = 'samfundet.add_userorgrole'; +export const SAMFUNDET_CHANGE_USERORGROLE = 'samfundet.change_userorgrole'; +export const SAMFUNDET_DELETE_USERORGROLE = 'samfundet.delete_userorgrole'; +export const SAMFUNDET_VIEW_USERORGROLE = 'samfundet.view_userorgrole'; + export const SAMFUNDET_ADD_USERPREFERENCE = 'samfundet.add_userpreference'; export const SAMFUNDET_CHANGE_USERPREFERENCE = 'samfundet.change_userpreference'; export const SAMFUNDET_DELETE_USERPREFERENCE = 'samfundet.delete_userpreference'; diff --git a/frontend/src/router/router.tsx b/frontend/src/router/router.tsx index 0f86b5696..6ad6476e4 100644 --- a/frontend/src/router/router.tsx +++ b/frontend/src/router/router.tsx @@ -57,6 +57,7 @@ import { RecruitmentUnprocessedApplicantsPage, RecruitmentUsersWithoutInterviewGangPage, RecruitmentUsersWithoutThreeInterviewCriteriaPage, + RolesAdminPage, SaksdokumentAdminPage, SaksdokumentFormAdminPage, SultenMenuAdminPage, @@ -179,6 +180,16 @@ export const router = createBrowserRouter( element={} />} /> + {/* Roles */} + } + handle={{ crumb: () => {t(KEY.common_roles)} }} + > + } />} + /> + {/* Events */} } diff --git a/frontend/src/routes/frontend.ts b/frontend/src/routes/frontend.ts index 0e1363341..d49b59766 100644 --- a/frontend/src/routes/frontend.ts +++ b/frontend/src/routes/frontend.ts @@ -42,6 +42,8 @@ export const ROUTES_FRONTEND = { admin_impersonate: '/impersonate/', // Users admin_users: '/control-panel/users/', + // Roles + admin_roles: '/control-panel/roles/', // Gangs: admin_gangs: '/control-panel/gangs/', admin_gangs_create: '/control-panel/gangs/create/',