Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add open Facebook Event button #143

Merged
merged 6 commits into from
Jul 18, 2024
Merged
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
53 changes: 0 additions & 53 deletions src/client/src/app/+state/events/actions/commit-event.action.ts

This file was deleted.

58 changes: 58 additions & 0 deletions src/client/src/app/+state/events/actions/update-event.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { inject } from '@angular/core';
import { on } from '@ngrx/store';
import { produce } from 'immer';
import { switchMap } from 'rxjs';

import { EventAdministrationService } from '../../../api/services';
import { createHttpAction, handleHttpAction, onHttpAction, toHttpAction } from '../../action-state';
import { createFunctionalEffect } from '../../functional-effect';
import { Effects, Reducers } from '../../utils';
import { EVENTS_ACTION_SCOPE } from '../consts';
import { selectEventsActionState } from '../events.selectors';
import { EventsFeatureState, eventEntityAdapter } from '../events.state';

export const updateEventAction = createHttpAction<{
eventId: string;
commit?: boolean;
externalUri?: string;
}>()(EVENTS_ACTION_SCOPE, 'Update Event');

export const updateEventReducers: Reducers<EventsFeatureState> = [
on(updateEventAction.success, (state, { props }) =>
eventEntityAdapter.mapOne(
{
id: props.eventId,
map: produce(draft => {
draft.staged = props.commit ? props.commit : undefined;
draft.externalUri = props.externalUri != undefined ? props.externalUri : undefined;
}),
},
state
)
),
handleHttpAction('update', updateEventAction),
];

export const updateEventEffects: Effects = {
updateEvent$: createFunctionalEffect.dispatching((api = inject(EventAdministrationService)) =>
onHttpAction(updateEventAction, selectEventsActionState('update')).pipe(
switchMap(({ props }) => toHttpAction(updateEvent(api, props), updateEventAction, props))
)
),
};

async function updateEvent(
api: EventAdministrationService,
props: ReturnType<typeof updateEventAction>['props']
) {
const response = await api.updateEvent({
eventId: props.eventId,
body: {
commit: props.commit ? props.commit : undefined,
externalUri: props.externalUri ?? undefined,
},
});
return response.ok
? updateEventAction.success(props, undefined)
: updateEventAction.error(props, response);
}
2 changes: 1 addition & 1 deletion src/client/src/app/+state/events/events.actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export { addEventPreconfigAction } from './actions/add-event-preconfig.action';
export { addEventTimeslotAction } from './actions/add-event-timeslot.action';
export { addEventAction } from './actions/add-event.action';
export { commitEventAction } from './actions/commit-event.action';
export { updateEventAction } from './actions/update-event.action';
export { eventTimeslotRegistrationChangedAction } from './actions/event-timeslot-registration-changed.action';
export { addPlayerToEventPreconfigurationAction } from './actions/add-player-to-preconfig.action';
export { buildEventInstancesAction } from './actions/build-event-instances.action';
Expand Down
4 changes: 2 additions & 2 deletions src/client/src/app/+state/events/events.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { addEventTimeslotEffects } from './actions/add-event-timeslot.action';
import { addEventEffects } from './actions/add-event.action';
import { addPlayerToEventPreconfigurationEffects } from './actions/add-player-to-preconfig.action';
import { buildEventInstancesEffects } from './actions/build-event-instances.action';
import { commitEventEffects } from './actions/commit-event.action';
import { loadEventAction, loadEventEffects } from './actions/load-event.action';
import { loadEventsEffects } from './actions/load-events.action';
import { removeEventPreconfigEffects } from './actions/remove-event-preconfig.action';
Expand All @@ -15,6 +14,7 @@ import { removeEventAction, removeEventEffects } from './actions/remove-event.ac
import { removePlayerFromPreconfigEffects } from './actions/remove-player-from-preconfig.action';
import { startEventEffects } from './actions/start-event.action';
import { updateEventTimeslotEffects } from './actions/update-event-timeslot.action';
import { updateEventEffects } from './actions/update-event.action';
import {
eventTimeslotRegistrationChangedAction,
resetEventsActionStateAction,
Expand All @@ -36,7 +36,7 @@ export const eventsFeatureEffects: Effects[] = [
removeEventEffects,
removePlayerFromPreconfigEffects,
startEventEffects,
commitEventEffects,
updateEventEffects,
updateEventTimeslotEffects,
{
eventUpdated$: createFunctionalEffect.dispatching((events = inject(RealtimeEventsService)) =>
Expand Down
4 changes: 2 additions & 2 deletions src/client/src/app/+state/events/events.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { addEventTimeslotReducers } from './actions/add-event-timeslot.action';
import { addEventReducers } from './actions/add-event.action';
import { addPlayerToEventPreconfigurationReducers } from './actions/add-player-to-preconfig.action';
import { buildEventInstancesReducers } from './actions/build-event-instances.action';
import { commitEventReducers } from './actions/commit-event.action';
import { eventTimeslotRegistrationChangedReducers } from './actions/event-timeslot-registration-changed.action';
import { loadEventReducers } from './actions/load-event.action';
import { loadEventsReducers } from './actions/load-events.action';
Expand All @@ -16,6 +15,7 @@ import { removePlayerFromPreconfigReducers } from './actions/remove-player-from-
import { resetEventsActionStateReducers } from './actions/reset-events-action-state.action';
import { startEventReducers } from './actions/start-event.action';
import { updateEventTimeslotReducers } from './actions/update-event-timeslot.action';
import { updateEventReducers } from './actions/update-event.action';
import { EventsFeatureState, initialEventsFeatureState } from './events.state';

export const eventsReducer = createReducer<EventsFeatureState>(
Expand All @@ -26,7 +26,7 @@ export const eventsReducer = createReducer<EventsFeatureState>(
...addEventReducers,
...addPlayerToEventPreconfigurationReducers,
...buildEventInstancesReducers,
...commitEventReducers,
...updateEventReducers,
...eventTimeslotRegistrationChangedReducers,
...loadEventReducers,
...loadEventsReducers,
Expand Down
4 changes: 2 additions & 2 deletions src/client/src/app/+state/events/events.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type EventsFeatureState = EntityState<Event> & {
add: ActionState;
remove: ActionState;
start: ActionState;
commit: ActionState;
update: ActionState;
addTimeslot: ActionState;
removeTimeslot: ActionState;
buildInstances: ActionState;
Expand All @@ -36,7 +36,7 @@ export const initialEventsFeatureState: EventsFeatureState = eventEntityAdapter.
add: initialActionState,
remove: initialActionState,
start: initialActionState,
commit: initialActionState,
update: initialActionState,
addTimeslot: initialActionState,
removeTimeslot: initialActionState,
buildInstances: initialActionState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,37 @@
</div>
</p-card>

<div class="mt-4 flex flex-row items-center gap-2">
<h2 class="m-0 grow">{{ translations.events_facebookLink() }}</h2>
<div>
<p-inputGroup>
<button
type="button"
pButton
[label]="
externalUri() && externalUri() !== undefined && externalUri()?.length !== 0
? translations.shared_edit()
: translations.shared_add()
"
icon="i-[mdi--facebook]"
(click)="modifyExternalUriDialog.open(externalUri())"
></button>
<button
type="button"
pButton
class="bg-surface-a text-primary"
icon="i-[mdi--arrow-right-circle]"
[disabled]="
externalUri() && externalUri() !== undefined && externalUri()?.length !== 0
? false
: true
"
(click)="openExternalUri()"
></button>
</p-inputGroup>
</div>
</div>

<div class="mt-4 flex flex-row items-center gap-2">
<h2 class="m-0 grow">{{ translations.events_timeslots() }}</h2>
<span
Expand Down Expand Up @@ -189,6 +220,7 @@ <h3 class="m-0 flex flex-row items-center gap-4 px-2">
}

<app-event-timeslot-dialog #createTimeslotDialog [event]="event" />
<app-modify-external-uri-dialog #modifyExternalUriDialog [event]="event" />
} @else {
<div class="mt-16 flex flex-col items-center gap-8">
<span class="i-[mdi--close-octagon] text-[8rem] text-red-500"></span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CommonModule, formatDate } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { InterpolatePipe, interpolate } from '@ngneers/signal-translate';
import { Actions, ofType } from '@ngrx/effects';
Expand All @@ -9,19 +10,23 @@ import { AccordionModule } from 'primeng/accordion';
import { ConfirmationService } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
import { CardModule } from 'primeng/card';
import { InputGroupModule } from 'primeng/inputgroup';
import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
import { InputTextModule } from 'primeng/inputtext';
import { MessagesModule } from 'primeng/messages';
import { ProgressSpinnerModule } from 'primeng/progressspinner';
import { TooltipModule } from 'primeng/tooltip';
import { filter, map, timer } from 'rxjs';

import { ModifyExternalUriDialogComponent } from './modify-external-uri-dialog/modify-external-uri-dialog.component';
import { hasActionFailed, isActionBusy } from '../../../+state/action-state';
import {
buildEventInstancesAction,
removeEventAction,
selectEvent,
selectEventsActionState,
startEventAction,
commitEventAction,
updateEventAction,
} from '../../../+state/events';
import { keepEventLoaded } from '../../../+state/events/events.utils';
import { mapSelectors } from '../../../+state/maps';
Expand All @@ -44,8 +49,13 @@ import { EventTimeslotDialogComponent } from '../event-timeslot-dialog/event-tim
CommonModule,
EventFormComponent,
EventTimeslotDialogComponent,
FormsModule,
InputGroupAddonModule,
InputGroupModule,
InputTextModule,
InterpolatePipe,
MessagesModule,
ModifyExternalUriDialogComponent,
ProgressSpinnerModule,
RouterLink,
TooltipModule,
Expand Down Expand Up @@ -77,6 +87,8 @@ export class EventDetailsComponent {
protected readonly isStartBusy = computed(() => isActionBusy(this.startActionState()));
protected readonly isBuildBusy = computed(() => isActionBusy(this.buildActionState()));
protected readonly event = selectSignal(computed(() => selectEvent(this.eventId())));
protected readonly externalUri = computed(() => this.event()?.externalUri);
// protected readonly externalUriLoaded = computed(() => )
protected readonly timeslots = computed(() =>
[...(this.event()?.timeslots ?? [])].sort((a, b) => compareTimes(a.time, b.time))
);
Expand Down Expand Up @@ -198,7 +210,7 @@ export class EventDetailsComponent {
rejectButtonStyleClass: 'p-button-text',
accept: () => {
this._store.dispatch(
commitEventAction({
updateEventAction({
eventId: event.id,
commit: true,
})
Expand All @@ -207,6 +219,26 @@ export class EventDetailsComponent {
});
}

protected updateExternalUri() {
const event = this.event();
if (!event) return;

this._store.dispatch(
updateEventAction({
eventId: event.id,
externalUri:
this.externalUri() ?? undefined,
})
);
}

protected openExternalUri() {
const url = this.externalUri();
if (url) {
window.location.href = url;
}
}

protected buildInstances() {
this._store.dispatch(buildEventInstancesAction({ eventId: this.eventId() }));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<p-dialog
[visible]="visible()"
(visibleChange)="visible.set($event)"
[modal]="true"
[header]="translations.events_facebookLink()"
>
<p-inputGroup>
<input
#inputElement
class="w-full max-w-[350px]"
type="text"
pInputText
autocomplete="off"
[ngModel]="externalUri()"
(ngModelChange)="externalUri.set($event)"
/>
<button pButton icon="i-[mdi--backspace]" (click)="clearExternalUri()"></button>
</p-inputGroup>

<ng-template pTemplate="footer">
<p-button [text]="true" [label]="translations.shared_cancel()" (onClick)="visible.set(false)" />
<p-button [label]="translations.shared_save()" (onClick)="updateExternalUri()" />
</ng-template>
</p-dialog>
Loading
Loading