Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions backend/root/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class WebFeatures:
ROLES = 'roles'
GANGS = 'gangs'
INFORMATION = 'information'
INFOBOX = 'infobox'
DOCUMENTS = 'documents'
RECRUITMENT = 'recruitment'
SULTEN = 'sulten'
Expand All @@ -79,6 +80,7 @@ class WebFeatures:
WebFeatures.ROLES,
WebFeatures.GANGS,
WebFeatures.INFORMATION,
WebFeatures.INFOBOX,
WebFeatures.DOCUMENTS,
WebFeatures.RECRUITMENT,
WebFeatures.SULTEN,
Expand Down
2 changes: 1 addition & 1 deletion backend/root/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,4 @@
DEFAULT_FROM_EMAIL = 'mg-web@samfundet.no'

# For enabled features in the control panel
CP_ENABLED = {s.strip() for s in os.getenv('CP_ENABLED', 'events,images,opening_hours,closed_hours,venue').split(',') if s.strip()} & CP_FEATURES_ALL
CP_ENABLED = {s.strip() for s in os.getenv('CP_ENABLED', 'events,images,opening_hours,closed_hours,venue,infobox').split(',') if s.strip()} & CP_FEATURES_ALL
9 changes: 9 additions & 0 deletions backend/root/utils/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@
admin__samfundet_closedperiod_delete = 'admin:samfundet_closedperiod_delete'
admin__samfundet_closedperiod_change = 'admin:samfundet_closedperiod_change'
adminsamfundetclosedperiod__objectId = ''
admin__samfundet_infobox_permissions = 'admin:samfundet_infobox_permissions'
admin__samfundet_infobox_permissions_manage_user = 'admin:samfundet_infobox_permissions_manage_user'
admin__samfundet_infobox_permissions_manage_group = 'admin:samfundet_infobox_permissions_manage_group'
admin__samfundet_infobox_changelist = 'admin:samfundet_infobox_changelist'
admin__samfundet_infobox_add = 'admin:samfundet_infobox_add'
admin__samfundet_infobox_history = 'admin:samfundet_infobox_history'
admin__samfundet_infobox_delete = 'admin:samfundet_infobox_delete'
admin__samfundet_infobox_change = 'admin:samfundet_infobox_change'
adminsamfundetinfobox__objectId = ''
admin__samfundet_textitem_permissions = 'admin:samfundet_textitem_permissions'
admin__samfundet_textitem_permissions_manage_user = 'admin:samfundet_textitem_permissions_manage_user'
admin__samfundet_textitem_permissions_manage_group = 'admin:samfundet_textitem_permissions_manage_group'
Expand Down
2 changes: 1 addition & 1 deletion backend/samfundet/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ class ClosedPeriodAdmin(CustomBaseAdmin):
# list_select_related = True


@register_if_feature_enabled(WebFeatures.INFORMATION, Infobox)
@register_if_feature_enabled(WebFeatures.INFOBOX, Infobox)
class InfoboxAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'title_nb']
Expand Down
6 changes: 5 additions & 1 deletion backend/samfundet/view/general_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,11 @@ class InformationPageView(ModelViewSet):


class InfoboxView(ModelViewSet):
permission_classes = (RoleProtectedOrAnonReadOnlyObjectPermissions,)
feature_key = WebFeatures.INFOBOX
permission_classes = (
RoleProtectedOrAnonReadOnlyObjectPermissions,
FeatureEnabled,
)
serializer_class = InfoboxSerializer
queryset = Infobox.objects.all()

Expand Down
8 changes: 8 additions & 0 deletions frontend/src/Pages/AdminPage/applets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ export const appletCategories: AdminAppletCategory[] = [
url: ROUTES.frontend.admin_information,
feature: 'information',
},
{
title_nb: 'Infobokser',
title_en: 'Infoboxes',
perm: PERM.SAMFUNDET_ADD_INFOBOX,
icon: 'mdi:message-badge-outline',
url: ROUTES.frontend.admin_infobox,
feature: 'infobox',
},
{
title_nb: 'Åpningstider',
title_en: 'Opening hours',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/Pages/ComponentPage/ComponentPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function ComponentPage() {
visibility_from_dt: new Date().toISOString(),
visibility_to_dt: '',
start_dt: new Date().toISOString(),
status: 'active',
status: 'public',
ticket_type: 'free',
title_en: 'Von August with a very long title just like this // 23:59',
title_nb: 'Von August // 23:59',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,92 @@
padding-bottom: 3.75em;
gap: 0.5em;
}

.status_label_row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5em;
}

.status_info_button {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: none;
border-radius: 999px;
padding: 0;
width: 1.35rem;
height: 1.35rem;
background: transparent;
color: $blue;

&:hover {
background: rgba($blue, 0.12);
}

&:focus-visible {
outline: 2px solid $blue;
outline-offset: 2px;
}
}

.status_help_modal {
width: min(32rem, calc(100vw - 2rem));
}

.status_help_modal_header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.75rem;

h3 {
margin: 0;
}
}

.status_help_close_button {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: none;
border-radius: 999px;
width: 2rem;
height: 2rem;
background: transparent;
color: $grey-1;

&:hover {
background: rgba($grey-2, 0.2);
}

@include theme-dark {
color: $grey-4;

&:hover {
background: rgba($grey-4, 0.2);
}
}
}

.status_help_intro {
margin: 0.5rem 0 0;
}

.status_help_list {
margin: 0.75rem 0 0;
padding-left: 1.2rem;

li + li {
margin-top: 0.5rem;
}
}

.status_help_actions {
display: flex;
justify-content: flex-end;
margin-top: 1.25rem;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,22 @@ import type { EventDto } from '~/dto';
import { usePrevious, useTitle } from '~/hooks';
import { KEY } from '~/i18n/constants';
import { venueKeys } from '~/queryKeys';
import { EventAgeRestriction, type EventAgeRestrictionValue, EventCategory, type EventCategoryValue } from '~/types';
import { dbT, getAgeRestrictionKey, getEventCategoryKey, lowerCapitalize } from '~/utils';
import {
EventAgeRestriction,
type EventAgeRestrictionValue,
EventCategory,
type EventCategoryValue,
type EventStatus,
EventStatusChoice,
} from '~/types';
import {
dbT,
getAgeRestrictionKey,
getEventCategoryKey,
getEventStatusDescriptionTranslationKey,
getEventStatusTranslationKey,
lowerCapitalize,
} from '~/utils';
import { AdminPageLayout } from '../AdminPageLayout/AdminPageLayout';
import styles from './EventCreatorAdminPage.module.scss';
import { type FormType, useEventCreatorForm } from './hooks/useEventCreatorForm';
Expand All @@ -30,6 +44,7 @@ import { InfoStep } from './steps/InfoStep';
import { PaymentStep } from './steps/PaymentStep';
import { SummaryStep } from './steps/SummaryStep';
import { TextStep } from './steps/TextStep';
import type { EventStatusOption } from './types';

export function EventCreatorAdminPage() {
const { t } = useTranslation();
Expand Down Expand Up @@ -57,6 +72,16 @@ export function EventCreatorAdminPage() {
label: t(getAgeRestrictionKey(age)),
}));

const availableEventStatuses: EventStatus[] = id
? Object.values(EventStatusChoice)
: [EventStatusChoice.PUBLIC, EventStatusChoice.PRIVATE];

const eventStatusOptions: EventStatusOption[] = availableEventStatuses.map((status) => ({
value: status,
label: t(getEventStatusTranslationKey(status)),
description: t(getEventStatusDescriptionTranslationKey(status)),
}));

const { form, watchedValues, buildPayload } = useEventCreatorForm({
event,
defaultCategory: eventCategoryOptions[0]?.value ?? EventCategory.ART,
Expand All @@ -68,7 +93,7 @@ export function EventCreatorAdminPage() {
info: <InfoStep form={form} eventCategoryOptions={eventCategoryOptions} locationOptions={locationOptions} />,
payment: <PaymentStep form={form} ageLimitOptions={ageLimitOptions} />,
graphics: <GraphicsStep form={form} />,
summary: <SummaryStep form={form} />,
summary: <SummaryStep form={form} eventStatusOptions={eventStatusOptions} />,
};

// Fetch event data using the event ID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
EVENT_LOCATION,
EVENT_REGISTRATION_URL,
EVENT_START_DT,
EVENT_STATUS,
EVENT_TICKET_TYPE,
EVENT_TITLE,
EVENT_VISIBILITY_FROM_DT,
Expand Down Expand Up @@ -51,6 +52,7 @@ export const eventSchema = z.object({
// Graphics
image: OPTIONAL_IMAGE,
// Summary/Publication date
status: EVENT_STATUS,
visibility_from_dt: EVENT_VISIBILITY_FROM_DT,
visibility_to_dt: EVENT_VISIBILITY_TO_DT,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useForm } from 'react-hook-form';
import type { z } from 'zod';

import type { EventDto, EventWriteDto } from '~/dto';
import type { EventCategoryValue } from '~/types';
import { type EventCategoryValue, EventStatusChoice } from '~/types';
import { utcTimestampToLocal } from '~/utils';
import { eventSchema } from '../EventCreatorSchema';

Expand Down Expand Up @@ -46,6 +46,7 @@ export function useEventCreatorForm(params: {
custom_tickets: [],
billig_id: undefined,
image: undefined,
status: EventStatusChoice.PUBLIC,
visibility_from_dt: '',
visibility_to_dt: '',
},
Expand Down Expand Up @@ -75,6 +76,7 @@ export function useEventCreatorForm(params: {
custom_tickets: event.custom_tickets || [],
billig_id: event.billig?.id,
image: event.image ?? undefined,
status: event.status || EventStatusChoice.PUBLIC,
visibility_from_dt: event.visibility_from_dt ? utcTimestampToLocal(event.visibility_from_dt, false) : '',
visibility_to_dt: event.visibility_to_dt ? utcTimestampToLocal(event.visibility_to_dt, false) : '',
};
Expand Down
Loading