-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #55 from BaronVonPerko/v2.0
V2.0
- Loading branch information
Showing
83 changed files
with
11,444 additions
and
1,874 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,7 @@ | ||
.idea/ | ||
/vendor/ | ||
dist | ||
node_modules | ||
.cache | ||
composer.phar | ||
*.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"tabWidth": 2, | ||
"useTabs": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"plugins": ["."], | ||
"config": { | ||
"WP_DEBUG_DISPLAY": true | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Component } from "react"; | ||
import React = require("react"); | ||
import WarningBar from "./elements/WarningBar"; | ||
import { upgrade } from "./services/database"; | ||
import { fetchData } from "./services/api"; | ||
import CustomizerEditor from "./components/CustomizerEditor"; | ||
import TabPane from "./components/TabPane"; | ||
import { connect } from "react-redux"; | ||
import store, { actions } from "./redux/wpcuiReducer"; | ||
import Notification from "./components/Notification"; | ||
import Modal from "./components/Modal"; | ||
import { DatabaseObject, NavigationTab } from "./models/models"; | ||
import { getNavigationTabs } from "./services/navigation"; | ||
|
||
interface IProps { | ||
data: DatabaseObject; | ||
} | ||
class CustomizerUI extends Component<IProps, null> { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.upgradeDatabase = this.upgradeDatabase.bind(this); | ||
} | ||
|
||
componentDidMount() { | ||
fetchData().then((data) => { | ||
store.dispatch({ | ||
type: actions.DATA_FETCH, | ||
data, | ||
}); | ||
}); | ||
} | ||
|
||
upgradeDatabase() { | ||
upgrade(this.props.data); | ||
} | ||
|
||
databaseUpgradeWarning() { | ||
return ( | ||
<WarningBar | ||
title="Database Upgrade Required" | ||
buttonText="Upgrade Now" | ||
buttonClick={this.upgradeDatabase} | ||
innerText="Your database needs to be updated in order to use this version of the Customizer UI plugin. It is recommended that you create a backup of your database before continuing." | ||
/> | ||
); | ||
} | ||
|
||
render() { | ||
if (this.props.data.db_version < 2 && this.props.data.db_version > 0) { | ||
return this.databaseUpgradeWarning(); | ||
} else if (this.props.data.sections) { | ||
return ( | ||
<section> | ||
<Notification /> | ||
<Modal /> | ||
<TabPane tabs={getNavigationTabs(this.props.data)} /> | ||
</section> | ||
); | ||
} else { | ||
return <p>Loading ...</p>; | ||
} | ||
} | ||
} | ||
|
||
const mapStateToProps = (state) => ({ | ||
data: state, | ||
}); | ||
export default connect(mapStateToProps)(CustomizerUI); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Control, DatabaseObject, Settings } from "./models/models"; | ||
|
||
export function stringToSnakeCase(input: string): string { | ||
const strArr = input.split(" "); | ||
const snakeArr = strArr.reduce((acc, val) => { | ||
return acc.concat(val.toLowerCase()); | ||
}, []); | ||
return snakeArr.join("_"); | ||
} | ||
|
||
/** | ||
* Check across all controls in every section to see | ||
* if the given control ID already exists. | ||
* @param controlId | ||
* @param data | ||
*/ | ||
export function controlIdExists( | ||
controlId: string, | ||
data: DatabaseObject | ||
): boolean { | ||
let exists = false; | ||
|
||
data.sections.forEach((section) => { | ||
section.controls.forEach((control) => { | ||
if (control.id === controlId) exists = true; | ||
}); | ||
}); | ||
|
||
return exists; | ||
} | ||
|
||
/** | ||
* Check across all sections to see if the given section ID | ||
* is already in use. | ||
* @param sectionId | ||
* @param data | ||
*/ | ||
export function sectionIdExists( | ||
sectionId: string, | ||
data: DatabaseObject | ||
): boolean { | ||
let exists = false; | ||
|
||
data.sections.forEach((section) => { | ||
if (section.id === sectionId) exists = true; | ||
}); | ||
|
||
return exists; | ||
} | ||
|
||
|
||
/** | ||
* Get the full control ID, including the prefix (if any). | ||
* @param control | ||
* @param data | ||
*/ | ||
export function getFullControlId(control: Control, settings: Settings) { | ||
return settings.controlPrefix ? `${settings.controlPrefix}_${control.id}` : control.id; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { Component } from "react"; | ||
import React = require("react"); | ||
import { CardHeaderBar } from "../styled"; | ||
|
||
interface IconButton { | ||
function: Function; | ||
title: string; | ||
} | ||
|
||
interface IProps { | ||
onDuplicate?: IconButton; | ||
onEdit?: IconButton; | ||
onDelete?: IconButton; | ||
onCode?: IconButton; | ||
title?: string; | ||
} | ||
|
||
export default class CardHeader extends Component<IProps, {}> { | ||
renderHeaderButtons() { | ||
const buttons = []; | ||
if (this.props.onCode) { | ||
buttons.push( | ||
<i | ||
key="codeIcon" | ||
title={this.props.onCode.title} | ||
onClick={() => this.props.onCode.function()} | ||
className="dashicons dashicons-editor-code" | ||
/> | ||
); | ||
} | ||
if (this.props.onDuplicate) { | ||
buttons.push( | ||
<i | ||
key="duplicateIcon" | ||
title={this.props.onDuplicate.title} | ||
onClick={() => this.props.onDuplicate.function} | ||
className="dashicons dashicons-admin-page" | ||
/> | ||
); | ||
} | ||
if (this.props.onEdit) { | ||
buttons.push( | ||
<i | ||
key="editIcon" | ||
title={this.props.onEdit.title} | ||
onClick={() => this.props.onEdit.function()} | ||
className="dashicons dashicons-edit" | ||
/> | ||
); | ||
} | ||
if (this.props.onDelete) { | ||
buttons.push( | ||
<i | ||
key="deleteIcon" | ||
title={this.props.onDelete.title} | ||
onClick={() => this.props.onDelete.function()} | ||
className="dashicons dashicons-trash" | ||
/> | ||
); | ||
} | ||
|
||
return buttons; | ||
} | ||
|
||
render() { | ||
return ( | ||
<CardHeaderBar> | ||
<div>{this.props.title}</div> | ||
<div>{this.renderHeaderButtons()}</div> | ||
</CardHeaderBar> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { Component } from "react"; | ||
import { Control as CustomizerControl, Settings } from "../models/models"; | ||
import React = require("react"); | ||
import store, { actions } from "../redux/wpcuiReducer"; | ||
import CardHeader from "./CardHeader"; | ||
import { Card, CardContents } from "../styled"; | ||
import { GetControlTypeById } from "../models/selectOptions"; | ||
import { hideModal, modal } from "./Modal"; | ||
import ControlForm from "../forms/ControlForm"; | ||
import { ModalWrapper, ModalContent, CodeSample, ButtonBar } from "../styled"; | ||
import Button from "../elements/Button"; | ||
import { getFullControlId } from "../common"; | ||
|
||
interface IProps { | ||
control: CustomizerControl; | ||
settings: Settings; | ||
prefix: string; | ||
} | ||
|
||
export default class Control extends Component<IProps, null> { | ||
constructor(props: IProps) { | ||
super(props); | ||
|
||
this.delete = this.delete.bind(this); | ||
this.edit = this.edit.bind(this); | ||
this.showCode = this.showCode.bind(this); | ||
} | ||
|
||
delete() { | ||
let res = confirm( | ||
`Are you sure that you want to delete the control with ID of ${this.props.control.id}` | ||
); | ||
|
||
if (res) { | ||
store.dispatch({ | ||
type: actions.DELETE_CONTROL, | ||
controlId: this.props.control.id | ||
}); | ||
} | ||
} | ||
|
||
copyCode() { | ||
// @ts-ignore | ||
document.getElementById('wpcui_sample_code').select(); | ||
document.execCommand('copy'); | ||
alert('Code copied to your clipboard!'); | ||
} | ||
|
||
showCode() { | ||
const id = this.props.prefix ? `${this.props.prefix}_${this.props.control.id}` : this.props.control.id; | ||
const sample = `get_theme_mod( '${id}', '${this.props.control.default ? this.props.control.default : "Default Value"}' )`; | ||
modal( | ||
<ModalWrapper> | ||
<ModalContent> | ||
<CodeSample> | ||
<textarea id="wpcui_sample_code" readOnly value={sample}></textarea> | ||
<span onClick={() => this.copyCode()} title="Copy code" className="wpcui-copy-icon dashicons dashicons-admin-page"></span> | ||
</CodeSample> | ||
|
||
<ButtonBar> | ||
<Button innerText="Close" click={hideModal} /> | ||
</ButtonBar> | ||
</ModalContent> | ||
</ModalWrapper>); | ||
} | ||
|
||
edit() { | ||
modal(<ControlForm control={this.props.control} />); | ||
} | ||
|
||
render() { | ||
return ( | ||
<Card> | ||
<CardHeader | ||
title="Control" | ||
onDelete={{ title: "Delete Control", function: this.delete }} | ||
onCode={{ title: "Show Code", function: this.showCode }} | ||
onEdit={{ title: "Edit", function: this.edit }} | ||
/> | ||
<CardContents> | ||
<p>Label: <strong>{this.props.control.label}</strong></p> | ||
<p>Id: <strong>{getFullControlId(this.props.control, this.props.settings)}</strong></p> | ||
<p>Type: <strong>{GetControlTypeById(this.props.control.type).text}</strong></p> | ||
<p>Default Value: <strong>{this.props.control.default}</strong></p> | ||
</CardContents> | ||
</Card> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Component } from "react"; | ||
import Control from "./Control"; | ||
import Button from "../elements/Button"; | ||
import ControlForm from "../forms/ControlForm"; | ||
import { connect } from "react-redux"; | ||
import { modal } from "./Modal"; | ||
import { CardListWrapper } from "../styled"; | ||
import { Section, Settings } from "../models/models"; | ||
import React = require("react"); | ||
|
||
interface IProps { | ||
selectedSection: Section; | ||
settings: Settings; | ||
} | ||
|
||
class ControlList extends Component<IProps, null> { | ||
constructor(props) { | ||
super(props); | ||
} | ||
|
||
displayCreateControlForm() { | ||
modal(<ControlForm />); | ||
} | ||
|
||
renderControls() { | ||
const controls = this.props.selectedSection.controls; | ||
if (controls && controls.length) { | ||
return controls.map((control) => ( | ||
<Control key={control.id} control={control} settings={this.props.settings} | ||
prefix={this.props.settings.controlPrefix} /> | ||
)); | ||
} else { | ||
return <p>There are no controls for this section yet.</p>; | ||
} | ||
} | ||
|
||
render() { | ||
if (!this.props.selectedSection) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<CardListWrapper> | ||
{this.renderControls()} | ||
<Button | ||
innerText="Create New Control" | ||
click={() => this.displayCreateControlForm()} | ||
/> | ||
</CardListWrapper> | ||
); | ||
} | ||
} | ||
|
||
const mapStateToProps = (state): IProps => ({ | ||
selectedSection: state.selectedSection, | ||
settings: state.settings | ||
}); | ||
export default connect(mapStateToProps)(ControlList); |
Oops, something went wrong.