mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2026-08-04 15:28:58 +00:00
fix issues
Some checks are pending
build / test (macOS-latest) (push) Waiting to run
build / test (ubuntu-latest) (push) Waiting to run
build / test (windows-latest) (push) Waiting to run
build / build-release (push) Blocked by required conditions
build / notify (push) Blocked by required conditions
lint / go-lint (push) Waiting to run
lint / eslint (push) Waiting to run
lint / notify (push) Blocked by required conditions
Some checks are pending
build / test (macOS-latest) (push) Waiting to run
build / test (ubuntu-latest) (push) Waiting to run
build / test (windows-latest) (push) Waiting to run
build / build-release (push) Blocked by required conditions
build / notify (push) Blocked by required conditions
lint / go-lint (push) Waiting to run
lint / eslint (push) Waiting to run
lint / notify (push) Blocked by required conditions
This commit is contained in:
parent
d20a5e297a
commit
86456f38d9
10 changed files with 52 additions and 18 deletions
|
|
@ -47,12 +47,12 @@
|
|||
border: none;
|
||||
border-radius: 16px;
|
||||
background-clip: border-box;
|
||||
padding: 8px 0;
|
||||
padding: 16px 0;
|
||||
color: var(--default-main-text);
|
||||
text-align: left;
|
||||
overflow: auto;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
@media (min-width: 768px) {
|
||||
border-radius: 16px;
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,22 @@ export const Encryption = () => {
|
|||
|
||||
const [tlsStatusLoaded, setTlsStatusLoaded] = createSignal(false);
|
||||
|
||||
/**
|
||||
* Shadows encryptionState.enabled with {@code equals: false} so we can
|
||||
* force a DOM re-sync even when the value is unchanged (e.g. reverting
|
||||
* after a modal opens without saving). Synced from store only when
|
||||
* {@code processingConfig} is false to avoid flashing during async save.
|
||||
*/
|
||||
const [encryptionEnabled, setEncryptionEnabled] = createSignal(false, {
|
||||
equals: false,
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (!encryptionState.processingConfig) {
|
||||
setEncryptionEnabled(encryptionState.enabled);
|
||||
}
|
||||
});
|
||||
|
||||
const [validateConfig, cancelValidation] = createDebouncedValidator();
|
||||
|
||||
onMount(async () => {
|
||||
|
|
@ -49,9 +65,9 @@ export const Encryption = () => {
|
|||
!!(encryptionState.certificate_chain || encryptionState.certificate_path);
|
||||
|
||||
const handleEncryptedDnsChange = (checked: boolean) => {
|
||||
resetValidationStatus();
|
||||
|
||||
if (!checked) {
|
||||
setEncryptionEnabled(false);
|
||||
resetValidationStatus();
|
||||
setTlsConfig(
|
||||
{
|
||||
enabled: false,
|
||||
|
|
@ -72,6 +88,8 @@ export const Encryption = () => {
|
|||
const hasServerName = !!encryptionState.server_name;
|
||||
|
||||
// Everything is set up — save the change.
|
||||
// Native input already shows ON from the click; sync effect
|
||||
// confirms on success or reverts on failure.
|
||||
if (hasCert && hasKey && hasServerName) {
|
||||
setTlsConfig(
|
||||
{
|
||||
|
|
@ -82,6 +100,10 @@ export const Encryption = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
// Not saving — force DOM back to unchecked so the switch
|
||||
// doesn't appear ON while encryption is actually OFF.
|
||||
setEncryptionEnabled(false);
|
||||
|
||||
// Certificate or key is missing — open the TLS cert wizard (don't save yet).
|
||||
if (!hasCert || !hasKey) {
|
||||
setAddCertOpen(true);
|
||||
|
|
@ -174,7 +196,7 @@ export const Encryption = () => {
|
|||
</div>
|
||||
|
||||
<Show
|
||||
when={tlsStatusLoaded() || !encryptionState.processing}
|
||||
when={tlsStatusLoaded()}
|
||||
fallback={<PageLoader />}
|
||||
>
|
||||
<PlainDnsToggle />
|
||||
|
|
@ -195,7 +217,7 @@ export const Encryption = () => {
|
|||
variant="switch"
|
||||
title={intl.getMessage('encryption_encrypted_dns')}
|
||||
description={intl.getMessage('encryption_encrypted_dns_desc')}
|
||||
checked={encryptionState.enabled}
|
||||
checked={encryptionEnabled()}
|
||||
disabled={encryptionState.processingConfig}
|
||||
onChange={handleEncryptedDnsChange}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ import { encryptionState, setTlsConfig } from 'panel/stores/encryption';
|
|||
|
||||
export const PlainDnsToggle = () => {
|
||||
const [confirmDisable, setConfirmDisable] = createSignal(false);
|
||||
const [localChecked, setLocalChecked] = createSignal(encryptionState.serve_plain_dns);
|
||||
const [localChecked, setLocalChecked] = createSignal(encryptionState.serve_plain_dns, {
|
||||
equals: false,
|
||||
});
|
||||
const enc = () => encryptionState;
|
||||
|
||||
// Sync localChecked from store when the dialog is not open,
|
||||
|
|
@ -31,8 +33,9 @@ export const PlainDnsToggle = () => {
|
|||
setTlsConfig({ serve_plain_dns: true });
|
||||
return;
|
||||
}
|
||||
// Don't update localChecked — the switch stays visually on
|
||||
// until the user confirms in the modal.
|
||||
// Force DOM re-sync before opening the modal. With equals:false
|
||||
// this re-applies checked={true} to the native input.
|
||||
setLocalChecked((v) => v);
|
||||
setConfirmDisable(true);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Show } from 'solid-js';
|
||||
import { Icon } from 'panel/common/ui/Icon';
|
||||
import intl from 'panel/common/intl';
|
||||
import { encryptionState, setTlsConfig, resetValidationStatus } from 'panel/stores/encryption';
|
||||
import { encryptionState, setTlsConfig, resetValidationStatus, clearCertOptimistically } from 'panel/stores/encryption';
|
||||
import { CertificateStatus, KeyStatus, ValidationStatus } from '../Status';
|
||||
import s from '../styles.module.pcss';
|
||||
import theme from 'panel/lib/theme';
|
||||
|
|
@ -10,6 +10,8 @@ export const TlsCertSection = () => {
|
|||
const enc = () => encryptionState;
|
||||
|
||||
const removeCert = () => {
|
||||
clearCertOptimistically();
|
||||
resetValidationStatus();
|
||||
setTlsConfig({
|
||||
enabled: false,
|
||||
serve_plain_dns: true,
|
||||
|
|
@ -19,7 +21,6 @@ export const TlsCertSection = () => {
|
|||
private_key_path: '',
|
||||
private_key_saved: false,
|
||||
});
|
||||
resetValidationStatus();
|
||||
};
|
||||
|
||||
const renderStatus = () => {
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ export const Auth = (props: Props) => {
|
|||
autocomplete="username"
|
||||
value={(field.value as string) ?? ''}
|
||||
errorMessage={field.error as string}
|
||||
size="large"
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
|
@ -146,6 +147,7 @@ export const Auth = (props: Props) => {
|
|||
})
|
||||
}
|
||||
errorMessage={field.error as string}
|
||||
size="large"
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
|
@ -175,6 +177,7 @@ export const Auth = (props: Props) => {
|
|||
})
|
||||
}
|
||||
errorMessage={field.error as string}
|
||||
size="large"
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ export const DnsBanner = (props: Props) => {
|
|||
const { value } = e.target as HTMLInputElement;
|
||||
props.setDnsPort(toNumber(value));
|
||||
}}
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,9 @@ export const WebBanner = (props: Props) => {
|
|||
<h3 class={styles.bannerTitle}>{intl.getMessage('setup_ui_title_banner')}</h3>
|
||||
<div class={styles.bannerInputs}>
|
||||
<div class={styles.form}>
|
||||
<label class={styles.bannerLabel}>{intl.getMessage('network_interface')}</label>
|
||||
<label for="install_web_ip" class={styles.bannerLabel}>
|
||||
{intl.getMessage('network_interface')}
|
||||
</label>
|
||||
<Select
|
||||
options={props.webIpOptions}
|
||||
value={props.webIpOptions.find((option) => option.value === props.webIp())}
|
||||
|
|
@ -60,7 +62,7 @@ export const WebBanner = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<div class={styles.form}>
|
||||
<label class={styles.bannerLabel}>
|
||||
<label for="install_web_port" class={styles.bannerLabel}>
|
||||
{intl.getMessage('install_settings_port')}
|
||||
</label>
|
||||
<Input
|
||||
|
|
@ -73,6 +75,7 @@ export const WebBanner = (props: Props) => {
|
|||
const { value } = e.target as HTMLInputElement;
|
||||
props.setWebPort(toNumber(value));
|
||||
}}
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
}
|
||||
|
||||
.bannerLabel {
|
||||
color: var(--gray-70);
|
||||
color: var(--defaul-labels);
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
}
|
||||
|
||||
.errorText {
|
||||
color: var(--red-50);
|
||||
color: var(--default-error-text);
|
||||
}
|
||||
|
||||
.mutedText {
|
||||
|
|
@ -65,5 +65,5 @@
|
|||
.bannerList {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
.bannerList {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.bannerItem {
|
||||
|
|
@ -28,5 +28,5 @@
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
margin-top: 16px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ textarea {
|
|||
align-items: flex-start;
|
||||
border-radius: 16px;
|
||||
box-shadow: 8px 8px 24px 0 rgba(0, 0, 0, 0.1);
|
||||
background-color: var(--default-cards-background);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue