Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

Commit

Permalink
Typescript (#298)
Browse files Browse the repository at this point in the history
* Basic typescript

* Working typescript setup

* cant use react-components from react-components

* js type

* Do not remove sideEffects flag

* Fix linter errors

* Use shared tsconfig

* bring back typings :/

* lintfix

* Fix prettier command

* Lint all files before comit

* Remove redundant config

* Use autoreply constant

* Move enum

* update ts

* add type override

* Remove redundant type

* Fix imports after moving

* Removeunused import

* Jest ts config

* Use babel-jest to handle typescript in tests
  • Loading branch information
vincaslt authored and EpokK committed Oct 3, 2019
1 parent cafc899 commit 384f0b3
Show file tree
Hide file tree
Showing 32 changed files with 197 additions and 169 deletions.
72 changes: 40 additions & 32 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
{
"plugins": [
"react",
"react-hooks"
],
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
"parser": "@typescript-eslint/parser",
"plugins": ["react", "react-hooks", "@typescript-eslint"],
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"settings": {
"react": {
"version": "detect"
},
"import/resolver": {
"node": {
"extensions": [".js", ".ts", ".tsx"]
}
}
},
"extends": ["plugin:@typescript-eslint/recommended", "eslint:recommended", "plugin:react/recommended"],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/indent": "off",
"react/display-name": "off",
"react/prop-types": "warn",
"react-hooks/rules-of-hooks": "error",
"no-console": [
"error",
{
"allow": ["warn", "error"]
}
]
}
},
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"settings": {
"react": {
"version": "detect"
}
},
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"rules": {
"react/display-name": "off",
"react/prop-types": "warn",
"react-hooks/rules-of-hooks": "error",
"no-console": ["error", { "allow": ["warn", "error"] }]
}
}
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
presets: ['@babel/preset-env', '@babel/preset-react'],
presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
plugins: [
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-transform-runtime',
Expand Down
2 changes: 1 addition & 1 deletion components/autocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const useAutocomplete = ({
changeInputValue(multiple ? '' : label);

const itemToAdd = !item && label ? labelToItem(label) : item;
setSelectedItems((selected) => multiple ? [...selected, itemToAdd] : [itemToAdd]);
setSelectedItems((selected) => (multiple ? [...selected, itemToAdd] : [itemToAdd]));
};

const submit = (label) => select(null, label);
Expand Down
1 change: 1 addition & 0 deletions components/container/ObserverSections.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'intersection-observer';

import ObserverSection from './ObserverSection';

/** @type any */
const ObserverSections = ({ children, setActiveSection }) => {
React.Children.forEach(children, (child) => {
if (!child.props.id) throw new Error('All sections to be observed need an id');
Expand Down
1 change: 1 addition & 0 deletions components/container/SettingsTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { classnames } from 'react-components';

import { useMainArea } from '../../hooks/useMainArea';

/** @type {any} */
const SettingsTitle = ({ children }) => {
const mainAreaRef = useMainArea();
const [topClass, setClass] = useState('sticky-title--onTop');
Expand Down
13 changes: 6 additions & 7 deletions components/loader/Loader.js → components/loader/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import * as React from 'react';
import { c } from 'ttag';
import loadingSvg from 'design-system/assets/img/shared/loading-atom.svg';
import loadingSmallerSvg from 'design-system/assets/img/shared/loading-atom-smaller.svg';
Expand All @@ -13,7 +12,11 @@ const IMAGES = {
const MEDIUM_WIDTH = '80';
const MEDIUM_HEIGHT = '80';

const Loader = ({ size = 'small' }) => {
interface Props {
size: 'small' | 'medium' | 'big';
}

const Loader = ({ size = 'small' }: Props) => {
return (
<div className="center flex mb2 mt2">
<img
Expand All @@ -27,8 +30,4 @@ const Loader = ({ size = 'small' }) => {
);
};

Loader.propTypes = {
size: PropTypes.oneOf(['small', 'medium', 'big'])
};

export default Loader;
6 changes: 1 addition & 5 deletions components/price/Price.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ const Price = ({ children: amount = 0, currency = '', className = '', divisor =
const c = <span className="currency">{CURRENCIES[currency] || currency}</span>;
const p = value < 0 ? <span className="prefix">-</span> : null;
const v = <span className="amount">{Math.abs(value)}</span>;
const s = suffix ? (
<span className="ml0-5 suffix">
{suffix}
</span>
) : null;
const s = suffix ? <span className="ml0-5 suffix">{suffix}</span> : null;

if (currency === 'USD') {
return (
Expand Down
2 changes: 1 addition & 1 deletion components/table/TableCellBusy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import React from 'react';

const TableCellBusy = () => <td aria-busy="true" />;

export default TableCellBusy;
export default TableCellBusy;
1 change: 0 additions & 1 deletion components/table/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export { default as TableHeader } from './TableHeader';
export { default as TableFooter } from './TableFooter';
export { default as TableRow } from './TableRow';
export { default as TableBody } from './TableBody';

2 changes: 1 addition & 1 deletion components/title/SubTitle.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ SubTitle.propTypes = {
children: PropTypes.node.isRequired
};

export default SubTitle;
export default SubTitle;
2 changes: 1 addition & 1 deletion components/title/Title.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ Title.propTypes = {
children: PropTypes.node.isRequired
};

export default Title;
export default Title;
3 changes: 3 additions & 0 deletions components/toggle/Toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const label = (key) => {
);
};

/**
* @type any
*/
const Toggle = ({ id = 'toggle', className = '', checked = false, loading, onChange, disabled, ...rest }) => {
const handleChange = (event) => {
if (!disabled && onChange) {
Expand Down
3 changes: 2 additions & 1 deletion containers/autoReply/AutoReplyForm/AutoReplyForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import StartDayOfMonthField from './fields/StartDayOfMonthField';
import EndDayOfMonthField from './fields/EndDayOfMonthField';
import StartDayOfWeekField from './fields/StartDayOfWeekField';
import EndDayOfWeekField from './fields/EndDayOfWeekField';
import { AutoReplyDuration, DAY_MILLISECONDS } from '../utils';
import { DAY_MILLISECONDS } from '../utils';
import { AutoReplyDuration } from 'proton-shared/lib/constants';

const AutoReplyForm = ({ model, updateModel }) => {
if (model.duration === AutoReplyDuration.FIXED) {
Expand Down
9 changes: 2 additions & 7 deletions containers/autoReply/AutoReplyTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@ import { c } from 'ttag';
import PropTypes from 'prop-types';
import { Button } from 'react-components';
import moment from 'moment';
import {
getDaysOfMonthOptions,
getDurationOptions,
AutoReplyDuration,
DAY_MILLISECONDS,
getTimeZoneOptions
} from './utils';
import { getDaysOfMonthOptions, getDurationOptions, DAY_MILLISECONDS, getTimeZoneOptions } from './utils';
import InfoLine from './InfoLine';
import { AutoReplyDuration } from 'proton-shared/lib/constants';

const AutoReplyTemplate = ({ autoresponder, onEdit }) => {
const durationLabel = getDurationOptions().find(({ value }) => value === autoresponder.Repeat).text;
Expand Down
32 changes: 0 additions & 32 deletions containers/autoReply/AutoReplyToggle.js

This file was deleted.

36 changes: 36 additions & 0 deletions containers/autoReply/AutoReplyToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as React from 'react';
import { useState } from 'react';
import { updateAutoresponder } from 'proton-shared/lib/api/mailSettings';
import useToggle from '../../components/toggle/useToggle';
import useEventManager from '../eventManager/useEventManager';
import useApiWithoutResult from '../../hooks/useApiWithoutResult';
import Toggle from '../../components/toggle/Toggle';
import { AutoResponder } from 'proton-shared/lib/interfaces/AutoResponder';

interface Props {
autoresponder: AutoResponder;
}

const AutoReplyToggle = ({ autoresponder, ...rest }: Props) => {
const { state, toggle } = useToggle(!!autoresponder.IsEnabled);
const { call } = useEventManager();
const { request } = useApiWithoutResult(updateAutoresponder);
const [loading, setLoading] = useState(false);

const handleToggle = async ({ target }: React.ChangeEvent<HTMLInputElement>) => {
try {
setLoading(true);
await request({ ...autoresponder, IsEnabled: target.checked });
await call();
setLoading(false);
toggle();
} catch (error) {
setLoading(false);
throw error;
}
};

return <Toggle {...rest} loading={loading} checked={state} onChange={handleToggle} />;
};

export default AutoReplyToggle;
17 changes: 0 additions & 17 deletions containers/autoReply/InfoLine.js

This file was deleted.

16 changes: 16 additions & 0 deletions containers/autoReply/InfoLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from 'react';

interface Props {
plain: boolean;
label: React.ReactNode;
children: React.ReactNode;
}

const InfoLine = ({ label, children, plain = false }: Props) => (
<tr className="mb1 w100 aligntop">
<td className="pr1">{label}</td>
<td className={`w100 ${plain ? '' : 'bold'}`}>{children}</td>
</tr>
);

export default InfoLine;
13 changes: 3 additions & 10 deletions containers/autoReply/utils.js → containers/autoReply/utils.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import moment from 'moment-timezone';
import { c } from 'ttag';
import { AutoReplyDuration } from 'proton-shared/lib/constants';

export const DAY_MILLISECONDS = 24 * 60 * 60 * 1000;

export const AutoReplyDuration = {
FIXED: 0,
DAILY: 1,
WEEKLY: 2,
MONTHLY: 3,
PERMANENT: 4
};

export const getDurationOptions = () => [
{
text: c('Option').t`Fixed duration`,
Expand Down Expand Up @@ -85,7 +78,7 @@ export const getDaysOfMonthOptions = () => [
{ text: c('Option').t`31st of the month`, value: 30 }
];

export const getRoundedHours = (time) => {
export const getRoundedHours = (time: moment.MomentInput) => {
const startOfDay = moment(time).startOf('day');

return moment(moment(time).diff(startOfDay))
Expand All @@ -94,7 +87,7 @@ export const getRoundedHours = (time) => {
.valueOf();
};

export const startOfDay = (date) =>
export const startOfDay = (date: moment.MomentInput) =>
moment(date)
.startOf('day')
.valueOf();
2 changes: 2 additions & 0 deletions containers/general/LanguageSection.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { updateLocale } from 'proton-shared/lib/api/settings';
import { loadLocale } from 'proton-shared/lib/i18n';
import { DEFAULT_LOCALE } from 'proton-shared/lib/constants';

/* eslint-disable @typescript-eslint/camelcase */
const LOCALES = {
cs_CZ: 'Čeština',
de_DE: 'Deutsch',
Expand All @@ -38,6 +39,7 @@ const LOCALES = {
zh_CN: '简体中文',
zh_TW: '繁體中'
};
/* eslint-enable @typescript-eslint/camelcase */

function LanguageSection({ locales }) {
const [{ Locale }] = useUserSettings();
Expand Down
Loading

0 comments on commit 384f0b3

Please sign in to comment.