| 1 |
/** |
| 2 |
* One settings tab: the fields that belong to it, grouped into sections. |
| 3 |
* |
| 4 |
* Two tabs carry something that is not a setting: Appearance shows the preview, |
| 5 |
* because seeing the result answers the question faster than reading about it, |
| 6 |
* and Advanced offers to replace the encryption secrets, because that is an |
| 7 |
* action and belongs where somebody would look for it. |
| 8 |
*/ |
| 9 |
|
| 10 |
import { Card, CardBody, CardHeader } from '@wordpress/components'; |
| 11 |
|
| 12 |
import Field, { isVisible } from './Field'; |
| 13 |
import Preview from './Preview'; |
| 14 |
import Secrets from './Secrets'; |
| 15 |
|
| 16 |
const APPEARANCE_TAB = 'appearance'; |
| 17 |
const ADVANCED_TAB = 'advanced'; |
| 18 |
|
| 19 |
export default function SettingsTab( { |
| 20 |
tab, |
| 21 |
fields, |
| 22 |
values, |
| 23 |
onChange, |
| 24 |
rotatedAt, |
| 25 |
isNetwork = false, |
| 26 |
} ) { |
| 27 |
const forThisTab = fields.filter( |
| 28 |
( field ) => field.tab === tab && isVisible( field, values ) |
| 29 |
); |
| 30 |
|
| 31 |
// Sections keep their order of first appearance in the schema, so the |
| 32 |
// schema file reads in the same order as the screen. |
| 33 |
const sections = []; |
| 34 |
forThisTab.forEach( ( field ) => { |
| 35 |
const existing = sections.find( |
| 36 |
( section ) => section.title === field.section |
| 37 |
); |
| 38 |
|
| 39 |
if ( existing ) { |
| 40 |
existing.fields.push( field ); |
| 41 |
} else { |
| 42 |
sections.push( { title: field.section, fields: [ field ] } ); |
| 43 |
} |
| 44 |
} ); |
| 45 |
|
| 46 |
return ( |
| 47 |
<div |
| 48 |
className="cryptx-tab-panel" |
| 49 |
role="tabpanel" |
| 50 |
id={ `cryptx-panel-${ tab }` } |
| 51 |
aria-labelledby={ `cryptx-tab-${ tab }` } |
| 52 |
> |
| 53 |
{ /* Neither belongs on the network defaults: the preview renders |
| 54 |
with THIS site's secret and settings, and the secrets are per |
| 55 |
site by design -- there is no network-wide one to replace. */ } |
| 56 |
{ tab === APPEARANCE_TAB && ! isNetwork && ( |
| 57 |
<Preview values={ values } /> |
| 58 |
) } |
| 59 |
|
| 60 |
{ sections.map( ( section ) => ( |
| 61 |
<Card key={ section.title } className="cryptx-section"> |
| 62 |
<CardHeader> |
| 63 |
<h2 className="cryptx-section__title"> |
| 64 |
{ section.title } |
| 65 |
</h2> |
| 66 |
</CardHeader> |
| 67 |
<CardBody> |
| 68 |
<div className="cryptx-section__fields"> |
| 69 |
{ section.fields.map( ( field ) => ( |
| 70 |
<div key={ field.key } className="cryptx-field"> |
| 71 |
<Field |
| 72 |
field={ field } |
| 73 |
value={ values[ field.key ] } |
| 74 |
onChange={ onChange } |
| 75 |
/> |
| 76 |
</div> |
| 77 |
) ) } |
| 78 |
</div> |
| 79 |
</CardBody> |
| 80 |
</Card> |
| 81 |
) ) } |
| 82 |
|
| 83 |
{ tab === ADVANCED_TAB && ! isNetwork && ( |
| 84 |
<Secrets rotatedAt={ rotatedAt } /> |
| 85 |
) } |
| 86 |
</div> |
| 87 |
); |
| 88 |
} |
| 89 |
|