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(run): Add Lumi Run #1504

Merged
merged 25 commits into from
May 14, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5bf5152
fix(sentry): add new DSN
JPSchellenberg Apr 12, 2021
debd04b
feat(run): WIP
JPSchellenberg Apr 13, 2021
05ba2bb
feat(run): wip
JPSchellenberg Apr 15, 2021
6e76dd0
Merge branch 'master' into feat/run
JPSchellenberg Apr 17, 2021
6301afa
feat(run): WIP
JPSchellenberg Apr 18, 2021
9f36522
Merge master into feat/run
JPSchellenberg Apr 20, 2021
c1408f0
fix(settings): missing icon
JPSchellenberg Apr 21, 2021
86d5371
Merge branch 'master' into feat/run
JPSchellenberg Apr 21, 2021
1ad47fe
feat(run): allow h5p to be uploaded from the editor
JPSchellenberg Apr 21, 2021
763cdbc
feat(run): wip
JPSchellenberg Apr 26, 2021
d67487e
fix(run-consent): api
JPSchellenberg Apr 26, 2021
fa9500f
feat(run): wip
JPSchellenberg Apr 28, 2021
e0fb037
Merge branch 'master' into feat/run
JPSchellenberg Apr 28, 2021
7c8f355
feat(run): add run
JPSchellenberg Apr 29, 2021
4774fac
test(lint): make linter happy
JPSchellenberg Apr 29, 2021
78d061f
fix(run): fix erros
JPSchellenberg May 5, 2021
ab2ab65
Merge branch 'master' into feat/run
JPSchellenberg May 5, 2021
e92dbb3
fix(run): use new api
JPSchellenberg May 6, 2021
96acf00
feat(auth): add logout button
JPSchellenberg May 8, 2021
22324a6
feat(run): add delete confirmation dialog
JPSchellenberg May 8, 2021
cd91dee
refactor(components): add bit & make components reusable
JPSchellenberg May 9, 2021
e2fe014
fix(run): Setup Dialog now points to correct terms of use url
JPSchellenberg May 11, 2021
60babbf
ci(build): add build workflow
JPSchellenberg May 11, 2021
86c7a66
fix(link): add noreferrer to link
JPSchellenberg May 11, 2021
2a4a0d6
Merge branch 'master' into feat/run
JPSchellenberg May 14, 2021
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
20 changes: 20 additions & 0 deletions client/src/helpers/LumiError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export type ErrorCodes = 'user-abort' | 'h5p-not-found';

export default class LumiError {
constructor(
code: ErrorCodes,
message: string,
status: number = 500,
error?: Error
) {
this.code = code;
this.message = message;
this.status = status;
this.error = new Error(message);
}

public code: ErrorCodes;
public error: Error;
public message: string;
public status: number;
}
6 changes: 3 additions & 3 deletions client/src/state/H5PEditor/H5PEditorActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,21 +461,21 @@ export function save(
Sentry.captureException(error);
}

dispatch({
return dispatch({
// tslint:disable-next-line: object-shorthand-properties-first
payload: { id: data.contentId, ...response.body },
type: H5PEDITOR_SAVE_SUCCESS
});
} catch (error) {
if (error.status === 499) {
dispatch({
return dispatch({
payload: {},
type: H5PEDITOR_SAVE_CANCEL
});
} else {
Sentry.captureException(error);

dispatch({
return dispatch({
error,
payload: { path },
type: H5PEDITOR_SAVE_ERROR
Expand Down
31 changes: 30 additions & 1 deletion client/src/state/Notifications/NotificationsActions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import {
CLOSE_SNACKBAR,
ENQUEUE_SNACKBAR,
IShowErrorDialog,
NotificationActionTypes,
NotificationTypes,
REMOVE_SNACKBAR
REMOVE_SNACKBAR,
SHOW_ERROR_DIALOG,
ErrorTypes,
ICloseErrorDialog,
CLOSE_ERROR_DIALOG
} from './NotificationsTypes';

import shortid from 'shortid';
Expand All @@ -24,6 +29,30 @@ export function notify(
};
}

export function showErrorDialog(
code: ErrorTypes,
message: string,
redirect?: string
): IShowErrorDialog {
return {
payload: {
error: {
code,
message,
redirect
}
},
type: SHOW_ERROR_DIALOG
};
}

export function closeErrorDialog(): ICloseErrorDialog {
return {
payload: {},
type: CLOSE_ERROR_DIALOG
};
}

export function closeSnackbar(key: string): NotificationActionTypes {
return {
key,
Expand Down
33 changes: 31 additions & 2 deletions client/src/state/Notifications/NotificationsReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {
REMOVE_SNACKBAR,
INotifyAction,
ICloseSnackbar,
IRemoveSnackbar
IRemoveSnackbar,
SHOW_ERROR_DIALOG,
IShowErrorDialog,
ICloseErrorDialog,
CLOSE_ERROR_DIALOG
} from './NotificationsTypes';

import {
Expand Down Expand Up @@ -36,7 +40,12 @@ import i18next from 'i18next';
import shortid from 'shortid';

export const initialState: INotificationsState = {
notifications: []
notifications: [],
showErrorDialog: false,
error: {
code: 'init',
message: ''
}
};

export default function notificationsReducer(
Expand All @@ -53,9 +62,29 @@ export default function notificationsReducer(
| IH5PImportErrorAction
| IAnalyticsImportSuccessAction
| IAnalyticsImportErrorAction
| IShowErrorDialog
| ICloseErrorDialog
): INotificationsState {
try {
switch (action.type) {
case SHOW_ERROR_DIALOG:
return {
...state,
showErrorDialog: true,
error: action.payload.error
};

case CLOSE_ERROR_DIALOG:
return {
...state,
error: {
code: 'init',
message: '',
redirect: undefined
},
showErrorDialog: false
};

case ANALYTICS_IMPORT_ERROR:
return {
...state,
Expand Down
31 changes: 30 additions & 1 deletion client/src/state/Notifications/NotificationsTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ export const ENQUEUE_SNACKBAR = 'ENQUEUE_SNACKBAR';
export const CLOSE_SNACKBAR = 'CLOSE_SNACKBAR';
export const REMOVE_SNACKBAR = 'REMOVE_SNACKBAR';

export const SHOW_ERROR_DIALOG = 'SHOW_ERROR_DIALOG';
export const CLOSE_ERROR_DIALOG = 'CLOSE_ERROR_DIALOG';

export type ErrorTypes = 'init' | 'econnrefused' | 'errors.codes.econnrefused';

export interface INotification {
dismissed?: boolean;
key: string;
Expand All @@ -25,7 +30,30 @@ export interface IState {

export interface INotificationsState {
notifications: INotification[];
showErrorDialog: boolean;
error: {
code: ErrorTypes;
message: string;
redirect?: string;
};
}

export interface IShowErrorDialog {
payload: {
error: {
code: ErrorTypes;
message: string;
redirect?: string;
};
};
type: typeof SHOW_ERROR_DIALOG;
}

export interface ICloseErrorDialog {
payload: {};
type: typeof CLOSE_ERROR_DIALOG;
}

export interface INotifyAction {
notification: INotification;
type: typeof ENQUEUE_SNACKBAR;
Expand All @@ -45,4 +73,5 @@ export interface IRemoveSnackbar {
export type NotificationActionTypes =
| INotifyAction
| ICloseSnackbar
| IRemoveSnackbar;
| IRemoveSnackbar
| IShowErrorDialog;
18 changes: 10 additions & 8 deletions client/src/state/Run/RunAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import superagent from 'superagent';
import { IRunState } from './RunTypes';

export async function getRuns(): Promise<IRunState> {
return (await superagent.get(`/api/v1/run`)).body;
const body = (await superagent.get(`/api/run/api/v1/run`)).body;
JPSchellenberg marked this conversation as resolved.
Show resolved Hide resolved

if (body === null) {
throw new Error('invalid body');
}
return body;
}

export async function upload(): Promise<IRunState> {
return (await superagent.post(`/api/v1/run/upload`)).body;
export async function upload(contentId?: string): Promise<IRunState> {
return (await superagent.post(`/api/run`).send({ contentId })).body;
JPSchellenberg marked this conversation as resolved.
Show resolved Hide resolved
}

export async function deleteFromRun(
id: string,
secret: string
): Promise<superagent.Response> {
return await superagent.delete(`/api/v1/run/${id}?secret=${secret}`);
export async function deleteFromRun(id: string): Promise<superagent.Response> {
return await superagent.delete(`/api/run/api/v1/run/${id}`);
}
79 changes: 65 additions & 14 deletions client/src/state/Run/RunActions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as Sentry from '@sentry/browser';
import i18next from 'i18next';

import {
RUN_GET_RUNS_REQUEST,
Expand All @@ -10,11 +11,17 @@ import {
RUN_DELETE_REQUEST,
RUN_DELETE_SUCCESS,
RUN_DELETE_ERROR,
RUN_NOT_AUTHORIZED,
IRunUpdateState,
RUN_UPDATE_STATE,
IRunState
} from './RunTypes';

import store from '../../state';

import { updateContentOnServer } from '../H5PEditor/H5PEditorActions';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"On" should be "To"

import { notify, showErrorDialog } from '../Notifications/NotificationsActions';

import * as API from './RunAPI';

export function getRuns(): any {
Expand All @@ -26,16 +33,22 @@ export function getRuns(): any {
});

try {
const settings = await API.getRuns();
const runs = await API.getRuns();

dispatch({
payload: settings,
return dispatch({
payload: runs,
type: RUN_GET_RUNS_SUCCESS
});
} catch (error) {
Sentry.captureException(error);
if (error.status === 401) {
return dispatch({
payload: {},
type: RUN_NOT_AUTHORIZED
});
}

dispatch({
Sentry.captureException(error);
return dispatch({
payload: { error },
type: RUN_GET_RUNS_ERROR
});
Expand All @@ -46,36 +59,68 @@ export function getRuns(): any {
};
}

export function upload(options?: { includeReporter?: boolean; path?: string }) {
export function upload(options?: { path?: string; contentId?: string }) {
return async (dispatch: any) => {
try {
const settings = store.getState().settings;
if (!settings.email || !settings.token) {
return dispatch(updateState({ showSetupDialog: true }));
}

dispatch(updateState({ showUploadDialog: true }));
let contentId = options?.contentId;

if (!options?.path && contentId) {
const data = await dispatch(updateContentOnServer());
contentId = data.contentId;
}

dispatch({
payload: {},
type: RUN_UPLOAD_REQUEST
});

try {
const run = await API.upload();
const run = await API.upload(contentId);

dispatch({
payload: run,
type: RUN_UPLOAD_SUCCESS
});
dispatch(
notify(
i18next.t('run.notifications.upload.success'),
'success'
)
);
dispatch(getRuns());
} catch (error) {
Sentry.captureException(error);
if (error.status !== 499) {
Sentry.captureException(error);

dispatch({
payload: { error },
type: RUN_UPLOAD_ERROR
});
dispatch(
showErrorDialog(
'errors.codes.econnrefused',
'run.dialog.error.description'
)
);

dispatch({
payload: { error },
type: RUN_UPLOAD_ERROR
});
}

// user canceled electrons openfile dialog
dispatch(updateState({ showUploadDialog: false }));
}
} catch (error) {
Sentry.captureException(error);
}
};
}

export function deleteFromRun(id: string, secret: string): any {
export function deleteFromRun(id: string): any {
return async (dispatch: any) => {
try {
dispatch({
Expand All @@ -84,13 +129,19 @@ export function deleteFromRun(id: string, secret: string): any {
});

try {
const run = await API.deleteFromRun(id, secret);
const run = await API.deleteFromRun(id);

dispatch({
payload: run,
type: RUN_DELETE_SUCCESS
});
dispatch(getRuns());
dispatch(
notify(
i18next.t('run.notifications.delete.success', { id }),
'success'
)
);
} catch (error) {
Sentry.captureException(error);

Expand Down
Loading