Fix/clean errors (#191)

* clean dev errors

* add check command

* yarn -> npm in travis

* fix all warnings

* fix base test

* 💄
This commit is contained in:
Lachlan Kermode
2021-01-17 18:16:28 +13:00
committed by GitHub
parent 1f20fd68ec
commit 1bbcd57e5e
35 changed files with 229 additions and 158 deletions

View File

@@ -5,11 +5,10 @@ cache:
directories:
- node_modules
before_script:
- npm install -g yarn
- cp example.config.js config.js
install:
- yarn
- npm install
script:
- yarn lint
- yarn build
- yarn test
- npm run lint
- npm run build
- npm run test

View File

@@ -11,7 +11,7 @@
"test": "node scripts/test.js --silent",
"test:ava": "NODE_ENV=production ava --verbose",
"test-watch": "ava --watch",
"lint": "echo 'This is a placeholder for Travis'",
"lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"lint:fix": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\""
},
"dependencies": {

View File

@@ -1,4 +1,3 @@
/* global fetch, alert */
import { urlFromEnv } from "../common/utilities";
// TODO: relegate these URLs entirely to environment variables

View File

@@ -5,9 +5,11 @@ export const colors = {
white: "#fff",
};
export default {
const exports = {
fallbackEventColor: colors.fa_red,
darkBackground: colors.black,
primaryHighlight: colors.fa_red,
secondaryHighlight: colors.white,
};
export default exports;

View File

@@ -380,6 +380,7 @@ export function getFilterIdxFromColorSet(filter, coloringSet) {
coloringSet.map((set, idx) => {
const foundIdx = set.indexOf(filter);
if (foundIdx !== -1) filterIdx = idx;
return null;
});
return filterIdx;
}

View File

@@ -2,7 +2,7 @@ import React from "react";
import Popup from "./presentational/Popup";
import copy from "../common/data/copy.json";
export default ({ isOpen, onClose, language, styles }) => (
const Infopopup = ({ isOpen, onClose, language, styles }) => (
<Popup
title={copy[language].legend.default.header}
content={copy[language].legend.default.intro}
@@ -11,3 +11,5 @@ export default ({ isOpen, onClose, language, styles }) => (
styles={styles}
/>
);
export default Infopopup;

View File

@@ -1,4 +1,3 @@
/* global alert, Event */
import React from "react";
import { bindActionCreators } from "redux";
@@ -11,7 +10,6 @@ import LoadingOverlay from "./Overlay/Loading";
import Map from "./Map.jsx";
import Toolbar from "./Toolbar/Layout";
import CardStack from "./CardStack.jsx";
// import {CardStack} from '@forensic-architecture/design-system'
import NarrativeControls from "./presentational/Narrative/Controls.js";
import InfoPopup from "./InfoPopup.jsx";
import Popup from "./presentational/Popup";

View File

@@ -1,4 +1,4 @@
/* global L, Event */
/* global L */
import React from "react";
import { Portal } from "react-portal";
import Supercluster from "supercluster";

View File

@@ -16,11 +16,11 @@ export default class Notification extends React.Component {
if (!items) return "";
return (
<div>
{items.map((item) => {
{items.map((item, idx) => {
if (item.error) {
return <p>{item.error.message}</p>;
return <p key={idx}>{item.error.message}</p>;
}
return "";
return null;
})}
</div>
);
@@ -47,11 +47,12 @@ export default class Notification extends React.Component {
if (notificationsToRender.length > 0) {
return (
<div className="notification-wrapper">
{this.props.notifications.map((notification) => {
{this.props.notifications.map((notification, idx) => {
return (
<div
className="notification"
onClick={() => this.toggleDetails()}
key={idx}
>
<button
onClick={this.props.onToggle}

View File

@@ -5,7 +5,7 @@ import Md from "./Md";
import Spinner from "../presentational/Spinner";
import NoSource from "../presentational/NoSource";
export default ({ media, viewIdx, translations, switchLanguage, langIdx }) => {
const Content = ({ media, viewIdx, translations, switchLanguage, langIdx }) => {
const el = document.querySelector(".source-media-gallery");
const shiftW = el ? el.getBoundingClientRect().width : 0;
@@ -71,7 +71,7 @@ export default ({ media, viewIdx, translations, switchLanguage, langIdx }) => {
</div>
);
case "Document":
return <iframe className="source-document" src={path} />;
return <iframe title={path} className="source-document" src={path} />;
default:
return (
<NoSource
@@ -92,3 +92,5 @@ export default ({ media, viewIdx, translations, switchLanguage, langIdx }) => {
</div>
);
};
export default Content;

View File

@@ -1,6 +1,6 @@
import React from "react";
export default ({ viewIdx, paths, onShiftHandler }) => {
const OverlayControls = ({ viewIdx, paths, onShiftHandler }) => {
const backArrow =
viewIdx !== 0 ? (
<div className="back" onClick={() => onShiftHandler(-1)}>
@@ -28,3 +28,5 @@ export default ({ viewIdx, paths, onShiftHandler }) => {
}
return <div className="media-gallery-controls" />;
};
export default OverlayControls;

View File

@@ -1,4 +1,3 @@
/* global fetch */
import React from "react";
import PropTypes from "prop-types";
import marked from "marked";

View File

@@ -108,7 +108,7 @@ class SourceOverlay extends React.Component {
{url ? (
<span>
<i className="material-icons left">link</i>
<a href={url} target="_blank">
<a href={url} target="_blank" rel="noreferrer">
Link to original URL
</a>
</span>

View File

@@ -49,7 +49,7 @@ class Search extends React.Component {
return (
<div
class={
className={
"search-outer-container" +
(this.props.narrative ? " narrative-mode " : "")
}
@@ -58,11 +58,13 @@ class Search extends React.Component {
<i className="material-icons">search</i>
</div>
<div
class={"search-bar-overlay" + (this.state.isFolded ? " folded" : "")}
className={
"search-bar-overlay" + (this.state.isFolded ? " folded" : "")
}
>
<div class="search-input-container">
<div className="search-input-container">
<input
class="search-bar-input"
className="search-bar-input"
onChange={this.updateSearchQuery}
type="text"
/>
@@ -74,7 +76,7 @@ class Search extends React.Component {
close
</i>
</div>
<div class="search-results">
<div className="search-results">
{searchResults.map((result) => {
return (
<SearchRow

View File

@@ -1,14 +1,14 @@
import React, { useState } from "react";
export default ({ showing, onClickHandler, timelineDims }) => {
if (!showing) {
return null;
}
const StateOptions = ({ showing, onClickHandler, timelineDims }) => {
const [checked, setChecked] = useState(false);
const handleCheck = () => setChecked(!checked);
const onNarrativise = () => onClickHandler(checked);
if (!showing) {
return null;
}
return (
<div className="stateoptions-panel" style={{ bottom: timelineDims.height }}>
<div>
@@ -26,3 +26,5 @@ export default ({ showing, onClickHandler, timelineDims }) => {
</div>
);
};
export default StateOptions;

View File

@@ -1,9 +1,9 @@
import React from "react";
export default ({ showing, children }) => {
return (
const StaticPage = ({ showing, children }) => (
<div className={`cover-container ${showing ? "showing" : ""}`}>
{children}
</div>
);
};
export default StaticPage;

View File

@@ -158,10 +158,14 @@ class TemplateCover extends React.Component {
className="cover-logo-container"
href="https://forensic-architecture.org"
>
<img className="cover-logo" src={falogo} />
<img
className="cover-logo"
src={falogo}
alt="Forensic Architecture logo"
/>
</a>
<a className="cover-logo-container" href="https://bellingcat.com">
<img className="cover-logo" src={bcatlogo} />
<img className="cover-logo" src={bcatlogo} alt="Bellingcat logo" />
</a>
</div>
<div className="cover-content">

View File

@@ -38,7 +38,7 @@ class TimelineCategories extends React.Component {
return (
<>
<g
class="tick"
className="tick"
style={{ strokeWidth }}
opacity="0.5"
transform={`translate(0,${this.props.getCategoryY(cat)})`}
@@ -46,7 +46,7 @@ class TimelineCategories extends React.Component {
<line x1={dims.marginLeft} x2={dims.width - dims.width_controls} />
</g>
<g
class="tick"
className="tick"
opacity="1"
transform={`translate(0,${this.props.getCategoryY(cat)})`}
>
@@ -66,11 +66,11 @@ class TimelineCategories extends React.Component {
: this.renderCategory(fallbackLabel, 0);
return (
<g class="yAxis">
<g className="yAxis">
{renderedCategories}
<rect
ref={this.grabRef}
class="drag-grabber"
className="drag-grabber"
x={dims.marginLeft}
y={dims.marginTop}
width={dims.width - dims.marginLeft - dims.width_controls}

View File

@@ -6,7 +6,8 @@ import InfoIcon from "../presentational/Icons/Info";
function BottomActions(props) {
function renderToggles() {
return [
return (
<>
<div className="bottom-action-block">
{props.features.USE_SITES ? (
<SitesIcon
@@ -14,19 +15,23 @@ function BottomActions(props) {
onClickHandler={props.sites.toggle}
/>
) : null}
</div>,
</div>
,
<div className="botttom-action-block">
<InfoIcon
isActive={props.info.enabled}
onClickHandler={props.info.toggle}
/>
</div>,
</div>
,
<div className="botttom-action-block">
{props.features.USE_COVER ? (
<CoverIcon onClickHandler={props.cover.toggle} />
) : null}
</div>,
];
</div>
,
</>
);
}
return <div className="bottom-actions">{renderToggles()}</div>;

View File

@@ -3,7 +3,7 @@ import marked from "marked";
import Checkbox from "../presentational/Checkbox";
import copy from "../../common/data/copy.json";
export default ({
const CategoriesListPanel = ({
categories,
activeCategories,
onCategoryFilter,
@@ -45,3 +45,5 @@ export default ({
</div>
);
};
export default CategoriesListPanel;

View File

@@ -1,6 +1,6 @@
import React from "react";
export default ({ label, isActive, onClickCheckbox, color }) => {
const Checkbox = ({ label, isActive, onClickCheckbox, color }) => {
const styles = {
background: isActive ? color : "none",
border: `1px solid ${color}`,
@@ -15,3 +15,5 @@ export default ({ label, isActive, onClickCheckbox, color }) => {
</div>
);
};
export default Checkbox;

View File

@@ -8,7 +8,7 @@ const CoverIcon = ({ isActive, isDisabled, onClickHandler }) => {
return (
<button className={classes} onClick={onClickHandler}>
<i class="material-icons">info</i>
<i className="material-icons">info</i>
</button>
);
};

View File

@@ -62,6 +62,7 @@ function Cluster({
if (!isLatitude(latitude) || !isLongitude(longitude)) return null;
return (
<svg>
<g
className="cluster-event"
transform={`translate(${x}, ${y})`}
@@ -71,7 +72,10 @@ function Cluster({
>
<ColoredMarkers
radius={size}
colorPercentMap={zipColorsToPercentages(filterColors, colorPercentages)}
colorPercentMap={zipColorsToPercentages(
filterColors,
colorPercentages
)}
styles={{
...styles,
}}
@@ -79,6 +83,7 @@ function Cluster({
/>
{hovered ? renderHover(cluster) : null}
</g>
</svg>
);
}
@@ -125,6 +130,7 @@ function ClusterEvents({
return (
<Portal node={svg}>
<svg>
<g className="cluster-locations">
{isRadial ? <DefsClusters /> : null}
{clusters.map((c) => {
@@ -149,6 +155,7 @@ function ClusterEvents({
);
})}
</g>
</svg>
</Portal>
);
}

View File

@@ -1,6 +1,7 @@
import React from "react";
const MapDefsMarkers = () => (
<svg>
<defs>
<marker
id="arrow"
@@ -22,9 +23,13 @@ const MapDefsMarkers = () => (
markerHeight="6"
orient="auto"
>
<path d="M0,3v-3l6,3l-6,3z" style={{ fill: "black", fillOpacity: 0.2 }} />
<path
d="M0,3v-3l6,3l-6,3z"
style={{ fill: "black", fillOpacity: 0.2 }}
/>
</marker>
</defs>
</svg>
);
export default MapDefsMarkers;

View File

@@ -171,6 +171,7 @@ function MapEvents({
}, false);
return (
<svg>
<g
className={`location-event ${narrative ? "no-hover" : ""}`}
transform={`translate(${x}, ${y})`}
@@ -185,12 +186,15 @@ function MapEvents({
{extraRender ? extraRender() : null}
{isSelected ? null : renderBorder()}
</g>
</svg>
);
}
return (
<Portal node={svg}>
<svg>
<g className="event-locations">{locations.map(renderLocation)}</g>
</svg>
</Portal>
);
}

View File

@@ -1,6 +1,6 @@
import React from "react";
export default ({ isDisabled, direction, onClickHandler }) => {
const Adjust = ({ isDisabled, direction, onClickHandler }) => {
return (
<div
className={`narrative-adjust ${direction}`}
@@ -12,3 +12,5 @@ export default ({ isDisabled, direction, onClickHandler }) => {
</div>
);
};
export default Adjust;

View File

@@ -1,6 +1,6 @@
import React from "react";
export default ({ onClickHandler, closeMsg }) => {
const Close = ({ onClickHandler, closeMsg }) => {
return (
<div className="narrative-close" onClick={onClickHandler}>
<button className="side-menu-burg is-active">
@@ -10,3 +10,5 @@ export default ({ onClickHandler, closeMsg }) => {
</div>
);
};
export default Close;

View File

@@ -3,7 +3,7 @@ import Card from "./Card";
import Adjust from "./Adjust";
import Close from "./Close";
export default ({ narrative, methods }) => {
const NarrativeControls = ({ narrative, methods }) => {
if (!narrative) return null;
const { current, steps } = narrative;
@@ -30,3 +30,5 @@ export default ({ narrative, methods }) => {
</>
);
};
export default NarrativeControls;

View File

@@ -3,7 +3,7 @@ import marked from "marked";
const fontSize = window.innerWidth > 1000 ? 14 : 18;
export default ({
const Popup = ({
content = [],
styles = {},
isOpen = true,
@@ -29,10 +29,12 @@ export default ({
</button>
<h2>{title}</h2>
</div>
{content.map((t) => (
<div dangerouslySetInnerHTML={{ __html: marked(t) }} />
{content.map((t, idx) => (
<div key={idx} dangerouslySetInnerHTML={{ __html: marked(t) }} />
))}
{children}
</div>
</div>
);
export default Popup;

View File

@@ -1,6 +1,6 @@
import React from "react";
export default ({
const DatetimeBar = ({
highlights,
events,
x,
@@ -41,3 +41,5 @@ export default ({
</>
);
};
export default DatetimeBar;

View File

@@ -1,6 +1,14 @@
import React from "react";
export default ({ x, y, r, transform, onSelect, styleProps, extraRender }) => {
const DatetimeSquare = ({
x,
y,
r,
transform,
onSelect,
styleProps,
extraRender,
}) => {
return (
<rect
onClick={onSelect}
@@ -14,3 +22,5 @@ export default ({ x, y, r, transform, onSelect, styleProps, extraRender }) => {
/>
);
};
export default DatetimeSquare;

View File

@@ -1,6 +1,14 @@
import React from "react";
export default ({ x, y, r, transform, onSelect, styleProps, extraRender }) => {
const DatetimeStar = ({
x,
y,
r,
transform,
onSelect,
styleProps,
extraRender,
}) => {
const s = (r * 2) / 3;
return (
<polygon
@@ -15,3 +23,5 @@ export default ({ x, y, r, transform, onSelect, styleProps, extraRender }) => {
/>
);
};
export default DatetimeStar;

View File

@@ -1,6 +1,6 @@
import React from "react";
export default ({
const Project = ({
offset,
id,
start,
@@ -26,3 +26,5 @@ export default ({
/>
);
};
export default Project;

View File

@@ -28,6 +28,7 @@ const TimelineZoomControls = ({ extent, zoomLevels, dims, onApplyZoom }) => {
x="60"
y={idx * 15 + 20}
onClick={() => onApplyZoom(zoom)}
key={idx}
>
{zoom.label}
</text>

View File

@@ -12,5 +12,5 @@ it("renders an option to view categories", () => {
<App />
</Provider>
);
expect(screen.getByText("Categories")).toBeInTheDocument();
expect(screen.getByText("Filters")).toBeInTheDocument();
});