Skip to content

Commit

Permalink
Ащкьфеештп
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed May 25, 2024
1 parent 4c0b79f commit f2996a8
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@mui/styles';
import { type Styles, withStyles } from '@mui/styles';

import { amber, blue, red } from '@mui/material/colors';

Expand All @@ -10,9 +9,11 @@ import {

import Router from '@iobroker/adapter-react-v5/Components/Router';

import type { Theme } from '@iobroker/adapter-react-v5/types';
import type { AdminConnection } from '@iobroker/adapter-react-v5';
import Utils from '../Utils';

const styles = theme => ({
const styles: Styles<Theme, any> = (theme: Theme) => ({
log: {
height: 400,
width: 860,
Expand All @@ -37,8 +38,45 @@ const styles = theme => ({
},
});

class Command extends Component {
constructor(props) {
interface CommandProps {
noSpacing?: boolean;
host: string;
callback: (exitCode: number) => void;
socket: AdminConnection;
onFinished: (exitCode: number, log: string[]) => void;
ready: boolean;
t: (text: string) => string;
inBackground?: boolean;
commandError?: boolean;
errorFunc?: (exitCode: number, log: string[]) => void;
performed?: () => void;
cmd: string;
onSetCommandRunning: (running: boolean) => void;
showElement?: boolean;
classes: Record<string, string>;
logsRead?: string[];
}

interface CommandState {
log: string[];
init: boolean;
max: number | null;
value: number | null;
// progressText: string;
moreChecked: boolean;
stopped: boolean;
activeCmdId?: number;
// closeOnReady: boolean;
}

class Command extends Component<CommandProps, CommandState> {
private readonly logRef: React.RefObject<HTMLDivElement>;

private static pattern = ['error', 'warn', 'info', 'ERROR', 'WARN', 'INFO'];

private readonly regExp: RegExp;

constructor(props: CommandProps) {
super(props);

this.state = {
Expand All @@ -53,8 +91,7 @@ class Command extends Component {

this.logRef = React.createRef();

const pattern = ['error', 'warn', 'info'];
this.regExp = new RegExp(pattern.join('|'), 'i');
this.regExp = new RegExp(Command.pattern.join('|'), 'i');
}

componentDidMount() {
Expand Down Expand Up @@ -91,12 +128,13 @@ class Command extends Component {

this.setState({ activeCmdId });

// @ts-expect-error fixed in socket-classes
this.props.socket.cmdExec(this.props.host.startsWith('system.host.') ? this.props.host : (`system.host.${this.props.host}`), this.props.cmd, activeCmdId)
.catch(error =>
console.log(error));
}

cmdStdoutHandler(id, text) {
cmdStdoutHandler(id: number, text: string) {
if (this.state.activeCmdId && this.state.activeCmdId === id) {
const log = this.state.log.slice();
log.push(text);
Expand Down Expand Up @@ -133,7 +171,7 @@ class Command extends Component {
}
}

cmdStderrHandler(id, text) {
cmdStderrHandler(id: number, text: string) {
if (this.state.activeCmdId && this.state.activeCmdId === id) {
const log = this.state.log.slice();
log.push(text);
Expand All @@ -146,7 +184,7 @@ class Command extends Component {
}
}

cmdExitHandler(id, exitCode) {
cmdExitHandler(id: number, exitCode: number) {
if (this.state.activeCmdId && this.state.activeCmdId === id) {
const log = this.state.log.slice();
if (!window.document.hidden && exitCode === 0 && log.length && log[log.length - 1].endsWith('created') && this.props.callback) {
Expand Down Expand Up @@ -184,7 +222,7 @@ class Command extends Component {
}
}

colorize(text, maxLength) {
colorize(text: string, maxLength?: number) {
if (maxLength !== undefined) {
text = text.substring(0, maxLength);
}
Expand All @@ -204,7 +242,7 @@ class Command extends Component {
text = text.replace(part, '');
}

const part = text.substr(0, match.length);
const part = text.substring(0, match.length);
if (part) {
const message = Utils.parseColorMessage(part);
result.push(<span key={result.length} className={classes[match.toLowerCase()]}>{typeof message === 'object' ? message.parts.map((item, i) => <span key={i} style={item.style}>{item.text}</span>) : message}</span>);
Expand Down Expand Up @@ -243,13 +281,13 @@ class Command extends Component {
direction="column"
spacing={this.props.noSpacing ? 0 : 2}
>
{this.props.showElement && <Grid item>
{this.props.showElement === undefined || this.props.showElement === true ? <Grid item>
{!this.state.stopped && <LinearProgress
style={this.props.commandError ? { backgroundColor: '#f44336' } : null}
variant={this.props.inBackground ? 'determinate' : 'indeterminate'}
value={this.state.max && this.state.value ? 100 - Math.round((this.state.value / this.state.max) * 100) : this.props.commandError ? 0 : 100}
/>}
</Grid>}
</Grid> : null}
<div style={{
width: '100%',
display: 'flex',
Expand All @@ -268,7 +306,7 @@ class Command extends Component {
>
{this.colorize(this.state.log[this.state.log.length - 1])}
</Typography>
{this.props.showElement && <Typography component="div" style={{ width: 250 }}>
{this.props.showElement === undefined || this.props.showElement === true ? <Typography component="div" style={{ width: 250 }}>
<Grid component="label" container alignItems="center" spacing={1}>
<Grid item>{this.props.t('less')}</Grid>
<Grid item>
Expand All @@ -280,7 +318,7 @@ class Command extends Component {
</Grid>
<Grid item>{this.props.t('more')}</Grid>
</Grid>
</Typography>}
</Typography> : null}
</div>
<Grid item style={this.props.noSpacing ? { height: 'calc(100% - 45px)', width: '100%' } : {}}>
{this.state.moreChecked && <Paper className={this.props.noSpacing ? classes.logNoSpacing : classes.log}>
Expand All @@ -291,25 +329,4 @@ class Command extends Component {
}
}

Command.defaultProps = {
showElement: true,
};

Command.propTypes = {
noSpacing: PropTypes.bool,
host: PropTypes.string.isRequired,
callback: PropTypes.func.isRequired,
socket: PropTypes.object.isRequired,
onFinished: PropTypes.func.isRequired,
ready: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired,
inBackground: PropTypes.bool,
commandError: PropTypes.bool,
errorFunc: PropTypes.func,
performed: PropTypes.func,
cmd: PropTypes.string.isRequired,
onSetCommandRunning: PropTypes.func.isRequired,
showElement: PropTypes.bool,
};

export default withStyles(styles)(Command);
103 changes: 59 additions & 44 deletions packages/admin/src/src/dialogs/NodeUpdateDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,43 +46,53 @@ export default class NodeUpdateDialog extends React.Component<NodeUpdateDialogPr
* Render the element
*/
render(): React.JSX.Element {
return <Dialog
open={!0}
maxWidth="lg"
fullWidth
>
<DialogTitle>{I18n.t('Node.js upgrade')}</DialogTitle>
<DialogContent style={{ height: 100, padding: '0 20px', overflow: 'hidden' }}>
{!this.state.finished ? <Typography>{I18n.t('Performing this update will restart the js-controller afterwards!')}</Typography> : null}
{this.state.inProgress ? <Box sx={{ display: 'flex', justifyContent: 'center' }}>
<CircularProgress />
</Box> : null}
{this.state.success ? <Typography>{I18n.t('Node.js update successful, restarting controller now!')}</Typography> : null}
{this.state.error ? <Typography sx={{ color: 'red' }}>{I18n.t('Node.js update failed: %s', this.state.error)}</Typography> : null}
</DialogContent>
<DialogActions>
<Button
disabled={this.state.inProgress || this.state.finished}
color="primary"
variant="contained"
startIcon={<RefreshIcon />}
onClick={() => this.updateNodeJsVersion()}
>
{I18n.t('Upgrade')}
</Button>
<Button
disabled={this.state.inProgress}
variant="contained"
onClick={() => {
this.props.onClose();
}}
color="primary"
startIcon={<CloseIcon />}
>
{I18n.t('Close')}
</Button>
</DialogActions>
</Dialog>;
return (
<Dialog open={!0} maxWidth="lg" fullWidth>
<DialogTitle>{I18n.t('Node.js upgrade')}</DialogTitle>
<DialogContent style={{ height: 100, padding: '0 20px', overflow: 'hidden' }}>
{!this.state.finished ? (
<Typography>
{I18n.t('Performing this update will restart the js-controller afterwards!')}
</Typography>
) : null}
{this.state.inProgress ? (
<Box sx={{ display: 'flex', justifyContent: 'center' }}>
<CircularProgress />
</Box>
) : null}
{this.state.success ? (
<Typography>{I18n.t('Node.js update successful, restarting controller now!')}</Typography>
) : null}
{this.state.error ? (
<Typography sx={{ color: 'red' }}>
{I18n.t('Node.js update failed: %s', this.state.error)}
</Typography>
) : null}
</DialogContent>
<DialogActions>
<Button
disabled={this.state.inProgress || this.state.finished}
color="primary"
variant="contained"
startIcon={<RefreshIcon />}
onClick={() => this.updateNodeJsVersion()}
>
{I18n.t('Upgrade')}
</Button>
<Button
disabled={this.state.inProgress}
variant="contained"
onClick={() => {
this.props.onClose();
}}
color="primary"
startIcon={<CloseIcon />}
>
{I18n.t('Close')}
</Button>
</DialogActions>
</Dialog>
);
}

/**
Expand All @@ -92,17 +102,22 @@ export default class NodeUpdateDialog extends React.Component<NodeUpdateDialogPr
this.setState({ inProgress: true });
const res = await this.props.socket.upgradeOsPackages(
this.props.hostId,
[{
name: 'nodejs',
// For apt updates we need to be precise about the version, e.g. `18.20.2-1nodesource1`, thus we simply upgrade to the newest version instead
// version: this.props.version,
}],
[
{
name: 'nodejs',
// For apt updates we need to be precise about the version, e.g. `18.20.2-1nodesource1`, thus we simply upgrade to the newest version instead
// version: this.props.version,
},
],
// restart the controller after the Node.js update
true,
true,
);

this.setState({
inProgress: false, success: res.success, error: res.error, finished: true,
inProgress: false,
success: res.success,
error: res.error,
finished: true,
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@ import { Close as CloseIcon } from '@mui/icons-material';

import {
Confirm as ConfirmDialog,
withWidth,
withWidth, I18n,
} from '@iobroker/adapter-react-v5';
import { Marker } from 'leaflet';
import { Marker } from 'leaflet';
import type {
DragEndEvent, LatLngTuple, Map,
} from 'leaflet';
import { type AdminGuiConfig, type Translate, type ioBrokerObject } from '@/types';

import { I18n } from '@iobroker/adapter-react-v5';

import Utils from '../../Utils';
import countries from '../../assets/json/countries.json';

Expand All @@ -53,7 +51,7 @@ const styles: Styles<Theme, any> = theme => ({
},
});

const MyMapComponent:React.FC<{addMap: (map: any) => any}> = props => {
const MyMapComponent: React.FC<{ addMap: (map: any) => any }> = props => {
const map = useMap();
props.addMap && props.addMap(map);
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// RepositoriesDialog
import React, { Component } from 'react';
import { type Styles, withStyles } from '@mui/styles';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
Expand Down Expand Up @@ -36,7 +35,7 @@ import { type Translator, type Theme } from '@iobroker/adapter-react-v5/types';
import type { AdminGuiConfig, ioBrokerObject } from '@/types';
import Utils from '../../Utils';

const styles:Styles<Theme, any> = theme => ({
const styles: Styles<Theme, any> = theme => ({
tabPanel: {
width: '100%',
height: '100% ',
Expand Down Expand Up @@ -118,25 +117,25 @@ interface RepositoriesDialogProps {
t: Translator;
classes: Record<string, string>;
data: ioBrokerObject<{ repositories: Repository }>;
dataAux: ioBrokerObject<object, {activeRepo: string | string[]}>;
dataAux: ioBrokerObject<object, { activeRepo: string | string[] }>;
multipleRepos: boolean;
repoInfo: Repository;
saving: boolean;
onChange: (data: ioBrokerObject<{ repositories: Repository }>, dataAux?: ioBrokerObject<object, {activeRepo: string | string[]}>) => void;
onChange: (data: ioBrokerObject<{ repositories: Repository }>, dataAux?: ioBrokerObject<object, { activeRepo: string | string[] }>) => void;
adminGuiConfig: AdminGuiConfig;
}

interface RepositoriesDialogState {
error: boolean;
confirm: boolean;
confirmValue: {
newData: ioBrokerObject<object, {activeRepo: string | string[]}>;
newData: ioBrokerObject<object, { activeRepo: string | string[] }>;
error: boolean;
} | null;
}

const SortableList = SortableContainer<{value: any}>(({ value }: {value: any}) => value);
const SortableItem = SortableElement<{value: any}>(({ value }: {value: any}) => value);
const SortableList = SortableContainer<{ value: any }>(({ value }: { value: any }) => value);
const SortableItem = SortableElement<{ value: any }>(({ value }: { value: any }) => value);

class RepositoriesDialog extends Component<RepositoriesDialogProps, RepositoriesDialogState> {
constructor(props: RepositoriesDialogProps) {
Expand All @@ -159,9 +158,12 @@ class RepositoriesDialog extends Component<RepositoriesDialogProps, Repositories
newData.native.repositories = arrayToRepo(array);

let newConfig;
if (((typeof this.props.dataAux.common.activeRepo === 'string' && this.props.dataAux.common.activeRepo === id) ||
(typeof this.props.dataAux.common.activeRepo !== 'string' && this.props.dataAux.common.activeRepo.includes(id))) &&
name === 'title') {
if ((
(typeof this.props.dataAux.common.activeRepo === 'string' && this.props.dataAux.common.activeRepo === id) ||
(typeof this.props.dataAux.common.activeRepo !== 'string' && this.props.dataAux.common.activeRepo.includes(id))
) &&
name === 'title'
) {
newConfig = this.getUpdateDefaultRepo(value, newData, oldTitle, value);
}

Expand Down
Loading

0 comments on commit f2996a8

Please sign in to comment.