Skip to content

Commit d3397a4

Browse files
authored
Merge pull request #23 from rtCamp/feature/auto-mu-configurations
Feature: auto multisite detection/configurations
2 parents ae26d93 + ef3ff7c commit d3397a4

35 files changed

+2232
-864
lines changed

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"_": true,
1414
"patternSyncData": true,
1515
"TemplateLibraryData": true,
16-
"OneDesignSettings": true
16+
"OneDesignSettings": true,
17+
"OneDesignMultiSiteSettings": true
1718
},
1819
"rules": {
1920
"jsdoc/check-indentation": "error",
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { useState, useEffect, createRoot, useCallback, useRef } from '@wordpress/element';
5+
import { __ } from '@wordpress/i18n';
6+
import { Card, CardHeader, CardBody, Notice, Button, SelectControl } from '@wordpress/components';
7+
8+
/**
9+
* Global variable from PHP
10+
*/
11+
import { MULTISITES, API_NAMESPACE, NONCE } from '../../js/constants';
12+
13+
/**
14+
* SiteTypeSelector component for selecting site type.
15+
*
16+
* @param {Object} props - Component properties.
17+
* @param {string} props.value - Current selected value.
18+
* @param {Function} props.setGoverningSite - Function to set governing site.
19+
*
20+
* @return {JSX.Element} Rendered component.
21+
*/
22+
const SiteTypeSelector = ( { value, setGoverningSite } ) => (
23+
<SelectControl
24+
label={ __( 'Select Governing Site', 'onedesign' ) }
25+
value={ value }
26+
help={ __( 'Choose governing site from current multisite network. Other sites will be set as brand sites. This setting cannot be changed later and affects available features and configurations.', 'onedesign' ) }
27+
onChange={ ( v ) => {
28+
setGoverningSite( v );
29+
} }
30+
options={ [
31+
{ label: __( 'Select…', 'onedesign' ), value: '' },
32+
...MULTISITES.map( ( site ) => ( { label: site.name, value: site.id } ) ),
33+
] }
34+
/>
35+
);
36+
37+
/**
38+
* Site type selection component for OneDesign Multisite setup.
39+
*
40+
* @return {JSX.Element} Rendered component.
41+
*/
42+
const OneDesignMultisiteGoverningSiteSelection = () => {
43+
const [ governingSite, setGoverningSite ] = useState( '' );
44+
const currentGoverningSiteID = useRef( '' );
45+
const [ notice, setNotice ] = useState( null );
46+
const [ isSaving, setIsSaving ] = useState( false );
47+
48+
const fetchCurrentGoverningSite = useCallback( async () => {
49+
try {
50+
const response = await fetch(
51+
`${ API_NAMESPACE }/multisite/governing-site`,
52+
{
53+
headers: {
54+
'Content-Type': 'application/json',
55+
'X-WP-NONCE': NONCE,
56+
},
57+
},
58+
);
59+
60+
if ( ! response.ok ) {
61+
setNotice( {
62+
type: 'error',
63+
message: __( 'Error fetching current governing site.', 'onedesign' ),
64+
} );
65+
return;
66+
}
67+
68+
const data = await response.json();
69+
if ( data?.governing_site ) {
70+
setGoverningSite( data.governing_site );
71+
currentGoverningSiteID.current = data.governing_site;
72+
}
73+
return;
74+
} catch {
75+
setNotice( {
76+
type: 'error',
77+
message: __( 'Error fetching current governing site.', 'onedesign' ),
78+
} );
79+
}
80+
}, [] );
81+
82+
useEffect( () => {
83+
fetchCurrentGoverningSite();
84+
}, [] ); // eslint-disable-line react-hooks/exhaustive-deps
85+
86+
const handleGoverningSiteChange = useCallback( async ( value ) => {
87+
setGoverningSite( value );
88+
currentGoverningSiteID.current = value;
89+
setIsSaving( true );
90+
91+
try {
92+
const response = await fetch( `${ API_NAMESPACE }/multisite/governing-site`, {
93+
method: 'POST',
94+
headers: {
95+
'Content-Type': 'application/json',
96+
'X-WP-NONCE': NONCE,
97+
},
98+
body: JSON.stringify( { governing_site_id: value } ),
99+
} );
100+
101+
if ( ! response.ok ) {
102+
setNotice( {
103+
type: 'error',
104+
message: __( 'Error setting governing site.', 'onedesign' ),
105+
} );
106+
setIsSaving( false );
107+
return;
108+
}
109+
110+
setNotice( {
111+
type: 'success',
112+
message: __( 'Governing site updated successfully.', 'onedesign' ),
113+
} );
114+
115+
setTimeout( () => {
116+
setIsSaving( false );
117+
window.location.reload();
118+
}, 1000 );
119+
return;
120+
} catch {
121+
setNotice( {
122+
type: 'error',
123+
message: __( 'Error setting governing site.', 'onedesign' ),
124+
} );
125+
} finally {
126+
setIsSaving( false );
127+
}
128+
}, [] );
129+
130+
return (
131+
<>
132+
<Card>
133+
<>
134+
{ notice?.message?.length > 0 &&
135+
<Notice
136+
status={ notice?.type ?? 'success' }
137+
isDismissible={ true }
138+
onRemove={ () => setNotice( null ) }
139+
>
140+
{ notice?.message }
141+
</Notice>
142+
}
143+
</>
144+
<CardHeader>
145+
<h2>{ __( 'OneDesign', 'onedesign' ) }</h2>
146+
</CardHeader>
147+
<CardBody>
148+
<SiteTypeSelector value={ governingSite } setGoverningSite={ setGoverningSite } />
149+
<Button
150+
variant="primary"
151+
onClick={ () => handleGoverningSiteChange( governingSite ) }
152+
disabled={ isSaving || governingSite.trim().length === 0 || governingSite === currentGoverningSiteID.current }
153+
style={ { marginTop: '1.5rem' } }
154+
isBusy={ isSaving }
155+
>
156+
{ __( 'Select Governing Site', 'onedesign' ) }
157+
</Button>
158+
</CardBody>
159+
</Card>
160+
</>
161+
);
162+
};
163+
164+
// Render to Gutenberg admin page with ID: onedesign-multisite-selection-modal
165+
const target = document.getElementById( 'onedesign-multisite-selection-modal' );
166+
if ( target ) {
167+
const root = createRoot( target );
168+
root.render( <OneDesignMultisiteGoverningSiteSelection /> );
169+
}

assets/src/admin/patterns/App.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
import { createRoot } from '@wordpress/element';
55
import { registerPlugin } from '@wordpress/plugins';
6+
import { __ } from '@wordpress/i18n';
67

78
/**
89
* Internal dependencies
@@ -31,5 +32,8 @@ registerPlugin( 'onedesign-library', {
3132
const modal = Object.assign( modalWrap, { id: modalID, className } );
3233
document.body?.appendChild( modal );
3334
createRoot( modal ).render( <PatternModal /> );
35+
36+
// make document.title to Pattern Library.
37+
document.title = __( 'Pattern Library', 'onedesign' );
3438
},
3539
} );

0 commit comments

Comments
 (0)