Skip to content

Commit 5b493fb

Browse files
authored
Improve the Street Smart plugin view for 3D maps visualization(Re-login enabled) #11374 (#11628)
1 parent 996c2fe commit 5b493fb

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

web/client/plugins/StreetView/components/CyclomediaView/Credentials.jsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useState} from 'react';
22
import Message from '../../../../components/I18N/Message';
3-
import { Form, Button, ControlLabel, FormControl, Glyphicon } from 'react-bootstrap';
3+
import { Form, Button, ControlLabel, FormControl, Glyphicon, Alert } from 'react-bootstrap';
44
import tooltip from '../../../../components/misc/enhancers/tooltip';
55
const ButtonT = tooltip(Button);
66
/**
@@ -11,9 +11,10 @@ const ButtonT = tooltip(Button);
1111
* @prop {object} credentials object with username and password
1212
* @prop {boolean} showCredentialsForm show form
1313
* @prop {function} setShowCredentialsForm function to set showCredentialsForm
14+
* @prop {boolean} isCredentialsInvalid flag to indicate if credentials are invalid
1415
* @returns {JSX.Element} The rendered component
1516
*/
16-
export default ({setCredentials = () => {}, credentials, showCredentialsForm, setShowCredentialsForm = () => {}}) => {
17+
export default ({setCredentials = () => {}, credentials, showCredentialsForm, setShowCredentialsForm = () => {}, isCredentialsInvalid = false}) => {
1718
const [username, setUsername] = useState(credentials?.username || '');
1819
const [password, setPassword] = useState(credentials?.password || '');
1920
const onSubmit = () => {
@@ -38,10 +39,15 @@ export default ({setCredentials = () => {}, credentials, showCredentialsForm, se
3839
<FormControl type="text" value={username} onChange={e => setUsername(e.target.value)}/>
3940
<ControlLabel><Message msgId="streetView.cyclomedia.password" /></ControlLabel>
4041
<FormControl type="password" value={password} onChange={e => setPassword(e.target.value)}/>
42+
{isCredentialsInvalid && (
43+
<Alert bsStyle="danger" style={{marginTop: 10}}>
44+
<Message msgId="streetView.cyclomedia.errors.invalidCredentials" />
45+
</Alert>
46+
)}
4147
<div className="street-view-credentials-form-buttons">
4248
<Button disabled={!username || !password} onClick={() => onSubmit()}><Message msgId="streetView.cyclomedia.submit" /></Button>
4349
{
44-
credentials?.username && credentials?.password && <Button onClick={() => {
50+
credentials?.username && credentials?.password && !isCredentialsInvalid && <Button onClick={() => {
4551
setCredentials({username: credentials.username, password: credentials.password});
4652
setShowCredentialsForm(false);
4753
} }><Message msgId="cancel" /></Button>

web/client/plugins/StreetView/components/CyclomediaView/CyclomediaView.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ const CyclomediaView = ({ apiKey, style, location = {}, setPov = () => {}, setLo
215215
setInitializing(false);
216216
setError(err);
217217
setReloadAllowed(true);
218+
if (isInvalidCredentials(err) >= 0) {
219+
setShowCredentialsForm(true);
220+
}
218221
if (err) {
219222
console.error('Cyclomedia API: init: error: ' + err);
220223
}
@@ -328,8 +331,11 @@ const CyclomediaView = ({ apiKey, style, location = {}, setPov = () => {}, setLo
328331
showCredentialsForm={showCredentialsForm}
329332
setShowCredentialsForm={setShowCredentialsForm}
330333
credentials={credentials}
334+
isCredentialsInvalid={isInvalidCredentials(error) >= 0}
331335
setCredentials={(newCredentials) => {
332336
setCredentials(newCredentials);
337+
setError(null);
338+
setReload(prev => prev + 1);
333339
}}/>}
334340
{showLogout
335341
&& initialized
@@ -368,7 +374,7 @@ const CyclomediaView = ({ apiKey, style, location = {}, setPov = () => {}, setLo
368374
<Message msgId="streetView.cyclomedia.errorOccurred" />
369375
{getErrorMessage(error, {srs})}
370376
<div style={{ display: "flex", justifyContent: "center", marginTop: 10 }}>
371-
{initialized || reloadAllowed ? <div><Button
377+
{(initialized || reloadAllowed) && isInvalidCredentials(error) < 0 ? <div><Button
372378
style={{margin: 10}}
373379
onClick={() => {
374380
setError(null);

web/client/plugins/StreetView/components/CyclomediaView/__tests__/Credentials-test.jsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,31 @@ describe('Cyclomedia Credentials', () => {
8383

8484

8585
});
86+
it('should show error alert when isCredentialsInvalid is true', () => {
87+
act(() => {
88+
ReactDOM.render(<Credentials showCredentialsForm isCredentialsInvalid credentials={{username: 'test', password: 'password'}}/>, document.getElementById("container"));
89+
});
90+
const div = getMainDiv();
91+
const errorAlert = div.querySelector('.alert-danger');
92+
expect(errorAlert).toExist();
93+
});
94+
it('should not show cancel button when isCredentialsInvalid is true', () => {
95+
act(() => {
96+
ReactDOM.render(<Credentials showCredentialsForm isCredentialsInvalid credentials={{username: 'test', password: 'password'}}/>, document.getElementById("container"));
97+
});
98+
const div = getMainDiv();
99+
const buttons = div.querySelectorAll('.street-view-credentials-form-buttons button');
100+
// Only submit button should be present, no cancel button
101+
expect(buttons.length).toBe(1);
102+
});
103+
it('should show cancel button when isCredentialsInvalid is false and credentials exist', () => {
104+
act(() => {
105+
ReactDOM.render(<Credentials showCredentialsForm isCredentialsInvalid={false} credentials={{username: 'test', password: 'password'}}/>, document.getElementById("container"));
106+
});
107+
const div = getMainDiv();
108+
const buttons = div.querySelectorAll('.street-view-credentials-form-buttons button');
109+
// Both submit and cancel buttons should be present
110+
expect(buttons.length).toBe(2);
111+
});
86112

87113
});

web/client/plugins/StreetView/components/CyclomediaView/__tests__/CyclomediaView-test.jsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,35 @@ describe('Cyclomedia CyclomediaView', () => {
122122
// check alert to exist
123123
expect(document.querySelector('.alert-danger')).toExist();
124124
});
125+
it('shows credentials form automatically when 401 error occurs', (done) => {
126+
window.__cyclomedia__mock__ = {
127+
init: () => new Promise((resolve, reject) => {
128+
setTimeout(() => {
129+
reject(new Error('Authentication failed: code 401 Unauthorized'));
130+
}, 100);
131+
}),
132+
open: () => new Promise((resolve) => { resolve(); })
133+
};
134+
135+
const props = {
136+
apiKey: testAPIKey
137+
};
138+
139+
act(() => {
140+
ReactDOM.render(<CyclomediaView {...props} providerSettings={mockProviderSettings}/>, document.getElementById("container"));
141+
});
142+
143+
// Wait for the error to be processed and displayed
144+
setTimeout(() => {
145+
// Check that credentials form is automatically shown
146+
const credentialsForm = document.querySelector('.street-view-credentials');
147+
expect(credentialsForm).toExist();
148+
149+
// Check that error alert is shown within the form
150+
const errorAlert = document.querySelector('.street-view-credentials .alert-danger');
151+
expect(errorAlert).toExist();
152+
153+
done();
154+
}, 500);
155+
});
125156
});

0 commit comments

Comments
 (0)