Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
82f6a03
Code. React. Partially done settings_general
alexandergull Dec 26, 2025
31495ac
Merge branch 'dev' into react-settings-tab.ag
alexandergull Jan 31, 2026
2da3c96
Rebuild react after dev in-merge.
alexandergull Jan 31, 2026
6da1b93
Upd. React. Tab `Settings` refactoring started.
Glomberg Feb 13, 2026
cb3d356
Fix. React. `SettingApiKey` component fixed.
Glomberg Feb 19, 2026
22c88fd
Merge remote-tracking branch 'origin/dev' into react-settings-tab.ag
Glomberg Feb 19, 2026
8ae283f
Fix. Settings. Setting overview block rebuilt to react component.
Glomberg Feb 20, 2026
44e19c4
Merge remote-tracking branch 'origin/dev' into Fix-Settings-overview-…
Glomberg Feb 20, 2026
b18704e
Fix. Code. Code style fixed.
Glomberg Feb 20, 2026
0629953
Merge remote-tracking branch 'origin/dev' into react-settings-tab.ag
Glomberg Feb 20, 2026
bcd8651
Fix. Settings. Setting overview block rebuilt to react component.
Glomberg Feb 20, 2026
0803619
Fix. Code. Code style fixed.
Glomberg Feb 20, 2026
7cf0669
Code. React. Partially done settings_general
alexandergull Dec 26, 2025
52169cd
Upd. React. Tab `Settings` refactoring started.
Glomberg Feb 13, 2026
27aef47
Fix. Code. To-do added.
Glomberg Feb 20, 2026
5491223
Fix. Settings. Notice banner moved out from form settings.
Glomberg Feb 20, 2026
5bc598b
Fix. Code. Re-build JS.
Glomberg Feb 20, 2026
bc748e3
Merge remote-tracking branch 'origin/dev' into Fix-Settings-overview-…
Glomberg Feb 20, 2026
689252d
Fix. Code. CSS re-minify.
Glomberg Feb 20, 2026
beb0c76
Merge remote-tracking branch 'origin/Fix-Settings-overview-Rebuld-to-…
Glomberg Feb 20, 2026
e8e8987
Fix. Settings. React components fixed.
Glomberg Feb 20, 2026
db71d6f
Fix. Settings. React - getting data for `api_key` block fixed.
Glomberg Feb 20, 2026
1ba3d67
Fix. Settings. React - Context implemented to transfer `dataRoot` obj…
Glomberg Feb 20, 2026
c15166c
Fix. Settings. React - Context implemented to transfer `dataTabs` obj…
Glomberg Feb 20, 2026
095342d
Fix. Settings. React - Settings Api key continue.
Glomberg Feb 21, 2026
42a5d34
Code. React. Partially done settings_general
alexandergull Dec 26, 2025
0ca8b72
Upd. React. Tab `Settings` refactoring started.
Glomberg Feb 13, 2026
7805158
Fix. Settings. Setting overview block rebuilt to react component.
Glomberg Feb 20, 2026
6107c8a
Fix. Settings. React - Settings Api key continue #2.
Glomberg Feb 22, 2026
c5d4e08
Fix. Settings. React - Settings Api key continue #3.
Glomberg Feb 23, 2026
a7d7bb4
Fix. Settings. React - Settings Api key continue #3.
Glomberg Feb 24, 2026
453294f
Merge remote-tracking branch 'origin/dev' into react-settings-tab.ag
Glomberg Feb 24, 2026
06730e1
Fix. Code. Re-minify JS.
Glomberg Feb 24, 2026
a588ca5
Fix. Settings. React - Settings Api key continue #4.
Glomberg Feb 24, 2026
a53ce71
Fix. Settings. React - Settings Api key WPMS settings (wpms mode, hos…
Glomberg Feb 24, 2026
1202798
Fix. Code. ToDo added - Is `ms__service_utilization` actual?
Glomberg Feb 24, 2026
1947eaa
Fix. Settings. React - WPMS settings render login fixed.
Glomberg Feb 24, 2026
03a88b2
Fix. Settings. React - WPMS settings render login fixed #2.
Glomberg Feb 24, 2026
d769bda
Merge remote-tracking branch 'origin/dev' into react-settings-tab.ag
Glomberg Feb 27, 2026
4eccedd
Fix. Settings. React - Quick nav bar styles fixed.
Glomberg Feb 27, 2026
6079f69
Fix. Settings. Getting key auto fixed.
Glomberg Feb 27, 2026
0d14e35
Fix. Settings. React - get settings from backend fixed.
Glomberg Feb 27, 2026
63319d3
Revert "Fix. Settings. Getting key auto fixed."
Glomberg Feb 27, 2026
79b5061
Fix. Code. Remove unused code.
Glomberg Feb 27, 2026
2d86c8b
Fix. Code. Checking existence `spbcModal`.
Glomberg Feb 27, 2026
16f0fd7
Fix. Code. JS attributes fixed.
Glomberg Feb 27, 2026
e0a9518
Fix. Code. JS attributes fixed #2.
Glomberg Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion css/spbc-settings.min.css

Large diffs are not rendered by default.

49 changes: 0 additions & 49 deletions css/src/spbc-settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,6 @@ div.pagination{
width: 500px;
}


/* Show/hide key link */
#showHideLink{
display: inline-block;
margin-top: 5px;
color: #777;
}

/* Log button */
.spbc__wrapper--center{margin: 10px 0 10px 0; text-align: center;}

Expand Down Expand Up @@ -805,47 +797,6 @@ button#spbc_setting_get_key_auto:disabled {
flex-grow: 1;
}

.spbc-quicknav--bar_wrapper {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
height: fit-content;
position: sticky;
top: 5vh;
}

.spbc-quicknav--links_wrapper {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: center;
padding: 3px;
border: 1px solid #e5e5e5;
margin: 10px;
}

.spbc-quicknav--link{
margin: 3px;
width: -webkit-fill-available;
width: -moz-available;
text-align: left;
display: flex;
flex-direction: row;
justify-content: flex-start;
}

#spbc_quicknav--header {
color: #026E88;
text-align: center;
margin: 5px 0;
}

.spbc_quicknav--save_button {
margin: 10px 5px !important;
height: 40px;
}

.spbc_settings--save_button_custom {
position: sticky;
bottom: 0;
Expand Down
4 changes: 4 additions & 0 deletions inc/spbc-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use CleantalkSP\SpbctWP\DTO\ReactDataDTO;
use CleantalkSP\SpbctWP\Escape;
use CleantalkSP\SpbctWP\Scanner\DBTrigger\DBTriggerService;
use CleantalkSP\SpbctWP\Settings\SettingsGeneralReact;
use CleantalkSP\SpbctWP\VulnerabilityAlarm\Dto\PluginReport;
use CleantalkSP\SpbctWP\Firewall\View as FirewallView;
use CleantalkSP\SpbctWP\VulnerabilityAlarm\Dto\ThemeReport;
Expand Down Expand Up @@ -226,6 +227,9 @@ function spbct_get_tab_data()
case 'traffic_control':
wp_send_json(FirewallView::getReactData($data));
break;
case 'settings_general':
wp_send_json(SettingsGeneralReact::getReactData());
break;
case 'spbct_settings_overview':
wp_send_json(spbc_field_options_overview_traffic_light());
break;
Expand Down
92 changes: 1 addition & 91 deletions inc/spbc-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,71 +203,6 @@ function spbc_settings__register()
'ajax' => true,
'after' => 'spbc_settings_draw_save_button_bottom_block',
'sections' => array(
'section_top_banner' => array(
'type' => 'section_banner',
'fields' => array(
'security_log' => array(
'type' => 'field',
),
),
),
'apikey' => array(
'type' => 'section',
'title' => __('Access Key', 'security-malware-firewall'),
'anchor' => 'apikey',
'fields' => array(
'apikey' => array(
'type' => 'field',
'callback' => 'spbc_field_key'
),
'ms__work_mode' => array(
'type' => 'field',
'input_type' => 'select',
'options' => array(
array(
'val' => 1,
'label' => __('Mutual Account, Individual Access Keys', 'security-malware-firewall'),
'children_enable' => 1,
),
array(
'val' => 2,
'label' => __('Mutual Account, Mutual Access Key', 'security-malware-firewall'),
'children_enable' => 0,
),
array(
'val' => 3,
'label' => __('Individual accounts, individual Access keys', 'security-malware-firewall'),
'children_enable' => 0,
),
),
'title' => __('WordPress Multisite Work Mode', 'security-malware-firewall'),
'description' => __('You can choose the work mode here for the child blogs and how they will operate with the CleanTalk Cloud. Press "?" for the detailed description.', 'security-malware-firewall'),
'long_description' => true,
'display' => $spbc->is_network && $spbc->is_mainsite,
'children' => array('ms__hoster_api_key'),
'value_source' => 'network_settings',
),
'ms__hoster_api_key' => array(
'type' => 'field',
'input_type' => 'text',
'title' => __('Hoster access key', 'security-malware-firewall'),
'description' => __('Another API allowing you to hold multiple blogs on on account.', 'security-malware-firewall'),
'class' => 'spbc_middle_text_field',
'title_first' => true,
'long_description' => true,
'display' => $spbc->is_network && $spbc->is_mainsite,
'disabled' => ! isset($spbc->network_settings['ms__work_mode']) || $spbc->network_settings['ms__work_mode'] != 1,
'value_source' => 'network_settings',
'parent_value_source' => 'network_settings',
'parent' => 'ms__work_mode',
),
'ms__service_utilization' => array(
'type' => 'field',
'callback' => 'spbc_field_service_utilization',
'display' => $spbc->is_network && $spbc->is_mainsite && $spbc->ms__work_mode == 1,
),
),
),
'auth' => array(
'type' => 'section',
'title' => __('Authentication and Logging In', 'security-malware-firewall'),
Expand Down Expand Up @@ -1395,32 +1330,7 @@ function spbct_settings__the_settings_tab_draw($elem)
$settings_content = ob_get_clean();
// End buffer

$template = '
<div id="spbc-settings-general-wrapper" class="spbc-settings-general-wrapper">
<div id="spbc-settings-general-wrapper-settings">
%s
</div>
<div id="spbc-quicknav--bar_wrapper" class="spbc-quicknav--bar_wrapper">
%s
</div>
</div>
';

// Settings form elements here
echo '<form id="spbc_settings_form" method="post" action="options.php" style="margin-right: 12px; margin-top: -9px;">';

// Service fields
echo "<input type='hidden' name='option_page' value='" . esc_attr(SPBC_SETTINGS) . "' />";
echo '<input type="hidden" name="action" value="update" />';
wp_nonce_field(SPBC_SETTINGS . '-options', '_wpnonce', false);

echo sprintf(
$template,
$settings_content,
spbc_settings__get_quick_navbar_html($elem)
);

echo '</form>';
echo $settings_content;
}

/**
Expand Down
100 changes: 95 additions & 5 deletions js/public/spbct-react-bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/spbc-settings.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/spbc-settings.min.js.map

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions js/src/react/components/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React from 'react';
import React, {createContext} from 'react';
import Header from '../pageElements/Header/Header';
import ServiceButtons from '../pageElements/ServiceButtons/ServiceButtons';
import HiddenElements from '../pageElements/HiddenElements/HiddenElements';
import Tabs from '../pageElements/Tabs/Tabs';

export const DataRootContext = createContext(null);
export const DataTabsContext = createContext(null);

export default function App({dataRoot, dataTabs}) {
if (!dataRoot) {
return <div>Loading...</div>;
Expand All @@ -20,11 +23,13 @@ export default function App({dataRoot, dataTabs}) {
}

return (
<>
<Header data={dataRoot} />
<ServiceButtons />
<HiddenElements data={dataRoot} />
<Tabs data={dataTabs} />
</>
<DataRootContext.Provider value={dataRoot}>
<DataTabsContext.Provider value={dataTabs}>
<Header data={dataRoot} />
<ServiceButtons />
<HiddenElements data={dataRoot} />
<Tabs data={dataTabs} />
</DataTabsContext.Provider>
</DataRootContext.Provider>
);
}
21 changes: 21 additions & 0 deletions js/src/react/components/FormElements/InputHidden.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from "react";

export default function InputHidden(props) {
const {id, name, value} = props;
const sanitize = (str) => {
if (typeof str !== 'string') return str;
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#x27;')
.replace(/\//g, '&#x2F;');
};
return <input
type='hidden'
id={sanitize(id)}
name={sanitize(name)}
value={sanitize(value)}
/>;
}
33 changes: 33 additions & 0 deletions js/src/react/components/FormElements/InputText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, {useState} from "react";

export default function InputText(props) {
const {id, name, value: initialValue = '', placeholder, onChange, style} = props;
const [inputValue, setInputValue] = useState(initialValue);
const sanitize = (str) => {
if (typeof str !== 'string') return str;
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#x27;')
.replace(/\//g, '&#x2F;');
};
const handleChange = (e) => {
const newValue = e.target.value;
setInputValue(newValue);
// Call `onChange` from props, if exists
if (onChange) {
onChange(e);
}
};
return <input
type='text'
id={sanitize(id)}
name={sanitize(name)}
value={inputValue}
placeholder={sanitize(placeholder) || ''}
style={style || {}}
onChange={handleChange}
/>;
}
60 changes: 60 additions & 0 deletions js/src/react/components/FormElements/Select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useState, useEffect } from 'react';

export default function Select({
id,
name,
value: initialValue,
options = [],
onChange,
className = '',
disabled = false,
placeholder = '',
...props
}) {
const [selectedValue, setSelectedValue] = useState(initialValue || '');

useEffect(() => {
if (initialValue !== undefined) {
setSelectedValue(initialValue);
}
}, [initialValue]);

const handleChange = (event) => {
const newValue = event.target.value;
setSelectedValue(newValue);

// Call `onChange` from props, if exists
if (onChange) {
onChange(event);
}
};

return (
<select
id={id}
name={name}
value={selectedValue}
onChange={handleChange}
className={className}
disabled={disabled}
{...props}
>
{placeholder && (
<option value="" disabled>
{placeholder}
</option>
)}

{options.map((option) => (
<option
key={option.value}
value={option.value}
disabled={option.disabled}
{...option.dataAttributes}
>
{option.label}
</option>
))}
</select>
);
}
5 changes: 3 additions & 2 deletions js/src/react/components/SettingsOverview/SettingsOverview.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import './styles.css';
import Preloader from "../Preloader/Preloader";
import {sendAjaxRequest} from "../../modules/Http/Ajax";

export default function SettingsOverview() {
export default function SettingsOverview({settings}) {
const [settingsOverviewFetched, setSettingsOverviewFetched] = useState(false);
const [settingsOverview, setSettingsOverview] = useState(null);

useEffect(() => {
if ( ! settingsOverview ) {
// @ToDo use settings property instead of separate ajax-call
fetchSettingsOverview();
}
}, []);
Expand Down Expand Up @@ -92,4 +93,4 @@ export default function SettingsOverview() {
</div>
</div>
</div>;
}
}
9 changes: 7 additions & 2 deletions js/src/react/components/TabContent/TabContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import Preloader from '../Preloader/Preloader';
import {sendAjaxRequest} from '../../modules/Http/Ajax';
import TabDefault from './TabDefault/TabDefault';

export default function TabContent({sectionId, isActive, tabComponent}) {
export default function TabContent({sectionId, isActive, tabComponent, tabsData}) {
const [sectionData, setSectionData] = useState(null);

useEffect(() => {
if (isActive && !sectionData) {
if ( sectionId === 'critical_updates' || sectionId === 'fswatcher' || sectionId === 'traffic_control' ) {
if (
sectionId === 'critical_updates' ||
sectionId === 'fswatcher' ||
sectionId === 'traffic_control' ||
sectionId === 'general_settings'
) {
fetchContent();
} else {
fetchContentOld();
Expand Down
Loading