Skip to content

Commit e9dd2fe

Browse files
committed
Implement dialog to input board user fields
1 parent 2024b7f commit e9dd2fe

File tree

5 files changed

+235
-38
lines changed

5 files changed

+235
-38
lines changed

Diff for: arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+7
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ import {
253253
UploadCertificateDialogProps,
254254
UploadCertificateDialogWidget,
255255
} from './dialogs/certificate-uploader/certificate-uploader-dialog';
256+
import { UserFieldsDialog, UserFieldsDialogProps, UserFieldsDialogWidget } from './dialogs/user-fields/user-fields-dialog';
256257

257258
const ElementQueries = require('css-element-queries/src/ElementQueries');
258259

@@ -735,4 +736,10 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
735736
bind(UploadCertificateDialogProps).toConstantValue({
736737
title: 'UploadCertificate',
737738
});
739+
740+
bind(UserFieldsDialogWidget).toSelf().inSingletonScope();
741+
bind(UserFieldsDialog).toSelf().inSingletonScope();
742+
bind(UserFieldsDialogProps).toConstantValue({
743+
title: 'UserFields',
744+
});
738745
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as React from 'react';
2+
import { BoardUserField } from '../../../common/protocol';
3+
4+
export const UserFieldsComponent = ({
5+
initialBoardUserFields,
6+
updateUserFields,
7+
}: {
8+
initialBoardUserFields: BoardUserField[];
9+
updateUserFields: (userFields: BoardUserField[]) => void;
10+
}): React.ReactElement => {
11+
const [boardUserFields, setBoardUserFields] = React.useState<
12+
BoardUserField[]
13+
>(initialBoardUserFields);
14+
React.useEffect(() => {
15+
setBoardUserFields(initialBoardUserFields);
16+
}, [initialBoardUserFields]);
17+
18+
const updateUserField =
19+
(index: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
20+
let newBoardUserFields = [...boardUserFields];
21+
newBoardUserFields[index].value = e.target.value;
22+
setBoardUserFields(newBoardUserFields);
23+
};
24+
25+
React.useEffect(() => {
26+
updateUserFields(boardUserFields);
27+
}, [boardUserFields]);
28+
29+
return (
30+
<div>
31+
{boardUserFields.map((field, index) => {
32+
return (
33+
<div className="dialogSection" key={index}>
34+
<div className="dialogRow">
35+
<label className="field-label">{field.label}</label>
36+
</div>
37+
<div className="dialogRow">
38+
<input
39+
type={field.secret ? 'password' : 'text'}
40+
value={field.value}
41+
className="theia-input"
42+
placeholder={'Enter ' + field.label}
43+
onChange={updateUserField(index)}
44+
/>
45+
</div>
46+
</div>
47+
);
48+
})}
49+
</div>
50+
);
51+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import * as React from 'react';
2+
import { inject, injectable } from 'inversify';
3+
import {
4+
AbstractDialog,
5+
DialogProps,
6+
ReactWidget,
7+
} from '@theia/core/lib/browser';
8+
import { Widget } from '@phosphor/widgets';
9+
import { Message } from '@phosphor/messaging';
10+
import { UploadSketch } from '../../contributions/upload-sketch';
11+
import { UserFieldsComponent } from './user-fields-component';
12+
import { BoardUserField } from '../../../common/protocol';
13+
14+
@injectable()
15+
export class UserFieldsDialogWidget extends ReactWidget {
16+
protected _currentUserFields: BoardUserField[] = [];
17+
18+
constructor() {
19+
super();
20+
}
21+
22+
set currentUserFields(userFields: BoardUserField[]) {
23+
this.setUserFields(userFields);
24+
}
25+
26+
get currentUserFields(): BoardUserField[] {
27+
return this._currentUserFields;
28+
}
29+
30+
resetUserFieldsValue(): void {
31+
this._currentUserFields = this._currentUserFields.map((field) => {
32+
field.value = '';
33+
return field;
34+
});
35+
}
36+
37+
protected setUserFields(userFields: BoardUserField[]): void {
38+
this._currentUserFields = userFields;
39+
}
40+
41+
protected render(): React.ReactNode {
42+
return (
43+
<form>
44+
<UserFieldsComponent
45+
initialBoardUserFields={this._currentUserFields}
46+
updateUserFields={this.setUserFields.bind(this)}
47+
/>
48+
</form>
49+
);
50+
}
51+
}
52+
53+
@injectable()
54+
export class UserFieldsDialogProps extends DialogProps {}
55+
56+
@injectable()
57+
export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
58+
@inject(UserFieldsDialogWidget)
59+
protected readonly widget: UserFieldsDialogWidget;
60+
61+
constructor(
62+
@inject(UserFieldsDialogProps)
63+
protected readonly props: UserFieldsDialogProps
64+
) {
65+
super({
66+
title: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label || '',
67+
});
68+
this.titleNode.classList.add('user-fields-dialog-title');
69+
this.contentNode.classList.add('user-fields-dialog-content');
70+
this.appendCloseButton('CANCEL');
71+
this.appendAcceptButton('UPLOAD');
72+
}
73+
74+
set value(userFields: BoardUserField[]) {
75+
this.widget.currentUserFields = userFields;
76+
}
77+
78+
get value(): BoardUserField[] {
79+
return this.widget.currentUserFields;
80+
}
81+
82+
protected onAfterAttach(msg: Message): void {
83+
if (this.widget.isAttached) {
84+
Widget.detach(this.widget);
85+
}
86+
Widget.attach(this.widget, this.contentNode);
87+
super.onAfterAttach(msg);
88+
this.update();
89+
}
90+
91+
protected onUpdateRequest(msg: Message): void {
92+
super.onUpdateRequest(msg);
93+
this.widget.update();
94+
}
95+
96+
protected onActivateRequest(msg: Message): void {
97+
super.onActivateRequest(msg);
98+
this.widget.activate();
99+
}
100+
101+
close(): void {
102+
this.widget.resetUserFieldsValue();
103+
this.widget.close();
104+
super.close();
105+
}
106+
}

Diff for: arduino-ide-extension/src/browser/style/index.css

+43-38
Original file line numberDiff line numberDiff line change
@@ -10,94 +10,99 @@
1010
@import './settings-dialog.css';
1111
@import './firmware-uploader-dialog.css';
1212
@import './certificate-uploader-dialog.css';
13+
@import './user-fields-dialog.css';
1314
@import './debug.css';
1415
@import './sketchbook.css';
1516
@import './cloud-sketchbook.css';
1617
@import './fonts.css';
1718
@import './custom-codicon.css';
1819

1920
.theia-input.warning:focus {
20-
outline-width: 1px;
21-
outline-style: solid;
22-
outline-offset: -1px;
23-
opacity: 1 !important;
24-
color: var(--theia-warningForeground);
25-
background-color: var(--theia-warningBackground);
21+
outline-width: 1px;
22+
outline-style: solid;
23+
outline-offset: -1px;
24+
opacity: 1 !important;
25+
color: var(--theia-warningForeground);
26+
background-color: var(--theia-warningBackground);
2627
}
2728

2829
.theia-input.warning {
29-
background-color: var(--theia-warningBackground);
30+
background-color: var(--theia-warningBackground);
3031
}
3132

32-
.theia-input.warning::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
33-
color: var(--theia-warningForeground);
34-
background-color: var(--theia-warningBackground);
35-
opacity: 1; /* Firefox */
33+
.theia-input.warning::placeholder {
34+
/* Chrome, Firefox, Opera, Safari 10.1+ */
35+
color: var(--theia-warningForeground);
36+
background-color: var(--theia-warningBackground);
37+
opacity: 1; /* Firefox */
3638
}
3739

38-
.theia-input.warning:-ms-input-placeholder { /* Internet Explorer 10-11 */
39-
color: var(--theia-warningForeground);
40-
background-color: var(--theia-warningBackground);
40+
.theia-input.warning:-ms-input-placeholder {
41+
/* Internet Explorer 10-11 */
42+
color: var(--theia-warningForeground);
43+
background-color: var(--theia-warningBackground);
4144
}
4245

43-
.theia-input.warning::-ms-input-placeholder { /* Microsoft Edge */
44-
color: var(--theia-warningForeground);
45-
background-color: var(--theia-warningBackground);
46+
.theia-input.warning::-ms-input-placeholder {
47+
/* Microsoft Edge */
48+
color: var(--theia-warningForeground);
49+
background-color: var(--theia-warningBackground);
4650
}
4751

48-
/* Makes the sidepanel a bit wider when opening the widget */
52+
/* Makes the sidepanel a bit wider when opening the widget */
4953
.p-DockPanel-widget {
50-
min-width: 200px;
51-
min-height: 200px;
54+
min-width: 200px;
55+
min-height: 200px;
5256
}
5357

5458
/* Overrule the default Theia CSS button styles. */
5559
button.theia-button,
5660
.theia-button {
57-
border: 1px solid var(--theia-dropdown-border);
61+
border: 1px solid var(--theia-dropdown-border);
5862
}
5963

6064
button.theia-button:hover,
6165
.theia-button:hover {
62-
border: 1px solid var(--theia-focusBorder);
66+
border: 1px solid var(--theia-focusBorder);
6367
}
6468

6569
button.theia-button {
66-
height: 31px;
70+
height: 31px;
6771
}
6872

6973
button.theia-button.secondary {
70-
background-color: var(--theia-secondaryButton-background);
71-
color: var(--theia-secondaryButton-foreground);
74+
background-color: var(--theia-secondaryButton-background);
75+
color: var(--theia-secondaryButton-foreground);
7276
}
7377

7478
button.theia-button.main {
75-
color: var(--theia-button-foreground);
79+
color: var(--theia-button-foreground);
7680
}
7781

7882
/* To make the progress-bar slightly thicker, and use the color from the status bar */
7983
.theia-progress-bar-container {
80-
width: 100%;
81-
height: 4px;
84+
width: 100%;
85+
height: 4px;
8286
}
8387

8488
.theia-progress-bar {
85-
height: 4px;
86-
width: 3%;
87-
animation: progress-animation 1.3s 0s infinite cubic-bezier(0.645, 0.045, 0.355, 1);
89+
height: 4px;
90+
width: 3%;
91+
animation: progress-animation 1.3s 0s infinite
92+
cubic-bezier(0.645, 0.045, 0.355, 1);
8893
}
8994

9095
.theia-notification-item-progressbar {
91-
height: 4px;
92-
width: 66%;
96+
height: 4px;
97+
width: 66%;
9398
}
9499

95100
.flex-line {
96-
display: flex;
97-
align-items: center;
98-
white-space: nowrap;
101+
display: flex;
102+
align-items: center;
103+
white-space: nowrap;
99104
}
100105

101106
.fa-reload {
102-
font-size: 14px;
103-
}
107+
font-size: 14px;
108+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.user-fields-dialog-title {
2+
font-family: Open Sans;
3+
font-size: 16px;
4+
font-style: normal;
5+
font-weight: 700;
6+
line-height: 27px;
7+
letter-spacing: 0.01em;
8+
text-align: left;
9+
}
10+
11+
.user-fields-dialog-content {
12+
width: 408px;
13+
}
14+
15+
.user-fields-dialog-content .field-label {
16+
color: #2c353a;
17+
font-family: Open Sans;
18+
font-size: 14px;
19+
font-style: normal;
20+
font-weight: 400;
21+
line-height: 21px;
22+
letter-spacing: 0.01em;
23+
text-align: left;
24+
}
25+
26+
.user-fields-dialog-content .theia-input {
27+
flex-grow: 1;
28+
}

0 commit comments

Comments
 (0)