Skip to content

Commit b2ac6ce

Browse files
committed
Merge branch 'dev' into long-callback-errors
2 parents 34bd81d + ac7b37d commit b2ac6ce

File tree

12 files changed

+89
-22
lines changed

12 files changed

+89
-22
lines changed

Diff for: @plotly/dash-generator-test-component-typescript/generator.test.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ describe('Test Typescript component metadata generation', () => {
6161
describe.each([
6262
'TypeScriptComponent',
6363
'TypeScriptClassComponent',
64-
'MemoTypeScriptComponent'
64+
'MemoTypeScriptComponent',
65+
'FCComponent',
6566
])('Test prop type names', componentName => {
6667
const getPropTypeName = (name, data) =>
6768
R.path(propPath(componentName, name).concat('type', 'name'), data);
@@ -256,10 +257,16 @@ describe('Test Typescript component metadata generation', () => {
256257
test('Standard js component is parsed', () => {
257258
expect(R.path(['StandardComponent'], metadata)).toBeDefined();
258259
});
260+
test('Mixed component prop-type & typescript', () => {
261+
expect(R.path(['MixedComponent', 'props', 'prop', 'type', 'name'], metadata)).toBe('arrayOf')
262+
})
259263
});
260-
describe('Test namespace props', () => {
264+
describe('Test special cases', () => {
261265
test('Component with picked boolean prop', () => {
262266
expect(R.path(['WrappedHTML', "props", "autoFocus", "type", "name"], metadata)).toBe("bool");
263-
})
264-
})
267+
});
268+
test('Empty Component', () => {
269+
expect(R.path(['EmptyComponent', 'props'], metadata)).toBeDefined();
270+
});
271+
});
265272
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from 'react';
2+
3+
const EmptyComponent = () => <div>Empty</div>;
4+
5+
export default EmptyComponent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import React from 'react';
2+
import { TypescriptComponentProps } from '../props';
3+
4+
const FCComponent: React.FC<TypescriptComponentProps> = (props) => (
5+
<div>{props.children}</div>
6+
);
7+
8+
export default FCComponent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import PropTypes from 'prop-types';
2+
import React from 'react';
3+
4+
type Props = {
5+
id?: string;
6+
prop: string[];
7+
}
8+
9+
const MixedComponent: React.FC<Props> = (props) => {
10+
return (
11+
<div id={props.id}>{props.children}</div>
12+
)
13+
}
14+
15+
MixedComponent.propTypes = {
16+
prop: PropTypes.arrayOf(PropTypes.string).isRequired
17+
}
18+
19+
export default MixedComponent;

Diff for: @plotly/dash-generator-test-component-typescript/src/index.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@ import TypeScriptClassComponent from './components/TypeScriptClassComponent';
33
import MemoTypeScriptComponent from './components/MemoTypeScriptComponent';
44
import StandardComponent from './components/StandardComponent.react';
55
import WrappedHTML from './components/WrappedHTML';
6+
import FCComponent from './components/FCComponent';
7+
import EmptyComponent from './components/EmptyComponent';
8+
import MixedComponent from './components/MixedComponent';
69

710
export {
8-
TypeScriptComponent,
9-
TypeScriptClassComponent,
10-
MemoTypeScriptComponent,
11-
StandardComponent,
12-
WrappedHTML,
11+
TypeScriptComponent,
12+
TypeScriptClassComponent,
13+
MemoTypeScriptComponent,
14+
StandardComponent,
15+
WrappedHTML,
16+
FCComponent,
17+
EmptyComponent,
18+
MixedComponent,
1319
};

Diff for: CHANGELOG.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
All notable changes to `dash` will be documented in this file.
33
This project adheres to [Semantic Versioning](https://semver.org/).
44

5+
## [UNRELEASED]
6+
7+
### Fixed
8+
9+
- [#2098](https://github.com/plotly/dash/pull/2098) Accept HTTP code 400 as well as 401 for JWT expiry
10+
- [#2097](https://github.com/plotly/dash/pull/2097) Fix bug [#2095](https://github.com/plotly/dash/issues/2095) with TypeScript compiler and `React.FC` empty valueDeclaration error & support empty props components.
11+
512
## [2.5.1] - 2022-06-13
613

714
### Fixed
@@ -29,8 +36,8 @@ This feature can be disabled by providing an empty viewport meta tag. e.g. `app
2936

3037
### Fixed
3138

32-
- [#2043](https://github.com/plotly/dash/pull/2043) Fix bug
33-
[#2003](https://github.com/plotly/dash/issues/2003) in which
39+
- [#2043](https://github.com/plotly/dash/pull/2043) Fix bug
40+
[#2003](https://github.com/plotly/dash/issues/2003) in which
3441
`dangerously_allow_html=True` + `mathjax=True` works in some cases, and in some cases not.
3542
- [#2065](https://github.com/plotly/dash/pull/2065) Fix bug [#2064](https://github.com/plotly/dash/issues/2064) rendering of `dcc.Dropdown` with a value but no options.
3643
- [#2047](https://github.com/plotly/dash/pull/2047) Fix bug [#1979](https://github.com/plotly/dash/issues/1979) in which `DASH_DEBUG` as environment variable gets ignored.

Diff for: dash/dash-renderer/src/actions/api.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ export default function apiThunk(endpoint, method, store, id, body) {
6565
return;
6666
}
6767

68-
if (res.status === STATUS.UNAUTHORIZED) {
68+
if (
69+
res.status === STATUS.UNAUTHORIZED ||
70+
res.status === STATUS.BAD_REQUEST
71+
) {
6972
if (hooks.request_refresh_jwt) {
7073
const body = await res.text();
7174
if (body.includes(JWT_EXPIRED_MESSAGE)) {

Diff for: dash/dash-renderer/src/actions/callbacks.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,8 @@ export function executeCallback(
679679
lastError = res;
680680
if (
681681
retry <= MAX_AUTH_RETRIES &&
682-
res.status === STATUS.UNAUTHORIZED
682+
(res.status === STATUS.UNAUTHORIZED ||
683+
res.status === STATUS.BAD_REQUEST)
683684
) {
684685
const body = await res.text();
685686

Diff for: dash/dash-renderer/src/constants/constants.js

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export const JWT_EXPIRED_MESSAGE = 'JWT Expired';
55
export const STATUS = {
66
OK: 200,
77
PREVENT_UPDATE: 204,
8+
// We accept both 400 and 401 for JWT token expiry responses.
9+
// Some servers use code 400 for expired tokens, because
10+
// they reserve 401 for cases that require user action
11+
BAD_REQUEST: 400,
812
UNAUTHORIZED: 401,
913
CLIENTSIDE_ERROR: 'CLIENTSIDE_ERROR',
1014
NO_RESPONSE: 'NO_RESPONSE'

Diff for: dash/development/base_component.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def _set_random_id(self):
196196
"""
197197
)
198198

199-
v = str(uuid.UUID(int=rd.randint(0, 2 ** 128)))
199+
v = str(uuid.UUID(int=rd.randint(0, 2**128)))
200200
setattr(self, "id", v)
201201
return v
202202

Diff for: dash/extract-meta.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ function checkDocstring(name, value) {
113113
function docstringWarning(doc) {
114114
checkDocstring(doc.displayName, doc.description);
115115

116-
Object.entries(doc.props).forEach(([name, p]) =>
116+
Object.entries(doc.props || {}).forEach(([name, p]) =>
117117
checkDocstring(`${doc.displayName}.${name}`, p.description)
118118
);
119119
}
@@ -672,14 +672,14 @@ function gatherComponents(sources, components = {}) {
672672
} else {
673673
// Function components.
674674
rootExp = typeSymbol;
675-
commentSource = rootExp.valueDeclaration;
675+
commentSource = rootExp.valueDeclaration || rootExp.declarations[0];
676676
if (
677-
rootExp.valueDeclaration &&
678-
rootExp.valueDeclaration.parent
677+
commentSource &&
678+
commentSource.parent
679679
) {
680680
// Function with export later like `const MyComponent = (props) => <></>;`
681681
commentSource = getParent(
682-
rootExp.valueDeclaration.parent
682+
commentSource.parent
683683
);
684684
}
685685
}
@@ -719,8 +719,13 @@ function gatherComponents(sources, components = {}) {
719719
);
720720
}
721721

722+
if (!props) {
723+
// Ensure empty components has props.
724+
props = {};
725+
}
726+
722727
const fullText = source.getFullText();
723-
let description;
728+
let description = '';
724729
const commentRanges = ts.getLeadingCommentRanges(
725730
fullText,
726731
commentSource.getFullStart()

Diff for: tests/integration/renderer/test_request_hooks.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import functools
33
import flask
4+
import pytest
45

56
from dash import Dash, Output, Input, html, dcc
67
from werkzeug.exceptions import HTTPException
@@ -195,7 +196,8 @@ def update_output(value):
195196
assert dash_duo.get_logs() == []
196197

197198

198-
def test_rdrh003_refresh_jwt(dash_duo):
199+
@pytest.mark.parametrize("expiry_code", [401, 400])
200+
def test_rdrh003_refresh_jwt(expiry_code, dash_duo):
199201

200202
app = Dash(__name__)
201203

@@ -260,7 +262,7 @@ def wrap(*args, **kwargs):
260262
):
261263
# Read the data to prevent bug with base http server.
262264
flask.request.get_json(silent=True)
263-
flask.abort(401, description="JWT Expired " + str(token))
265+
flask.abort(expiry_code, description="JWT Expired " + str(token))
264266
except HTTPException as e:
265267
return e
266268
return func(*args, **kwargs)

0 commit comments

Comments
 (0)