Files
arduino-ide/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-component.tsx
Akos Kitta 0ca1a31747 fix: board <select> update on board detach
When the previously selected board is not detected, unset the `<select>`
option.

Closes #2222

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
2024-01-15 09:25:10 +01:00

199 lines
5.7 KiB
TypeScript

import { nls } from '@theia/core/lib/common/nls';
import React from '@theia/core/shared/react';
import Tippy from '@tippyjs/react';
import type { BoardList } from '../../../common/protocol/board-list';
import {
boardIdentifierEquals,
portIdentifierEquals,
} from '../../../common/protocol/boards-service';
import { CertificateAddComponent } from './certificate-add-new';
import { CertificateListComponent } from './certificate-list';
import {
BoardOptionValue,
SelectBoardComponent,
} from './select-board-components';
export const CertificateUploaderComponent = ({
boardList,
certificates,
addCertificate,
updatableFqbns,
uploadCertificates,
openContextMenu,
}: {
boardList: BoardList;
certificates: string[];
addCertificate: (cert: string) => void;
updatableFqbns: string[];
uploadCertificates: (
fqbn: string,
address: string,
urls: string[]
) => Promise<any>;
openContextMenu: (x: number, y: number, cert: string) => void;
}): React.ReactElement => {
const [installFeedback, setInstallFeedback] = React.useState<
'ok' | 'fail' | 'installing' | null
>(null);
const [showAdd, setShowAdd] = React.useState(false);
const [selectedCerts, setSelectedCerts] = React.useState<string[]>([]);
const [selectedItem, setSelectedItem] =
React.useState<BoardOptionValue | null>(null);
const installCertificates = async () => {
if (!selectedItem) {
return;
}
const board = selectedItem.board;
if (!board.fqbn) {
return;
}
setInstallFeedback('installing');
try {
await uploadCertificates(
board.fqbn,
selectedItem.port.address,
selectedCerts
);
setInstallFeedback('ok');
} catch {
setInstallFeedback('fail');
}
};
const onItemSelect = React.useCallback(
(item: BoardOptionValue | null) => {
if (!item) {
setSelectedItem(null);
return;
}
const board = item.board;
const port = item.port;
const selectedBoard = selectedItem?.board;
const selectedPort = selectedItem?.port;
if (
!boardIdentifierEquals(board, selectedBoard) ||
!portIdentifierEquals(port, selectedPort)
) {
setInstallFeedback(null);
setSelectedItem(item);
}
},
[selectedItem]
);
return (
<>
<div className="dialogSection">
<div className="dialogRow">
<strong className="fl1">
{nls.localize(
'arduino/certificate/selectCertificateToUpload',
'1. Select certificate to upload'
)}
</strong>
<Tippy
content={
<CertificateAddComponent
addCertificate={(cert) => {
addCertificate(cert);
setShowAdd(false);
}}
/>
}
placement="bottom-end"
onClickOutside={() => setShowAdd(false)}
visible={showAdd}
interactive={true}
>
<button
type="button"
className="theia-button secondary add-cert-btn"
onClick={() => {
showAdd ? setShowAdd(false) : setShowAdd(true);
}}
>
{nls.localize('arduino/certificate/addNew', 'Add New')}{' '}
<span className="fa fa-caret-down caret"></span>
</button>
</Tippy>
</div>
<div className="dialogRow">
<CertificateListComponent
certificates={certificates}
selectedCerts={selectedCerts}
setSelectedCerts={setSelectedCerts}
openContextMenu={openContextMenu}
/>
</div>
</div>
<div className="dialogSection">
<div className="dialogRow">
<strong>
{nls.localize(
'arduino/certificate/selectDestinationBoardToUpload',
'2. Select destination board and upload certificate'
)}
</strong>
</div>
<div className="dialogRow">
<div className="fl1">
<SelectBoardComponent
boardList={boardList}
updatableFqbns={updatableFqbns}
onItemSelect={onItemSelect}
selectedItem={selectedItem}
busy={installFeedback === 'installing'}
/>
</div>
</div>
<div className="dialogRow">
<div className="upload-status">
{installFeedback === 'installing' && (
<div className="success">
<div className="spinner" />
{nls.localize(
'arduino/certificate/uploadingCertificates',
'Uploading certificates.'
)}
</div>
)}
{installFeedback === 'ok' && (
<div className="success">
<i className="fa fa-info status-icon" />
{nls.localize(
'arduino/certificate/certificatesUploaded',
'Certificates uploaded.'
)}
</div>
)}
{installFeedback === 'fail' && (
<div className="warn">
<i className="fa fa-exclamation status-icon" />
{nls.localize(
'arduino/certificate/uploadFailed',
'Upload failed. Please try again.'
)}
</div>
)}
</div>
<button
type="button"
className="theia-button primary install-cert-btn"
onClick={installCertificates}
disabled={selectedCerts.length === 0 || !selectedItem}
>
{nls.localize('arduino/certificate/upload', 'Upload')}
</button>
</div>
</div>
</>
);
};