Skip to content

Commit 54662c5

Browse files
committed
Make replay tool offline ready
- Show almost every steps k - Use react-icons instead of font url - Use local mapboxgl styles - Add link to osm push
1 parent 4765fe3 commit 54662c5

File tree

24 files changed

+490
-126
lines changed

24 files changed

+490
-126
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ The environment file should define these variables:
1515

1616
```sh
1717
REACT_APP_API_SERVER_URL=http://localhost:6007/api/v1
18-
REACT_APP_MAPBOX_ACCESS_TOKEN="<insert your access token here>"
18+
REACT_APP_OSM_URL=http://localhost:6007/login/openstreetmap
19+
REACT_APP_MAPBOX_ACCESS_TOKEN="<your-access-token>"
1920
REACT_APP_OSM_LAYER_URL="<url for local osm layer (this is optional)>"
2021
```
2122

config/webpack.dev.js

+9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const gitRevisionPlugin = new GitRevisionPlugin();
2121

2222
const appBase = process.cwd();
2323
const eslintFile = path.resolve(appBase, '.eslintrc-loader.js');
24+
const nodeModulesDir = path.resolve(appBase, 'node_modules/');
2425
const appSrc = path.resolve(appBase, 'src/');
2526
const appDist = path.resolve(appBase, 'build/');
2627
const appIndexJs = path.resolve(appBase, 'src/index.tsx');
@@ -148,6 +149,14 @@ module.exports = (env) => {
148149
},
149150
],
150151
},
152+
{
153+
test: /\.css$/,
154+
include: nodeModulesDir,
155+
use: [
156+
'style-loader',
157+
'css-loader',
158+
],
159+
},
151160
{
152161
test: /\.(png|jpg|gif|svg)$/,
153162
use: [

config/webpack.prod.js

+9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const gitRevisionPlugin = new GitRevisionPlugin();
2424

2525
const appBase = process.cwd();
2626
const eslintFile = path.resolve(appBase, '.eslintrc-loader.js');
27+
const nodeModulesDir = path.resolve(appBase, 'node_modules/');
2728
const appSrc = path.resolve(appBase, 'src/');
2829
const appDist = path.resolve(appBase, 'build/');
2930
const appIndexJs = path.resolve(appBase, 'src/index.tsx');
@@ -150,6 +151,14 @@ module.exports = (env) => {
150151
},
151152
],
152153
},
154+
{
155+
test: /\.css$/,
156+
include: nodeModulesDir,
157+
use: [
158+
MiniCssExtractPlugin.loader,
159+
'css-loader',
160+
],
161+
},
153162
{
154163
test: /\.(png|jpg|gif|svg)$/,
155164
use: [

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"keywords": [],
77
"author": "",
88
"license": "ISC",
9-
"sideEffects": false,
9+
"sideEffects": [
10+
"./node_modules/mapbox-gl/dist/mapbox-gl.css"
11+
],
1012
"scripts": {
1113
"start": "webpack-dev-server --mode development --config config/webpack.dev.js --env.NODE_ENV=development --history-api-fallback --config-register @babel/register",
1214
"build": "webpack --mode production --config config/webpack.prod.js --env.NODE_ENV=production --config-register @babel/register",
@@ -165,6 +167,7 @@
165167
"react-dom": "16.8.6",
166168
"react-focus-trap": "^2.7.1",
167169
"react-helmet": "^5.2.1",
170+
"react-icons": "^3.10.0",
168171
"react-loadable": "^5.5.0",
169172
"react-redux": "^7.1.0",
170173
"react-router-dom": "^5.0.1",

public/index.html

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
<!-- External resources -->
6060
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+TC:300,400,700&display=swap" rel="stylesheet">
6161
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.css" />
62-
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.1/mapbox-gl.css" rel="stylesheet" />
6362

6463
<script>
6564
if ('serviceWorker' in navigator) {

src/Root/App/Multiplexer/index.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import React from 'react';
33
import { Router } from '@reach/router';
44
import { _cs } from '@togglecorp/fujs';
55

6+
import 'mapbox-gl/dist/mapbox-gl.css';
7+
68
import Button from '#rsu/../v2/Action/Button';
79
import LoadingAnimation from '#rscv/LoadingAnimation';
810
import Message from '#rsu/../v2/View/Message';
@@ -11,7 +13,6 @@ import Navbar from '#components/Navbar';
1113
import errorBound from '#components/errorBound';
1214
import helmetify from '#components/helmetify';
1315

14-
1516
import { routeSettings } from '#constants';
1617
import styles from './styles.scss';
1718

src/components/Checkbox/index.tsx

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import React, { useMemo, useCallback } from 'react';
2+
import {
3+
RiCheckboxLine,
4+
RiCheckboxIndeterminateLine,
5+
RiCheckboxBlankLine,
6+
} from 'react-icons/ri';
7+
import {
8+
randomString,
9+
_cs,
10+
} from '@togglecorp/fujs';
11+
12+
import styles from './styles.scss';
13+
14+
interface Props {
15+
className?: string;
16+
labelClassName?: string;
17+
checkIconClassName?: string;
18+
19+
disabled?: boolean;
20+
value: boolean;
21+
onChange: (value: boolean) => void;
22+
label?: string | number;
23+
tooltip?: string;
24+
readOnly?: boolean;
25+
26+
// NOTE: if value is false and indetermiate is true, show a filled checkbox
27+
indeterminate?: boolean;
28+
}
29+
30+
const Checkbox = (props: Props) => {
31+
const {
32+
label,
33+
tooltip,
34+
className: classNameFromProps,
35+
value,
36+
disabled,
37+
readOnly,
38+
onChange,
39+
checkIconClassName,
40+
labelClassName: labelClassNameFromProps,
41+
indeterminate,
42+
...otherProps
43+
} = props;
44+
45+
const inputId = useMemo(
46+
() => randomString(16),
47+
[],
48+
);
49+
50+
const handleChange = useCallback(
51+
(e) => {
52+
const v = e.target.checked;
53+
onChange(v);
54+
},
55+
[onChange],
56+
);
57+
58+
const className = _cs(
59+
styles.checkbox,
60+
'checkbox',
61+
classNameFromProps,
62+
(value || indeterminate) && styles.checked,
63+
(value || indeterminate) && 'checked',
64+
disabled && styles.disabled,
65+
disabled && 'disabled',
66+
readOnly && styles.readOnly,
67+
readOnly && 'read-only',
68+
);
69+
70+
const iconName = _cs(
71+
styles.checkmark,
72+
'checkmark',
73+
checkIconClassName,
74+
);
75+
76+
const inputClassName = _cs(
77+
'input',
78+
styles.input,
79+
);
80+
81+
const labelClassName = _cs(
82+
'label',
83+
styles.label,
84+
labelClassNameFromProps,
85+
);
86+
87+
const Icon = (value && RiCheckboxLine)
88+
|| (indeterminate && RiCheckboxIndeterminateLine)
89+
|| RiCheckboxBlankLine;
90+
91+
return (
92+
<label
93+
htmlFor={inputId}
94+
className={className}
95+
title={tooltip}
96+
>
97+
<Icon
98+
className={iconName}
99+
/>
100+
<input
101+
id={inputId}
102+
onChange={handleChange}
103+
className={inputClassName}
104+
type="checkbox"
105+
checked={value}
106+
disabled={disabled || readOnly}
107+
{...otherProps}
108+
/>
109+
<div className={labelClassName}>
110+
{ label }
111+
</div>
112+
</label>
113+
);
114+
};
115+
116+
Checkbox.defaultProps = {
117+
disabled: false,
118+
readOnly: false,
119+
value: false,
120+
};
121+
122+
export default Checkbox;

src/components/Checkbox/styles.scss

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
.checkbox {
2+
display: flex;
3+
align-items: center;
4+
cursor: pointer;
5+
user-select: none;
6+
7+
.checkmark {
8+
margin-right: var(--spacing-extra-small);
9+
font-size: var(--font-size-large);
10+
}
11+
12+
.input {
13+
display: none;
14+
}
15+
16+
.label {
17+
color: var(--color-text);
18+
font-weight: var(--font-weight-normal);
19+
20+
&:hover {
21+
background-color: var(--color-background-accent-hint);
22+
}
23+
}
24+
25+
&.checked {
26+
.checkmark {
27+
color: var(--color-accent);
28+
}
29+
}
30+
31+
&.disabled {
32+
.checkmark {
33+
color: var(--color-text-disabled);
34+
}
35+
36+
.label {
37+
color: var(--color-text-disabled);
38+
}
39+
40+
.input {
41+
border-bottom-color: var(--color-separator);
42+
color: var(--color-text-disabled);
43+
}
44+
}
45+
46+
&.read-only {
47+
.checkmark {
48+
color: var(--color-text);
49+
}
50+
}
51+
}

src/components/Info/index.tsx

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import React from 'react';
22
import { _cs } from '@togglecorp/fujs';
3-
4-
import Icon from '#rscg/Icon';
3+
import { RiInformationLine } from 'react-icons/ri';
54

65
import styles from './styles.scss';
76

87
interface Props {
98
className?: string;
9+
title?: React.ReactNode;
1010
message?: React.ReactNode;
11-
variant?: 'danger' | 'info';
11+
variant?: 'danger' | 'info' | 'success';
1212
}
1313

1414
class Info extends React.PureComponent<Props> {
1515
public render() {
1616
const {
1717
className,
18+
title,
1819
message,
1920
variant = 'info',
2021
} = this.props;
@@ -26,19 +27,27 @@ class Info extends React.PureComponent<Props> {
2627
styles.container,
2728
variant === 'info' && styles.info,
2829
variant === 'danger' && styles.danger,
30+
variant === 'success' && styles.success,
2931
)}
3032
>
31-
<Icon
32-
className={_cs(
33-
styles.icon,
34-
variant === 'info' && styles.info,
35-
variant === 'danger' && styles.danger,
36-
)}
37-
name="infoCircle"
38-
/>
39-
<div className={styles.message}>
40-
{message}
33+
<div className={styles.title}>
34+
<RiInformationLine
35+
className={_cs(
36+
styles.icon,
37+
variant === 'info' && styles.info,
38+
variant === 'danger' && styles.danger,
39+
variant === 'success' && styles.success,
40+
)}
41+
/>
42+
<div className={styles.text}>
43+
{title}
44+
</div>
4145
</div>
46+
{message && (
47+
<div className={styles.message}>
48+
{message}
49+
</div>
50+
)}
4251
</div>
4352
);
4453
}

0 commit comments

Comments
 (0)