mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-06 19:46:52 +03:00
feat: implement some diagnostics widget
This commit is contained in:
@@ -431,7 +431,13 @@ export async function initDashboardController(): Promise<void> {
|
|||||||
// Remove old listener
|
// Remove old listener
|
||||||
store.unsubscribe(onStoreUpdate);
|
store.unsubscribe(onStoreUpdate);
|
||||||
// Clear store
|
// Clear store
|
||||||
store.reset();
|
store.reset([
|
||||||
|
'bandwidthWidget',
|
||||||
|
'trafficTotalWidget',
|
||||||
|
'systemInfoWidget',
|
||||||
|
'servicesInfoWidget',
|
||||||
|
'sectionsWidget',
|
||||||
|
]);
|
||||||
|
|
||||||
// Add new listener
|
// Add new listener
|
||||||
store.subscribe(onStoreUpdate);
|
store.subscribe(onStoreUpdate);
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
export enum DIAGNOSTICS_CHECKS {
|
||||||
|
DNS = 'DNS',
|
||||||
|
SINGBOX = 'SINGBOX',
|
||||||
|
NFT = 'NFT',
|
||||||
|
FAKEIP = 'FAKEIP',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DIAGNOSTICS_CHECKS_MAP: Record<
|
||||||
|
DIAGNOSTICS_CHECKS,
|
||||||
|
{ order: number; title: string; code: DIAGNOSTICS_CHECKS }
|
||||||
|
> = {
|
||||||
|
[DIAGNOSTICS_CHECKS.DNS]: {
|
||||||
|
order: 1,
|
||||||
|
title: _('DNS checks'),
|
||||||
|
code: DIAGNOSTICS_CHECKS.DNS,
|
||||||
|
},
|
||||||
|
[DIAGNOSTICS_CHECKS.SINGBOX]: {
|
||||||
|
order: 2,
|
||||||
|
title: _('Sing-box checks'),
|
||||||
|
code: DIAGNOSTICS_CHECKS.SINGBOX,
|
||||||
|
},
|
||||||
|
[DIAGNOSTICS_CHECKS.NFT]: {
|
||||||
|
order: 3,
|
||||||
|
title: _('Nftables checks'),
|
||||||
|
code: DIAGNOSTICS_CHECKS.NFT,
|
||||||
|
},
|
||||||
|
[DIAGNOSTICS_CHECKS.FAKEIP]: {
|
||||||
|
order: 4,
|
||||||
|
title: _('FakeIP checks'),
|
||||||
|
code: DIAGNOSTICS_CHECKS.FAKEIP,
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -2,13 +2,15 @@ import { getDNSCheck } from '../../../methods';
|
|||||||
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
||||||
import { insertIf } from '../../../../helpers';
|
import { insertIf } from '../../../../helpers';
|
||||||
import { IDiagnosticsChecksItem } from '../../../../store';
|
import { IDiagnosticsChecksItem } from '../../../../store';
|
||||||
|
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
|
||||||
|
|
||||||
export async function runDnsCheck() {
|
export async function runDnsCheck() {
|
||||||
const code = 'dns_check';
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.DNS;
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('DNS checks'),
|
title,
|
||||||
description: _('Checking dns, please wait'),
|
description: _('Checking dns, please wait'),
|
||||||
state: 'loading',
|
state: 'loading',
|
||||||
items: [],
|
items: [],
|
||||||
@@ -18,8 +20,9 @@ export async function runDnsCheck() {
|
|||||||
|
|
||||||
if (!dnsChecks.success) {
|
if (!dnsChecks.success) {
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('DNS checks'),
|
title,
|
||||||
description: _('Cannot receive DNS checks result'),
|
description: _('Cannot receive DNS checks result'),
|
||||||
state: 'error',
|
state: 'error',
|
||||||
items: [],
|
items: [],
|
||||||
@@ -55,8 +58,9 @@ export async function runDnsCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('DNS checks'),
|
title,
|
||||||
description: _('DNS checks passed'),
|
description: _('DNS checks passed'),
|
||||||
state: getStatus(),
|
state: getStatus(),
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
@@ -3,13 +3,15 @@ import * as fakeIPMethods from '../../../../fakeip/methods';
|
|||||||
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
||||||
import { insertIf } from '../../../../helpers';
|
import { insertIf } from '../../../../helpers';
|
||||||
import { IDiagnosticsChecksItem } from '../../../../store';
|
import { IDiagnosticsChecksItem } from '../../../../store';
|
||||||
|
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
|
||||||
|
|
||||||
export async function runFakeIPCheck() {
|
export async function runFakeIPCheck() {
|
||||||
const code = 'fake_ip_check';
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.FAKEIP;
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('FakeIP checks'),
|
title,
|
||||||
description: _('Checking FakeIP, please wait'),
|
description: _('Checking FakeIP, please wait'),
|
||||||
state: 'loading',
|
state: 'loading',
|
||||||
items: [],
|
items: [],
|
||||||
@@ -68,8 +70,9 @@ export async function runFakeIPCheck() {
|
|||||||
const { state, description } = getMeta();
|
const { state, description } = getMeta();
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('FakeIP checks'),
|
title,
|
||||||
description,
|
description,
|
||||||
state,
|
state,
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { getNftRulesCheck } from '../../../methods';
|
import { getNftRulesCheck } from '../../../methods';
|
||||||
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
||||||
import { getFakeIpCheck, getIpCheck } from '../../../../fakeip';
|
import { getFakeIpCheck, getIpCheck } from '../../../../fakeip';
|
||||||
|
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
|
||||||
|
|
||||||
export async function runNftCheck() {
|
export async function runNftCheck() {
|
||||||
const code = 'nft_check';
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.NFT;
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('Nftables checks'),
|
title,
|
||||||
description: _('Checking nftables, please wait'),
|
description: _('Checking nftables, please wait'),
|
||||||
state: 'loading',
|
state: 'loading',
|
||||||
items: [],
|
items: [],
|
||||||
@@ -20,8 +22,9 @@ export async function runNftCheck() {
|
|||||||
|
|
||||||
if (!nftablesChecks.success) {
|
if (!nftablesChecks.success) {
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('Nftables checks'),
|
title,
|
||||||
description: _('Cannot receive nftables checks result'),
|
description: _('Cannot receive nftables checks result'),
|
||||||
state: 'error',
|
state: 'error',
|
||||||
items: [],
|
items: [],
|
||||||
@@ -67,8 +70,9 @@ export async function runNftCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('Nftables checks'),
|
title,
|
||||||
description: allGood
|
description: allGood
|
||||||
? _('Nftables checks passed')
|
? _('Nftables checks passed')
|
||||||
: _('Nftables checks partially passed'),
|
: _('Nftables checks partially passed'),
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { getSingBoxCheck } from '../../../methods';
|
import { getSingBoxCheck } from '../../../methods';
|
||||||
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck';
|
||||||
|
import { DIAGNOSTICS_CHECKS_MAP } from './contstants';
|
||||||
|
|
||||||
export async function runSingBoxCheck() {
|
export async function runSingBoxCheck() {
|
||||||
const code = 'sing_box_check';
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.SINGBOX;
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('Sing-box checks'),
|
title,
|
||||||
description: _('Checking sing-box, please wait'),
|
description: _('Checking sing-box, please wait'),
|
||||||
state: 'loading',
|
state: 'loading',
|
||||||
items: [],
|
items: [],
|
||||||
@@ -16,8 +18,9 @@ export async function runSingBoxCheck() {
|
|||||||
|
|
||||||
if (!singBoxChecks.success) {
|
if (!singBoxChecks.success) {
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('Sing-box checks'),
|
title,
|
||||||
description: _('Cannot receive Sing-box checks result'),
|
description: _('Cannot receive Sing-box checks result'),
|
||||||
state: 'error',
|
state: 'error',
|
||||||
items: [],
|
items: [],
|
||||||
@@ -59,8 +62,9 @@ export async function runSingBoxCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _('Sing-box checks'),
|
title,
|
||||||
description: _('Sing-box checks passed'),
|
description: _('Sing-box checks passed'),
|
||||||
state: getStatus(),
|
state: getStatus(),
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
86
fe-app-podkop/src/podkop/tabs/diagnostic/diagnostic.store.ts
Normal file
86
fe-app-podkop/src/podkop/tabs/diagnostic/diagnostic.store.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import {
|
||||||
|
DIAGNOSTICS_CHECKS,
|
||||||
|
DIAGNOSTICS_CHECKS_MAP,
|
||||||
|
} from './checks/contstants';
|
||||||
|
import { StoreType } from '../../../store';
|
||||||
|
|
||||||
|
export const initialDiagnosticStore: Pick<
|
||||||
|
StoreType,
|
||||||
|
'diagnosticsChecks' | 'diagnosticsRunAction'
|
||||||
|
> = {
|
||||||
|
diagnosticsRunAction: { loading: false },
|
||||||
|
diagnosticsChecks: [
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.DNS,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.DNS.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.DNS.order,
|
||||||
|
description: _('Not running'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.SINGBOX,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.SINGBOX.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.SINGBOX.order,
|
||||||
|
description: _('Not running'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.NFT,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.NFT.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.NFT.order,
|
||||||
|
description: _('Not running'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.FAKEIP,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.FAKEIP.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.FAKEIP.order,
|
||||||
|
description: _('Not running'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const loadingDiagnosticsChecksStore: Pick<
|
||||||
|
StoreType,
|
||||||
|
'diagnosticsChecks'
|
||||||
|
> = {
|
||||||
|
diagnosticsChecks: [
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.DNS,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.DNS.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.DNS.order,
|
||||||
|
description: _('Queued'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.SINGBOX,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.SINGBOX.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.SINGBOX.order,
|
||||||
|
description: _('Queued'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.NFT,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.NFT.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.NFT.order,
|
||||||
|
description: _('Queued'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: DIAGNOSTICS_CHECKS.FAKEIP,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.FAKEIP.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.FAKEIP.order,
|
||||||
|
description: _('Queued'),
|
||||||
|
items: [],
|
||||||
|
state: 'skipped',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -5,10 +5,16 @@ import { runDnsCheck } from './checks/runDnsCheck';
|
|||||||
import { runSingBoxCheck } from './checks/runSingBoxCheck';
|
import { runSingBoxCheck } from './checks/runSingBoxCheck';
|
||||||
import { runNftCheck } from './checks/runNftCheck';
|
import { runNftCheck } from './checks/runNftCheck';
|
||||||
import { runFakeIPCheck } from './checks/runFakeIPCheck';
|
import { runFakeIPCheck } from './checks/runFakeIPCheck';
|
||||||
|
import { renderDiagnosticRunAction } from './renderDiagnosticRunAction';
|
||||||
|
import { renderAvailableActions } from './renderAvailableActions';
|
||||||
|
import { renderSystemInfo } from './renderSystemInfo';
|
||||||
|
import { loadingDiagnosticsChecksStore } from './diagnostic.store';
|
||||||
|
|
||||||
async function renderDiagnosticsChecks() {
|
function renderDiagnosticsChecks() {
|
||||||
console.log('renderDiagnosticsChecks');
|
console.log('renderDiagnosticsChecks');
|
||||||
const diagnosticsChecks = store.get().diagnosticsChecks;
|
const diagnosticsChecks = store
|
||||||
|
.get()
|
||||||
|
.diagnosticsChecks.sort((a, b) => a.order - b.order);
|
||||||
const container = document.getElementById('pdk_diagnostic-page-checks');
|
const container = document.getElementById('pdk_diagnostic-page-checks');
|
||||||
|
|
||||||
const renderedDiagnosticsChecks = diagnosticsChecks.map((check) =>
|
const renderedDiagnosticsChecks = diagnosticsChecks.map((check) =>
|
||||||
@@ -20,6 +26,69 @@ async function renderDiagnosticsChecks() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderDiagnosticRunActionWidget() {
|
||||||
|
console.log('renderDiagnosticRunActionWidget');
|
||||||
|
|
||||||
|
const { loading } = store.get().diagnosticsRunAction;
|
||||||
|
const container = document.getElementById('pdk_diagnostic-page-run-check');
|
||||||
|
|
||||||
|
const renderedAction = renderDiagnosticRunAction({
|
||||||
|
loading,
|
||||||
|
click: () => runChecks(),
|
||||||
|
});
|
||||||
|
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container!.replaceChildren(renderedAction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDiagnosticAvailableActionsWidget() {
|
||||||
|
console.log('renderDiagnosticActionsWidget');
|
||||||
|
|
||||||
|
const container = document.getElementById('pdk_diagnostic-page-actions');
|
||||||
|
|
||||||
|
const renderedActions = renderAvailableActions();
|
||||||
|
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container!.replaceChildren(renderedActions);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDiagnosticSystemInfoWidget() {
|
||||||
|
console.log('renderDiagnosticSystemInfoWidget');
|
||||||
|
|
||||||
|
const container = document.getElementById('pdk_diagnostic-page-system-info');
|
||||||
|
|
||||||
|
const renderedSystemInfo = renderSystemInfo({
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
key: 'Podkop',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Luci App',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Sing-box',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'OS',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Device',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container!.replaceChildren(renderedSystemInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function onStoreUpdate(
|
async function onStoreUpdate(
|
||||||
next: StoreType,
|
next: StoreType,
|
||||||
prev: StoreType,
|
prev: StoreType,
|
||||||
@@ -28,9 +97,19 @@ async function onStoreUpdate(
|
|||||||
if (diff.diagnosticsChecks) {
|
if (diff.diagnosticsChecks) {
|
||||||
renderDiagnosticsChecks();
|
renderDiagnosticsChecks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diff.diagnosticsRunAction) {
|
||||||
|
renderDiagnosticRunActionWidget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runChecks() {
|
async function runChecks() {
|
||||||
|
try {
|
||||||
|
store.set({
|
||||||
|
diagnosticsRunAction: { loading: true },
|
||||||
|
diagnosticsChecks: loadingDiagnosticsChecksStore.diagnosticsChecks,
|
||||||
|
});
|
||||||
|
|
||||||
await runDnsCheck();
|
await runDnsCheck();
|
||||||
|
|
||||||
await runSingBoxCheck();
|
await runSingBoxCheck();
|
||||||
@@ -38,6 +117,11 @@ async function runChecks() {
|
|||||||
await runNftCheck();
|
await runNftCheck();
|
||||||
|
|
||||||
await runFakeIPCheck();
|
await runFakeIPCheck();
|
||||||
|
} catch (e) {
|
||||||
|
console.log('runChecks - e', e);
|
||||||
|
} finally {
|
||||||
|
store.set({ diagnosticsRunAction: { loading: false } });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function initDiagnosticController(): Promise<void> {
|
export async function initDiagnosticController(): Promise<void> {
|
||||||
@@ -46,13 +130,19 @@ export async function initDiagnosticController(): Promise<void> {
|
|||||||
// Remove old listener
|
// Remove old listener
|
||||||
store.unsubscribe(onStoreUpdate);
|
store.unsubscribe(onStoreUpdate);
|
||||||
|
|
||||||
// Clear store
|
|
||||||
store.reset();
|
|
||||||
|
|
||||||
// Add new listener
|
// Add new listener
|
||||||
store.subscribe(onStoreUpdate);
|
store.subscribe(onStoreUpdate);
|
||||||
|
|
||||||
// TMP run checks on mount
|
// Initial checks render
|
||||||
runChecks();
|
renderDiagnosticsChecks();
|
||||||
|
|
||||||
|
// Initial run checks action render
|
||||||
|
renderDiagnosticRunActionWidget();
|
||||||
|
|
||||||
|
// Initial available actions render
|
||||||
|
renderDiagnosticAvailableActionsWidget();
|
||||||
|
|
||||||
|
// Initial system info render
|
||||||
|
renderDiagnosticSystemInfoWidget();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export function renderAvailableActions() {
|
||||||
|
return E('div', { class: 'pdk_diagnostic-page__right-bar__actions' }, [
|
||||||
|
E('b', {}, 'Available actions'),
|
||||||
|
E('button', { class: 'btn' }, 'Restart podkop'),
|
||||||
|
E('button', { class: 'btn' }, 'Stop podkop'),
|
||||||
|
E('button', { class: 'btn' }, 'Disable podkop'),
|
||||||
|
E('button', { class: 'btn' }, 'Get global check'),
|
||||||
|
E('button', { class: 'btn' }, 'View logs'),
|
||||||
|
E('button', { class: 'btn' }, 'Show sing-box config'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -1,45 +1,15 @@
|
|||||||
export function renderDiagnostic() {
|
export function renderDiagnostic() {
|
||||||
return E(
|
return E('div', { id: 'diagnostic-status', class: 'pdk_diagnostic-page' }, [
|
||||||
'div',
|
E('div', { class: 'pdk_diagnostic-page__left-bar' }, [
|
||||||
{ id: 'diagnostic-status', class: 'pdk_diagnostic-page' },
|
E('div', { id: 'pdk_diagnostic-page-run-check' }),
|
||||||
E(
|
E('div', {
|
||||||
'div',
|
|
||||||
{
|
|
||||||
class: 'pdk_diagnostic-page__checks',
|
class: 'pdk_diagnostic-page__checks',
|
||||||
id: 'pdk_diagnostic-page-checks',
|
id: 'pdk_diagnostic-page-checks',
|
||||||
},
|
}),
|
||||||
// [
|
]),
|
||||||
// renderCheckSection({
|
E('div', { class: 'pdk_diagnostic-page__right-bar' }, [
|
||||||
// state: 'loading',
|
E('div', { id: 'pdk_diagnostic-page-actions' }),
|
||||||
// title: _('DNS Checks'),
|
E('div', { id: 'pdk_diagnostic-page-system-info' }),
|
||||||
// description: _('Checking, please wait'),
|
]),
|
||||||
// items: [],
|
]);
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'warning',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Some checks was failed'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'error',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Checks was failed'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'success',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Checks was passed'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'skipped',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Checks was skipped'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// ],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
interface IRenderDiagnosticRunActionProps {
|
||||||
|
loading: boolean;
|
||||||
|
click: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderDiagnosticRunAction({
|
||||||
|
loading,
|
||||||
|
click,
|
||||||
|
}: IRenderDiagnosticRunActionProps) {
|
||||||
|
return E('div', { class: 'pdk_diagnostic-page__run_check_wrapper' }, [
|
||||||
|
E(
|
||||||
|
'button',
|
||||||
|
{ class: 'btn', disabled: loading ? true : undefined, click },
|
||||||
|
loading ? _('Running... please wait') : _('Run Diagnostic'),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
19
fe-app-podkop/src/podkop/tabs/diagnostic/renderSystemInfo.ts
Normal file
19
fe-app-podkop/src/podkop/tabs/diagnostic/renderSystemInfo.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
interface IRenderSystemInfoProps {
|
||||||
|
items: Array<{ key: string; value: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderSystemInfo({ items }: IRenderSystemInfoProps) {
|
||||||
|
return E('div', { class: 'pdk_diagnostic-page__right-bar__system-info' }, [
|
||||||
|
E(
|
||||||
|
'b',
|
||||||
|
{ class: 'pdk_diagnostic-page__right-bar__system-info__title' },
|
||||||
|
'System information',
|
||||||
|
),
|
||||||
|
...items.map((item) =>
|
||||||
|
E('div', { class: 'pdk_diagnostic-page__right-bar__system-info__row' }, [
|
||||||
|
E('b', {}, item.key),
|
||||||
|
E('div', {}, item.value),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Podkop } from './podkop/types';
|
import { Podkop } from './podkop/types';
|
||||||
|
import { initialDiagnosticStore } from './podkop/tabs/diagnostic/diagnostic.store';
|
||||||
|
|
||||||
function jsonStableStringify<T, V>(obj: T): string {
|
function jsonStableStringify<T, V>(obj: T): string {
|
||||||
return JSON.stringify(obj, (_, value) => {
|
return JSON.stringify(obj, (_, value) => {
|
||||||
@@ -61,9 +62,17 @@ class Store<T extends Record<string, any>> {
|
|||||||
this.listeners.forEach((cb) => cb(this.value, prev, diff));
|
this.listeners.forEach((cb) => cb(this.value, prev, diff));
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(): void {
|
reset<K extends keyof T>(keys?: K[]): void {
|
||||||
const prev = this.value;
|
const prev = this.value;
|
||||||
const next = structuredClone(this.initial);
|
const next = structuredClone(this.value);
|
||||||
|
|
||||||
|
if (keys && keys.length > 0) {
|
||||||
|
keys.forEach((key) => {
|
||||||
|
next[key] = structuredClone(this.initial[key]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Object.assign(next, structuredClone(this.initial));
|
||||||
|
}
|
||||||
|
|
||||||
if (jsonEqual(prev, next)) return;
|
if (jsonEqual(prev, next)) return;
|
||||||
|
|
||||||
@@ -119,6 +128,7 @@ export interface IDiagnosticsChecksItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IDiagnosticsChecksStoreItem {
|
export interface IDiagnosticsChecksStoreItem {
|
||||||
|
order: number;
|
||||||
code: string;
|
code: string;
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
@@ -157,6 +167,9 @@ export interface StoreType {
|
|||||||
data: Podkop.OutboundGroup[];
|
data: Podkop.OutboundGroup[];
|
||||||
latencyFetching: boolean;
|
latencyFetching: boolean;
|
||||||
};
|
};
|
||||||
|
diagnosticsRunAction: {
|
||||||
|
loading: boolean;
|
||||||
|
};
|
||||||
diagnosticsChecks: Array<IDiagnosticsChecksStoreItem>;
|
diagnosticsChecks: Array<IDiagnosticsChecksStoreItem>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +204,7 @@ const initialStore: StoreType = {
|
|||||||
latencyFetching: false,
|
latencyFetching: false,
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
diagnosticsChecks: [],
|
...initialDiagnosticStore,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const store = new Store<StoreType>(initialStore);
|
export const store = new Store<StoreType>(initialStore);
|
||||||
|
|||||||
@@ -213,6 +213,62 @@ export const GlobalStyles = `
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1fr;
|
||||||
|
grid-column-gap: 10px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__actions {
|
||||||
|
border: 2px var(--background-color-low, lightgray) solid;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__system-info {
|
||||||
|
border: 2px var(--background-color-low, lightgray) solid;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__system-info__title {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__system-info__row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-column-gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__left-bar {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__run_check_wrapper {}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__run_check_wrapper button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.pdk_diagnostic-page__checks {
|
.pdk_diagnostic-page__checks {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|||||||
@@ -436,6 +436,62 @@ var GlobalStyles = `
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1fr;
|
||||||
|
grid-column-gap: 10px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__actions {
|
||||||
|
border: 2px var(--background-color-low, lightgray) solid;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__system-info {
|
||||||
|
border: 2px var(--background-color-low, lightgray) solid;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__system-info__title {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__right-bar__system-info__row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
grid-column-gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__left-bar {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__run_check_wrapper {}
|
||||||
|
|
||||||
|
.pdk_diagnostic-page__run_check_wrapper button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.pdk_diagnostic-page__checks {
|
.pdk_diagnostic-page__checks {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
@@ -1354,6 +1410,105 @@ var TabService = class _TabService {
|
|||||||
};
|
};
|
||||||
var TabServiceInstance = TabService.getInstance();
|
var TabServiceInstance = TabService.getInstance();
|
||||||
|
|
||||||
|
// src/podkop/tabs/diagnostic/checks/contstants.ts
|
||||||
|
var DIAGNOSTICS_CHECKS_MAP = {
|
||||||
|
["DNS" /* DNS */]: {
|
||||||
|
order: 1,
|
||||||
|
title: _("DNS checks"),
|
||||||
|
code: "DNS" /* DNS */
|
||||||
|
},
|
||||||
|
["SINGBOX" /* SINGBOX */]: {
|
||||||
|
order: 2,
|
||||||
|
title: _("Sing-box checks"),
|
||||||
|
code: "SINGBOX" /* SINGBOX */
|
||||||
|
},
|
||||||
|
["NFT" /* NFT */]: {
|
||||||
|
order: 3,
|
||||||
|
title: _("Nftables checks"),
|
||||||
|
code: "NFT" /* NFT */
|
||||||
|
},
|
||||||
|
["FAKEIP" /* FAKEIP */]: {
|
||||||
|
order: 4,
|
||||||
|
title: _("FakeIP checks"),
|
||||||
|
code: "FAKEIP" /* FAKEIP */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/podkop/tabs/diagnostic/diagnostic.store.ts
|
||||||
|
var initialDiagnosticStore = {
|
||||||
|
diagnosticsRunAction: { loading: false },
|
||||||
|
diagnosticsChecks: [
|
||||||
|
{
|
||||||
|
code: "DNS" /* DNS */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.DNS.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.DNS.order,
|
||||||
|
description: _("Not running"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "SINGBOX" /* SINGBOX */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.SINGBOX.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.SINGBOX.order,
|
||||||
|
description: _("Not running"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "NFT" /* NFT */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.NFT.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.NFT.order,
|
||||||
|
description: _("Not running"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "FAKEIP" /* FAKEIP */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.FAKEIP.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.FAKEIP.order,
|
||||||
|
description: _("Not running"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
var loadingDiagnosticsChecksStore = {
|
||||||
|
diagnosticsChecks: [
|
||||||
|
{
|
||||||
|
code: "DNS" /* DNS */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.DNS.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.DNS.order,
|
||||||
|
description: _("Queued"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "SINGBOX" /* SINGBOX */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.SINGBOX.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.SINGBOX.order,
|
||||||
|
description: _("Queued"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "NFT" /* NFT */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.NFT.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.NFT.order,
|
||||||
|
description: _("Queued"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "FAKEIP" /* FAKEIP */,
|
||||||
|
title: DIAGNOSTICS_CHECKS_MAP.FAKEIP.title,
|
||||||
|
order: DIAGNOSTICS_CHECKS_MAP.FAKEIP.order,
|
||||||
|
description: _("Queued"),
|
||||||
|
items: [],
|
||||||
|
state: "skipped"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
// src/store.ts
|
// src/store.ts
|
||||||
function jsonStableStringify(obj) {
|
function jsonStableStringify(obj) {
|
||||||
return JSON.stringify(obj, (_2, value) => {
|
return JSON.stringify(obj, (_2, value) => {
|
||||||
@@ -1399,9 +1554,16 @@ var Store = class {
|
|||||||
}
|
}
|
||||||
this.listeners.forEach((cb) => cb(this.value, prev, diff));
|
this.listeners.forEach((cb) => cb(this.value, prev, diff));
|
||||||
}
|
}
|
||||||
reset() {
|
reset(keys) {
|
||||||
const prev = this.value;
|
const prev = this.value;
|
||||||
const next = structuredClone(this.initial);
|
const next = structuredClone(this.value);
|
||||||
|
if (keys && keys.length > 0) {
|
||||||
|
keys.forEach((key) => {
|
||||||
|
next[key] = structuredClone(this.initial[key]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Object.assign(next, structuredClone(this.initial));
|
||||||
|
}
|
||||||
if (jsonEqual(prev, next)) return;
|
if (jsonEqual(prev, next)) return;
|
||||||
this.value = next;
|
this.value = next;
|
||||||
this.lastHash = jsonStableStringify(next);
|
this.lastHash = jsonStableStringify(next);
|
||||||
@@ -1468,7 +1630,7 @@ var initialStore = {
|
|||||||
latencyFetching: false,
|
latencyFetching: false,
|
||||||
data: []
|
data: []
|
||||||
},
|
},
|
||||||
diagnosticsChecks: []
|
...initialDiagnosticStore
|
||||||
};
|
};
|
||||||
var store = new Store(initialStore);
|
var store = new Store(initialStore);
|
||||||
|
|
||||||
@@ -2163,7 +2325,13 @@ async function onStoreUpdate(next, prev, diff) {
|
|||||||
async function initDashboardController() {
|
async function initDashboardController() {
|
||||||
onMount("dashboard-status").then(() => {
|
onMount("dashboard-status").then(() => {
|
||||||
store.unsubscribe(onStoreUpdate);
|
store.unsubscribe(onStoreUpdate);
|
||||||
store.reset();
|
store.reset([
|
||||||
|
"bandwidthWidget",
|
||||||
|
"trafficTotalWidget",
|
||||||
|
"systemInfoWidget",
|
||||||
|
"servicesInfoWidget",
|
||||||
|
"sectionsWidget"
|
||||||
|
]);
|
||||||
store.subscribe(onStoreUpdate);
|
store.subscribe(onStoreUpdate);
|
||||||
fetchDashboardSections();
|
fetchDashboardSections();
|
||||||
fetchServicesInfo();
|
fetchServicesInfo();
|
||||||
@@ -2173,49 +2341,19 @@ async function initDashboardController() {
|
|||||||
|
|
||||||
// src/podkop/tabs/diagnostic/renderDiagnostic.ts
|
// src/podkop/tabs/diagnostic/renderDiagnostic.ts
|
||||||
function renderDiagnostic() {
|
function renderDiagnostic() {
|
||||||
return E(
|
return E("div", { id: "diagnostic-status", class: "pdk_diagnostic-page" }, [
|
||||||
"div",
|
E("div", { class: "pdk_diagnostic-page__left-bar" }, [
|
||||||
{ id: "diagnostic-status", class: "pdk_diagnostic-page" },
|
E("div", { id: "pdk_diagnostic-page-run-check" }),
|
||||||
E(
|
E("div", {
|
||||||
"div",
|
|
||||||
{
|
|
||||||
class: "pdk_diagnostic-page__checks",
|
class: "pdk_diagnostic-page__checks",
|
||||||
id: "pdk_diagnostic-page-checks"
|
id: "pdk_diagnostic-page-checks"
|
||||||
}
|
})
|
||||||
// [
|
]),
|
||||||
// renderCheckSection({
|
E("div", { class: "pdk_diagnostic-page__right-bar" }, [
|
||||||
// state: 'loading',
|
E("div", { id: "pdk_diagnostic-page-actions" }),
|
||||||
// title: _('DNS Checks'),
|
E("div", { id: "pdk_diagnostic-page-system-info" })
|
||||||
// description: _('Checking, please wait'),
|
])
|
||||||
// items: [],
|
]);
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'warning',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Some checks was failed'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'error',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Checks was failed'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'success',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Checks was passed'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// renderCheckSection({
|
|
||||||
// state: 'skipped',
|
|
||||||
// title: _('DNS Checks'),
|
|
||||||
// description: _('Checks was skipped'),
|
|
||||||
// items: [],
|
|
||||||
// }),
|
|
||||||
// ],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/icons/renderLoaderCircleIcon24.ts
|
// src/icons/renderLoaderCircleIcon24.ts
|
||||||
@@ -2625,10 +2763,11 @@ function updateDiagnosticsCheck(check, minified) {
|
|||||||
|
|
||||||
// src/podkop/tabs/diagnostic/checks/runDnsCheck.ts
|
// src/podkop/tabs/diagnostic/checks/runDnsCheck.ts
|
||||||
async function runDnsCheck() {
|
async function runDnsCheck() {
|
||||||
const code = "dns_check";
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.DNS;
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("DNS checks"),
|
title,
|
||||||
description: _("Checking dns, please wait"),
|
description: _("Checking dns, please wait"),
|
||||||
state: "loading",
|
state: "loading",
|
||||||
items: []
|
items: []
|
||||||
@@ -2636,8 +2775,9 @@ async function runDnsCheck() {
|
|||||||
const dnsChecks = await getDNSCheck();
|
const dnsChecks = await getDNSCheck();
|
||||||
if (!dnsChecks.success) {
|
if (!dnsChecks.success) {
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("DNS checks"),
|
title,
|
||||||
description: _("Cannot receive DNS checks result"),
|
description: _("Cannot receive DNS checks result"),
|
||||||
state: "error",
|
state: "error",
|
||||||
items: []
|
items: []
|
||||||
@@ -2658,8 +2798,9 @@ async function runDnsCheck() {
|
|||||||
return "error";
|
return "error";
|
||||||
}
|
}
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("DNS checks"),
|
title,
|
||||||
description: _("DNS checks passed"),
|
description: _("DNS checks passed"),
|
||||||
state: getStatus(),
|
state: getStatus(),
|
||||||
items: [
|
items: [
|
||||||
@@ -2692,10 +2833,11 @@ async function runDnsCheck() {
|
|||||||
|
|
||||||
// src/podkop/tabs/diagnostic/checks/runSingBoxCheck.ts
|
// src/podkop/tabs/diagnostic/checks/runSingBoxCheck.ts
|
||||||
async function runSingBoxCheck() {
|
async function runSingBoxCheck() {
|
||||||
const code = "sing_box_check";
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.SINGBOX;
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("Sing-box checks"),
|
title,
|
||||||
description: _("Checking sing-box, please wait"),
|
description: _("Checking sing-box, please wait"),
|
||||||
state: "loading",
|
state: "loading",
|
||||||
items: []
|
items: []
|
||||||
@@ -2703,8 +2845,9 @@ async function runSingBoxCheck() {
|
|||||||
const singBoxChecks = await getSingBoxCheck();
|
const singBoxChecks = await getSingBoxCheck();
|
||||||
if (!singBoxChecks.success) {
|
if (!singBoxChecks.success) {
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("Sing-box checks"),
|
title,
|
||||||
description: _("Cannot receive Sing-box checks result"),
|
description: _("Cannot receive Sing-box checks result"),
|
||||||
state: "error",
|
state: "error",
|
||||||
items: []
|
items: []
|
||||||
@@ -2725,8 +2868,9 @@ async function runSingBoxCheck() {
|
|||||||
return "error";
|
return "error";
|
||||||
}
|
}
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("Sing-box checks"),
|
title,
|
||||||
description: _("Sing-box checks passed"),
|
description: _("Sing-box checks passed"),
|
||||||
state: getStatus(),
|
state: getStatus(),
|
||||||
items: [
|
items: [
|
||||||
@@ -2797,10 +2941,11 @@ async function getFakeIpCheck() {
|
|||||||
|
|
||||||
// src/podkop/tabs/diagnostic/checks/runNftCheck.ts
|
// src/podkop/tabs/diagnostic/checks/runNftCheck.ts
|
||||||
async function runNftCheck() {
|
async function runNftCheck() {
|
||||||
const code = "nft_check";
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.NFT;
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("Nftables checks"),
|
title,
|
||||||
description: _("Checking nftables, please wait"),
|
description: _("Checking nftables, please wait"),
|
||||||
state: "loading",
|
state: "loading",
|
||||||
items: []
|
items: []
|
||||||
@@ -2810,8 +2955,9 @@ async function runNftCheck() {
|
|||||||
const nftablesChecks = await getNftRulesCheck();
|
const nftablesChecks = await getNftRulesCheck();
|
||||||
if (!nftablesChecks.success) {
|
if (!nftablesChecks.success) {
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("Nftables checks"),
|
title,
|
||||||
description: _("Cannot receive nftables checks result"),
|
description: _("Cannot receive nftables checks result"),
|
||||||
state: "error",
|
state: "error",
|
||||||
items: []
|
items: []
|
||||||
@@ -2832,8 +2978,9 @@ async function runNftCheck() {
|
|||||||
return "error";
|
return "error";
|
||||||
}
|
}
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("Nftables checks"),
|
title,
|
||||||
description: allGood ? _("Nftables checks passed") : _("Nftables checks partially passed"),
|
description: allGood ? _("Nftables checks passed") : _("Nftables checks partially passed"),
|
||||||
state: getStatus(),
|
state: getStatus(),
|
||||||
items: [
|
items: [
|
||||||
@@ -2886,10 +3033,11 @@ async function runNftCheck() {
|
|||||||
|
|
||||||
// src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts
|
// src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts
|
||||||
async function runFakeIPCheck() {
|
async function runFakeIPCheck() {
|
||||||
const code = "fake_ip_check";
|
const { order, title, code } = DIAGNOSTICS_CHECKS_MAP.FAKEIP;
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("FakeIP checks"),
|
title,
|
||||||
description: _("Checking FakeIP, please wait"),
|
description: _("Checking FakeIP, please wait"),
|
||||||
state: "loading",
|
state: "loading",
|
||||||
items: []
|
items: []
|
||||||
@@ -2930,8 +3078,9 @@ async function runFakeIPCheck() {
|
|||||||
}
|
}
|
||||||
const { state, description } = getMeta();
|
const { state, description } = getMeta();
|
||||||
updateDiagnosticsCheck({
|
updateDiagnosticsCheck({
|
||||||
|
order,
|
||||||
code,
|
code,
|
||||||
title: _("FakeIP checks"),
|
title,
|
||||||
description,
|
description,
|
||||||
state,
|
state,
|
||||||
items: [
|
items: [
|
||||||
@@ -2956,10 +3105,54 @@ async function runFakeIPCheck() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// src/podkop/tabs/diagnostic/renderDiagnosticRunAction.ts
|
||||||
|
function renderDiagnosticRunAction({
|
||||||
|
loading,
|
||||||
|
click
|
||||||
|
}) {
|
||||||
|
return E("div", { class: "pdk_diagnostic-page__run_check_wrapper" }, [
|
||||||
|
E(
|
||||||
|
"button",
|
||||||
|
{ class: "btn", disabled: loading ? true : void 0, click },
|
||||||
|
loading ? _("Running... please wait") : _("Run Diagnostic")
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// src/podkop/tabs/diagnostic/renderAvailableActions.ts
|
||||||
|
function renderAvailableActions() {
|
||||||
|
return E("div", { class: "pdk_diagnostic-page__right-bar__actions" }, [
|
||||||
|
E("b", {}, "Available actions"),
|
||||||
|
E("button", { class: "btn" }, "Restart podkop"),
|
||||||
|
E("button", { class: "btn" }, "Stop podkop"),
|
||||||
|
E("button", { class: "btn" }, "Disable podkop"),
|
||||||
|
E("button", { class: "btn" }, "Get global check"),
|
||||||
|
E("button", { class: "btn" }, "View logs"),
|
||||||
|
E("button", { class: "btn" }, "Show sing-box config")
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// src/podkop/tabs/diagnostic/renderSystemInfo.ts
|
||||||
|
function renderSystemInfo({ items }) {
|
||||||
|
return E("div", { class: "pdk_diagnostic-page__right-bar__system-info" }, [
|
||||||
|
E(
|
||||||
|
"b",
|
||||||
|
{ class: "pdk_diagnostic-page__right-bar__system-info__title" },
|
||||||
|
"System information"
|
||||||
|
),
|
||||||
|
...items.map(
|
||||||
|
(item) => E("div", { class: "pdk_diagnostic-page__right-bar__system-info__row" }, [
|
||||||
|
E("b", {}, item.key),
|
||||||
|
E("div", {}, item.value)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
// src/podkop/tabs/diagnostic/initDiagnosticController.ts
|
// src/podkop/tabs/diagnostic/initDiagnosticController.ts
|
||||||
async function renderDiagnosticsChecks() {
|
function renderDiagnosticsChecks() {
|
||||||
console.log("renderDiagnosticsChecks");
|
console.log("renderDiagnosticsChecks");
|
||||||
const diagnosticsChecks = store.get().diagnosticsChecks;
|
const diagnosticsChecks = store.get().diagnosticsChecks.sort((a, b) => a.order - b.order);
|
||||||
const container = document.getElementById("pdk_diagnostic-page-checks");
|
const container = document.getElementById("pdk_diagnostic-page-checks");
|
||||||
const renderedDiagnosticsChecks = diagnosticsChecks.map(
|
const renderedDiagnosticsChecks = diagnosticsChecks.map(
|
||||||
(check) => renderCheckSection(check)
|
(check) => renderCheckSection(check)
|
||||||
@@ -2968,24 +3161,90 @@ async function renderDiagnosticsChecks() {
|
|||||||
container.replaceChildren(...renderedDiagnosticsChecks);
|
container.replaceChildren(...renderedDiagnosticsChecks);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function renderDiagnosticRunActionWidget() {
|
||||||
|
console.log("renderDiagnosticRunActionWidget");
|
||||||
|
const { loading } = store.get().diagnosticsRunAction;
|
||||||
|
const container = document.getElementById("pdk_diagnostic-page-run-check");
|
||||||
|
const renderedAction = renderDiagnosticRunAction({
|
||||||
|
loading,
|
||||||
|
click: () => runChecks()
|
||||||
|
});
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container.replaceChildren(renderedAction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function renderDiagnosticAvailableActionsWidget() {
|
||||||
|
console.log("renderDiagnosticActionsWidget");
|
||||||
|
const container = document.getElementById("pdk_diagnostic-page-actions");
|
||||||
|
const renderedActions = renderAvailableActions();
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container.replaceChildren(renderedActions);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function renderDiagnosticSystemInfoWidget() {
|
||||||
|
console.log("renderDiagnosticSystemInfoWidget");
|
||||||
|
const container = document.getElementById("pdk_diagnostic-page-system-info");
|
||||||
|
const renderedSystemInfo = renderSystemInfo({
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
key: "Podkop",
|
||||||
|
value: "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "Luci App",
|
||||||
|
value: "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "Sing-box",
|
||||||
|
value: "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "OS",
|
||||||
|
value: "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "Device",
|
||||||
|
value: "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
return preserveScrollForPage(() => {
|
||||||
|
container.replaceChildren(renderedSystemInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
async function onStoreUpdate2(next, prev, diff) {
|
async function onStoreUpdate2(next, prev, diff) {
|
||||||
if (diff.diagnosticsChecks) {
|
if (diff.diagnosticsChecks) {
|
||||||
renderDiagnosticsChecks();
|
renderDiagnosticsChecks();
|
||||||
}
|
}
|
||||||
|
if (diff.diagnosticsRunAction) {
|
||||||
|
renderDiagnosticRunActionWidget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async function runChecks() {
|
async function runChecks() {
|
||||||
|
try {
|
||||||
|
store.set({
|
||||||
|
diagnosticsRunAction: { loading: true },
|
||||||
|
diagnosticsChecks: loadingDiagnosticsChecksStore.diagnosticsChecks
|
||||||
|
});
|
||||||
await runDnsCheck();
|
await runDnsCheck();
|
||||||
await runSingBoxCheck();
|
await runSingBoxCheck();
|
||||||
await runNftCheck();
|
await runNftCheck();
|
||||||
await runFakeIPCheck();
|
await runFakeIPCheck();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("runChecks - e", e);
|
||||||
|
} finally {
|
||||||
|
store.set({ diagnosticsRunAction: { loading: false } });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async function initDiagnosticController() {
|
async function initDiagnosticController() {
|
||||||
onMount("diagnostic-status").then(() => {
|
onMount("diagnostic-status").then(() => {
|
||||||
console.log("diagnostic controller initialized.");
|
console.log("diagnostic controller initialized.");
|
||||||
store.unsubscribe(onStoreUpdate2);
|
store.unsubscribe(onStoreUpdate2);
|
||||||
store.reset();
|
|
||||||
store.subscribe(onStoreUpdate2);
|
store.subscribe(onStoreUpdate2);
|
||||||
runChecks();
|
renderDiagnosticsChecks();
|
||||||
|
renderDiagnosticRunActionWidget();
|
||||||
|
renderDiagnosticAvailableActionsWidget();
|
||||||
|
renderDiagnosticSystemInfoWidget();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return baseclass.extend({
|
return baseclass.extend({
|
||||||
|
|||||||
Reference in New Issue
Block a user