Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.
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
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react';
import React, { ReactNode, StatelessComponent } from 'react';
import getDisplayName from './getDisplayName';

const { Consumer, Provider } = React.createContext();
const { Consumer, Provider } = React.createContext<string | undefined>(
undefined,
);

const AuthorizationProvider = ({ authorization, children }) => (
const AuthorizationProvider: StatelessComponent<{
authorization: string | undefined;
children: ReactNode;
}> = ({ authorization, children }) => (
<Provider value={authorization}>{children}</Provider>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { SvgIcon } from '@material-ui/core';
import { SvgIconProps } from '@material-ui/core/SvgIcon';
import React, { ComponentType } from 'react';
/* eslint-disable max-len */
const SqlStreamStore = props => (
const SqlStreamStore: ComponentType<SvgIconProps> = props => (
<SvgIcon {...props} viewBox={'0 0 448.687 627.153'}>
<g transform={'translate(-88.5 -116.776)'}>
<ellipse
Expand Down
19 changes: 6 additions & 13 deletions src/components/Loading.js → src/components/Loading.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import React from 'react';
import { LinearProgress, Modal } from '@material-ui/core';
import React from 'react';

const variants = {
true: 'indeterminate',
false: 'determinate',
};

const values = {
true: undefined,
false: 0,
};

const Loading = ({ open }) => (
const Loading = ({ open }: { open: boolean }) => (
<div>
<LinearProgress variant={variants[open]} value={values[open]} />
<LinearProgress
variant={open ? 'indeterminate' : 'determinate'}
value={open ? undefined : 0}
/>
<Modal disableBackdropClick disableEscapeKeyDown open={open}>
<span />
</Modal>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import React from 'react';
import React, { ReactNode, StatelessComponent } from 'react';
import { NavigationHandler } from '../types';
import getDisplayName from './getDisplayName';
const { Consumer, Provider } = React.createContext();

const NavigationProvider = ({ onNavigate, children }) => (
const defaultNavigationHandler: NavigationHandler = (link, authorization) => {
return;
};

const { Consumer, Provider } = React.createContext<NavigationHandler>(
defaultNavigationHandler,
);

const NavigationProvider: StatelessComponent<{
onNavigate: NavigationHandler;
children: ReactNode;
}> = ({ onNavigate, children }) => (
<Provider value={onNavigate}>{children}</Provider>
);

Expand Down
103 changes: 60 additions & 43 deletions src/components/Notifications.js → src/components/Notifications.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
import React, { createElement } from 'react';
import { Observable as obs } from 'rxjs';
import {
IconButton,
Snackbar,
SnackbarContent,
WithStyles,
withStyles,
} from '@material-ui/core';
import { Close, CheckCircle, Warning, Error, Info } from '../components/Icons';
import { green, amber, blue, red } from '@material-ui/core/colors';
import { amber, blue, green, red } from '@material-ui/core/colors';
import classNames from 'classnames';
import React, {ComponentType, createElement, ReactNode, StatelessComponent} from 'react';
import { Observable as obs } from 'rxjs';
import uuid from 'uuid';
import { actions } from '../stream-store';
import { CheckCircle, Close, Error, Info, Warning } from '../components/Icons';
import { connect, createAction, createState } from '../reactive';
import { actions } from '../stream-store';
import { HttpProblemDetailsResponse, HttpResponse } from '../types';

const iconsByVariant = {
success: CheckCircle,
warning: Warning,
error: Error,
info: Info,
success: CheckCircle,
warning: Warning,
};

const formatTitle = ({ status, statusText }) => `${status} ${statusText}`;
const formatTitle = ({
status,
statusText,
}: {
status: number;
statusText: string;
}) => `${status} ${statusText}`;

const formatSubheader = ({ title, type }) =>
const formatSubheader = ({ title, type }: { title: string; type: string }) =>
title ? `${title} (${type})` : null;

const formatContent = ({ detail }) =>
detail
const formatContent = ({ detail }: { detail?: string }): ReactNode[] =>
!!detail
? detail
.split(/\r|\n/)
.filter(x => x.length)
Expand All @@ -38,28 +46,28 @@ const formatContent = ({ detail }) =>
],
[],
)
: null;
: [];

const responses$ = obs.merge(
...Object.keys(actions).map(verb => actions[verb].response),
);

const clientError$ = responses$
.filter(({ status }) => status >= 400 && status < 500)
.map(({ body, ...response }) => ({
variant: 'warning',
title: formatTitle(response),
subheader: formatSubheader(body),
.map(({ body, ...response }: HttpProblemDetailsResponse) => ({
content: formatContent(body),
subheader: formatSubheader(body),
title: formatTitle(response),
variant: 'warning',
}));

const serverError$ = responses$
.filter(({ status }) => status >= 500)
.map(({ body, ...response }) => ({
variant: 'error',
title: formatTitle(response),
subheader: formatSubheader(body),
.map(({ body, ...response }: HttpProblemDetailsResponse) => ({
content: formatContent(body),
subheader: formatSubheader(body),
title: formatTitle(response),
variant: 'error',
}));

const unsafe = Object.keys(actions)
Expand All @@ -69,10 +77,10 @@ const unsafe = Object.keys(actions)
const success$ = obs
.merge(...unsafe)
.filter(({ status }) => status < 400)
.map(response => ({
variant: 'success',
title: formatTitle(response),
.map((response: HttpResponse) => ({
autoHideDuration: 2000,
title: formatTitle(response),
variant: 'success',
}));

const dismiss = createAction();
Expand Down Expand Up @@ -102,48 +110,58 @@ const state$ = createState(
);

const styles = theme => ({
success: {
backgroundColor: green[600],
},
error: {
backgroundColor: red[500],
},
info: {
backgroundColor: blue[500],
},
warning: {
backgroundColor: amber[700],
},
icon: {
fontSize: 20,
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing.unit,
opacity: 0.9,
},
info: {
backgroundColor: blue[500],
},
message: {
display: 'flex',
alignItems: 'center',
display: 'flex',
},
success: {
backgroundColor: green[600],
},
warning: {
backgroundColor: amber[700],
},
});

const Notification = withStyles(styles)(
interface NotificationProps {
autoHideDuration: number | undefined;
className: string;
content: ReactNode;
messageId: string;
subheader: string;
title: string;
variant: string;
}

const Notification: ComponentType<NotificationProps> = withStyles(styles)(
({
classes,
autoHideDuration,
className,
classes,
content,
messageId,
title,
subheader,
content,
title,
variant,
autoHideDuration,
...other
}) => (
}: NotificationProps & WithStyles<typeof styles>) => (
<Snackbar
open
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
vertical: 'bottom',
}}
autoHideDuration={autoHideDuration}
>
Expand All @@ -166,7 +184,6 @@ const Notification = withStyles(styles)(
<IconButton
key="close"
color="inherit"
className={classes.close}
onClick={() => dismiss.next(messageId)}
>
<Close className={classes.icon} />
Expand All @@ -178,7 +195,7 @@ const Notification = withStyles(styles)(
),
);

const Notifications = ({ notifications }) => (
const Notifications: StatelessComponent<{ notifications: NotificationProps[] }> = ({ notifications }) => (
<div>
{notifications.map(notification => (
<Notification key={notification.messageId} {...notification} />
Expand Down
25 changes: 15 additions & 10 deletions src/components/RelIcon.js → src/components/RelIcon.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { createElement } from 'react';
import { SvgIconProps } from '@material-ui/core/SvgIcon';
import { createElement, ReactElement } from 'react';
import { rels } from '../stream-store';
import {
Publish,
Settings,
ChevronLeft,
ChevronRight,
DeleteForever,
FirstPage,
Help,
LastPage,
ChevronLeft,
ChevronRight,
RssFeed,
List,
Publish,
Refresh,
RssFeed,
Search,
Settings,
SqlStreamStore,
List,
Help,
} from './Icons';
import { rels } from '../stream-store';

const fontIconByRel = {
[rels.first]: FirstPage,
Expand All @@ -32,7 +33,11 @@ const fontIconByRel = {
[rels.curies]: Help,
};

const RelIcon = ({ rel, ...props }) =>
interface RelIconProps extends SvgIconProps {
rel: string;
}

const RelIcon = ({ rel, ...props }: RelIconProps): ReactElement<SvgIconProps> =>
createElement(fontIconByRel[rel] || SqlStreamStore, props);

export default RelIcon;
39 changes: 0 additions & 39 deletions src/components/StreamBrowser.js

This file was deleted.

Loading