This commit is contained in:
Ildar Kamalov
2025-08-11 09:43:35 +03:00
parent f7357be494
commit d00f1e12b3
8 changed files with 69 additions and 43 deletions

View File

@@ -21,7 +21,7 @@ GO.MACRO = $${GO:-go}
VERBOSE.MACRO = $${VERBOSE:-0}
CHANNEL = development
CLIENT_DIR = client
CLIENT_DIR = client_v2
DEPLOY_SCRIPT_PATH = not/a/real/path
DIST_DIR = dist
GOAMD64 = v1

View File

@@ -3,6 +3,7 @@ import React from 'react';
import { getIpList, getDnsAddress, getWebAddress } from '../../helpers/helpers';
import { ALL_INTERFACES_IP } from '../../helpers/constants';
import { InstallInterface } from '../../initialState';
import theme from 'panel/lib/theme';
interface renderItemProps {
ip: string;
@@ -19,7 +20,7 @@ const renderItem = ({ ip, port, isDns }: renderItemProps) => {
{isDns ? (
<strong>{dnsAddress}</strong>
) : (
<a href={webAddress} target="_blank" rel="noopener noreferrer">
<a href={webAddress} target="_blank" className={theme.link.link} rel="noopener noreferrer">
{webAddress}
</a>
)}

View File

@@ -3,7 +3,7 @@ import { Controller, useForm } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';
import Controls from './Controls';
import { validatePasswordLength, validateRequiredValue } from '../../helpers/validators';
import { Input } from '../../components/ui/Controls/Input';
import { Input } from 'panel/common/controls/Input';
type AuthFormValues = {
username: string;
@@ -60,10 +60,11 @@ export const Auth = ({ onAuthSubmit }: Props) => {
<Input
{...field}
type="text"
id="install_username"
data-testid="install_username"
label={t('install_auth_username')}
placeholder={t('install_auth_username_enter')}
error={fieldState.error?.message}
errorMessage={fieldState.error?.message}
autoComplete="username"
/>
)}
@@ -84,10 +85,11 @@ export const Auth = ({ onAuthSubmit }: Props) => {
<Input
{...field}
type="password"
id="install_password"
data-testid="install_password"
label={t('install_auth_password')}
placeholder={t('install_auth_password_enter')}
error={fieldState.error?.message}
errorMessage={fieldState.error?.message}
autoComplete="new-password"
/>
)}
@@ -108,10 +110,11 @@ export const Auth = ({ onAuthSubmit }: Props) => {
<Input
{...field}
type="password"
id="install_confirm_password"
data-testid="install_confirm_password"
label={t('install_auth_confirm')}
placeholder={t('install_auth_confirm')}
error={fieldState.error?.message}
errorMessage={fieldState.error?.message}
autoComplete="new-password"
/>
)}

View File

@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import { Trans } from 'react-i18next';
import * as actionCreators from '../../actions/install';
import { Button } from 'panel/common/ui/Button';
interface ControlsProps {
install: {
@@ -33,13 +34,15 @@ class Controls extends Component<ControlsProps> {
case 2:
case 3:
return (
<button
<Button
data-testid="install_back"
type="button"
className="btn btn-secondary btn-lg setup__button"
size="small"
variant="secondary"
className="setup__button"
onClick={this.props.prevStep}>
<Trans>back</Trans>
</button>
</Button>
);
default:
return false;
@@ -52,44 +55,52 @@ class Controls extends Component<ControlsProps> {
switch (step) {
case 1:
return (
<button
<Button
data-testid="install_get_started"
type="button"
className="btn btn-success btn-lg setup__button"
onClick={nextStep}>
onClick={nextStep}
size="small"
variant="primary"
className="setup__button">
<Trans>get_started</Trans>
</button>
</Button>
);
case 2:
case 3:
return (
<button
<Button
data-testid="install_next"
type="submit"
className="btn btn-success btn-lg setup__button"
size="small"
variant="primary"
className="setup__button"
disabled={invalid || pristine || install.processingSubmit}>
<Trans>next</Trans>
</button>
</Button>
);
case 4:
return (
<button
<Button
data-testid="install_next"
type="button"
className="btn btn-success btn-lg setup__button"
size="small"
variant="primary"
className="setup__button"
onClick={nextStep}>
<Trans>next</Trans>
</button>
</Button>
);
case 5:
return (
<button
<Button
data-testid="install_open_dashboard"
type="button"
className="btn btn-success btn-lg setup__button"
size="small"
variant="primary"
className="setup__button"
onClick={() => this.props.openDashboard(ip, port)}>
<Trans>open_dashboard</Trans>
</button>
</Button>
);
default:
return false;
@@ -101,10 +112,8 @@ class Controls extends Component<ControlsProps> {
return (
<div className="setup__nav">
<div className="btn-list">
{this.renderPrevButton(install.step)}
{this.renderNextButton(install.step)}
</div>
{this.renderPrevButton(install.step)}
{this.renderNextButton(install.step)}
</div>
);
}

View File

@@ -52,7 +52,9 @@
}
.setup__nav {
text-align: center;
display: flex;
gap: 16px;
justify-content: center;
}
.setup__step {
@@ -130,9 +132,7 @@
}
.setup__button {
min-width: 120px;
padding-left: 30px;
padding-right: 30px;
max-width: 200px;
}
.setup__error {

View File

@@ -1,8 +1,9 @@
import React from 'react';
import { Controller, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { Input } from '../../components/ui/Controls/Input';
import { validateRequiredValue } from '../../helpers/validators';
import { validateRequiredValue } from 'panel/helpers/validators';
import { Input } from 'panel/common/controls/Input';
import { Button } from 'panel/common/ui/Button';
export type LoginFormValues = {
username: string;
@@ -39,14 +40,14 @@ const Form = ({ onSubmit, processing }: LoginFormProps) => {
render={({ field, fieldState }) => (
<Input
{...field}
id="username"
data-testid="username"
type="text"
label={t('username_label')}
placeholder={t('username_placeholder')}
error={fieldState.error?.message}
errorMessage={fieldState.error?.message}
autoComplete="username"
autoCapitalize="none"
disabled={processing}
/>
)}
/>
@@ -60,26 +61,28 @@ const Form = ({ onSubmit, processing }: LoginFormProps) => {
render={({ field, fieldState }) => (
<Input
{...field}
id="password"
data-testid="password"
type="password"
label={t('password_label')}
placeholder={t('password_placeholder')}
error={fieldState.error?.message}
errorMessage={fieldState.error?.message}
autoComplete="current-password"
disabled={processing}
/>
)}
/>
</div>
<div className="form-footer">
<button
<Button
id="sign_in"
data-testid="sign_in"
type="submit"
className="btn btn-success btn-block"
variant="primary"
size="small"
disabled={processing || !isValid}>
{t('sign_in')}
</button>
</Button>
</div>
</div>
</form>

View File

@@ -38,6 +38,12 @@
letter-spacing: 0;
}
.login__link {
margin-top: 16px;
border: 0;
background: transparent;
}
@media screen and (min-width: 992px) {
.login__message {
position: absolute;

View File

@@ -1,14 +1,16 @@
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Trans } from 'react-i18next';
import cn from 'clsx';
import theme from 'panel/lib/theme';
import * as actionCreators from '../../actions/login';
import Toasts from '../../components/Toasts';
import Form, { LoginFormValues } from './Form';
import { LoginState } from '../../initialState';
import './Login.css';
import { LoginState } from '../../initialState';
export const Login = () => {
const dispatch = useDispatch();
@@ -29,7 +31,7 @@ export const Login = () => {
<Form onSubmit={handleSubmit} processing={processingLogin} />
<div className="login__info">
<button type="button" className="btn btn-link login__link" onClick={toggleText}>
<button type="button" className={cn(theme.link.link, 'login__link')} onClick={toggleText}>
<Trans>forgot_password</Trans>
</button>
@@ -41,7 +43,9 @@ export const Login = () => {
href="https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration#password-reset"
key="0"
target="_blank"
rel="noopener noreferrer">
rel="noopener noreferrer"
className={theme.link.link}
>
link
</a>,
]}>