mirror of
https://github.com/vale981/Vulcan
synced 2025-03-04 17:21:37 -05:00
create vulcan:ui-material, update to Apollo2 RR4
This commit is contained in:
parent
a743022545
commit
b7b872591a
21 changed files with 217 additions and 479 deletions
|
@ -6,7 +6,7 @@ import { STATES } from '../../helpers.js';
|
|||
|
||||
class AccountsEnrollAccount extends PureComponent {
|
||||
componentDidMount() {
|
||||
const token = this.props.params.token;
|
||||
const token = this.props.match.params.token;
|
||||
Accounts._loginButtonsSession.set('enrollAccountToken', token);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.js]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
|
@ -1,86 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
//"airbnb",
|
||||
"plugin:meteor/recommended",
|
||||
"plugin:react/recommended"
|
||||
],
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"allowImportExportEverywhere": true,
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"babel/generator-star-spacing": 0,
|
||||
"babel/new-cap": [1, {
|
||||
"capIsNewExceptions": [
|
||||
"Optional",
|
||||
"OneOf",
|
||||
"Maybe",
|
||||
"MailChimpAPI",
|
||||
"Juice",
|
||||
"Run",
|
||||
"AppComposer",
|
||||
"Query",
|
||||
"InArray"
|
||||
]
|
||||
}],
|
||||
"babel/array-bracket-spacing": 0,
|
||||
"babel/object-curly-spacing": 0,
|
||||
"babel/object-shorthand": 0,
|
||||
"babel/arrow-parens": 0,
|
||||
"babel/no-await-in-loop": 1,
|
||||
"comma-dangle": 0,
|
||||
"key-spacing": 0,
|
||||
"no-extra-boolean-cast": 0,
|
||||
"no-undef": 1,
|
||||
"no-unused-vars": [1, {
|
||||
"vars": "all",
|
||||
"args": "none",
|
||||
"varsIgnorePattern": "React|PropTypes|Component"
|
||||
}],
|
||||
"react/prop-types": 0,
|
||||
"react/display-name": 0,
|
||||
"meteor/audit-argument-checks": 0,
|
||||
"meteor/no-session": 0,
|
||||
"no-case-declarations": 0,
|
||||
"no-console": 0,
|
||||
"semi": "error",
|
||||
"quotes": [
|
||||
1,
|
||||
"single"
|
||||
]
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"meteor": true,
|
||||
"node": true
|
||||
},
|
||||
"plugins": [
|
||||
"babel",
|
||||
"meteor",
|
||||
"react",
|
||||
"jsx-a11y"
|
||||
],
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"meteor": {
|
||||
"paths": [
|
||||
"/usr/local/share/global_modules"
|
||||
],
|
||||
"moduleDirectory": [
|
||||
"node_modules",
|
||||
"packages"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": true,
|
||||
"globals": {
|
||||
"param": true,
|
||||
"returns": true
|
||||
}
|
||||
}
|
3
packages/vulcan-ui-material/.gitignore
vendored
3
packages/vulcan-ui-material/.gitignore
vendored
|
@ -1,3 +1,6 @@
|
|||
npm-debug.log
|
||||
node_modules
|
||||
.idea/workspace.xml
|
||||
|
||||
### eslint-config
|
||||
.eslintrc
|
||||
|
|
|
@ -4,31 +4,40 @@ import { Components, registerComponent } from 'meteor/vulcan:core';
|
|||
import { intlShape } from 'meteor/vulcan:i18n';
|
||||
import EditIcon from 'mdi-material-ui/Pencil';
|
||||
|
||||
|
||||
const EditButton = ({
|
||||
collection,
|
||||
document,
|
||||
color = 'default',
|
||||
variant,
|
||||
triggerClasses,
|
||||
buttonClasses,
|
||||
...props
|
||||
}, { intl }) => (
|
||||
|
||||
const EditButton = (
|
||||
{
|
||||
collection,
|
||||
document,
|
||||
color = 'default',
|
||||
variant,
|
||||
triggerClasses,
|
||||
buttonClasses,
|
||||
showRemove,
|
||||
...props
|
||||
},
|
||||
{ intl }
|
||||
) => (
|
||||
<Components.ModalTrigger
|
||||
classes={triggerClasses}
|
||||
component={<Components.TooltipIconButton titleId="datatable.edit"
|
||||
icon={<EditIcon/>}
|
||||
color={color}
|
||||
variant={variant}
|
||||
classes={buttonClasses}
|
||||
/>}
|
||||
component={
|
||||
<Components.TooltipIconButton
|
||||
titleId="datatable.edit"
|
||||
icon={<EditIcon />}
|
||||
color={color}
|
||||
variant={variant}
|
||||
classes={buttonClasses}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Components.EditForm collection={collection} document={document} {...props}/>
|
||||
<Components.EditForm
|
||||
collection={collection}
|
||||
document={document}
|
||||
showRemove={showRemove}
|
||||
{...props}
|
||||
/>
|
||||
</Components.ModalTrigger>
|
||||
);
|
||||
|
||||
|
||||
EditButton.propTypes = {
|
||||
collection: PropTypes.object.isRequired,
|
||||
document: PropTypes.object.isRequired,
|
||||
|
@ -36,27 +45,32 @@ EditButton.propTypes = {
|
|||
variant: PropTypes.string,
|
||||
triggerClasses: PropTypes.object,
|
||||
buttonClasses: PropTypes.object,
|
||||
showRemove: PropTypes.bool
|
||||
};
|
||||
|
||||
|
||||
EditButton.contextTypes = {
|
||||
intl: intlShape
|
||||
};
|
||||
|
||||
|
||||
EditButton.displayName = 'EditButton';
|
||||
|
||||
|
||||
registerComponent('EditButton', EditButton);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
EditForm Component
|
||||
|
||||
*/
|
||||
const EditForm = ({ collection, document, closeModal, options, successCallback, removeSuccessCallback,...props }) => {
|
||||
|
||||
const EditForm = ({
|
||||
collection,
|
||||
document,
|
||||
closeModal,
|
||||
options,
|
||||
successCallback,
|
||||
removeSuccessCallback,
|
||||
showRemove,
|
||||
...props
|
||||
}) => {
|
||||
const success = successCallback
|
||||
? () => {
|
||||
successCallback();
|
||||
|
@ -70,17 +84,17 @@ const EditForm = ({ collection, document, closeModal, options, successCallback,
|
|||
closeModal();
|
||||
}
|
||||
: closeModal;
|
||||
|
||||
|
||||
return (
|
||||
<Components.SmartForm
|
||||
{...props}
|
||||
collection={collection}
|
||||
documentId={document && document._id}
|
||||
showRemove={true}
|
||||
successCallback={success}
|
||||
removeSuccessCallback={remove}
|
||||
/>
|
||||
);
|
||||
}
|
||||
<Components.SmartForm
|
||||
{...props}
|
||||
collection={collection}
|
||||
documentId={document && document._id}
|
||||
showRemove={showRemove ? true : showRemove}
|
||||
successCallback={success}
|
||||
removeSuccessCallback={remove}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
registerComponent('EditForm', EditForm);
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { intlShape } from 'meteor/vulcan:i18n';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
import { registerComponent, Components } from 'meteor/vulcan:core';
|
||||
import withStyles from '@material-ui/core/styles/withStyles';
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import Close from 'mdi-material-ui/Close';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
|
||||
|
@ -17,27 +20,29 @@ const styles = theme => ({
|
|||
button: {},
|
||||
anchor: {},
|
||||
dialog: {},
|
||||
dialogPaper: {},
|
||||
dialogTitle: {},
|
||||
dialogPaper: {
|
||||
overflowY: 'visible',
|
||||
},
|
||||
dialogTitle: {
|
||||
padding: theme.spacing.unit * 4,
|
||||
},
|
||||
dialogContent: {
|
||||
paddingTop: '4px',
|
||||
},
|
||||
dialogOverflow: {
|
||||
overflowY: 'visible',
|
||||
},
|
||||
closeButton: {
|
||||
position: 'absolute',
|
||||
right: theme.spacing.unit,
|
||||
top: theme.spacing.unit,
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
class ModalTrigger extends PureComponent {
|
||||
|
||||
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
this.state = { modalIsOpen: false };
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.action) {
|
||||
this.props.action({
|
||||
|
@ -50,11 +55,11 @@ class ModalTrigger extends PureComponent {
|
|||
openModal = () => {
|
||||
this.setState({ modalIsOpen: true });
|
||||
};
|
||||
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({ modalIsOpen: false });
|
||||
};
|
||||
|
||||
|
||||
render () {
|
||||
const {
|
||||
className,
|
||||
|
@ -67,9 +72,9 @@ class ModalTrigger extends PureComponent {
|
|||
children,
|
||||
classes,
|
||||
} = this.props;
|
||||
|
||||
|
||||
const intl = this.context.intl;
|
||||
|
||||
|
||||
const label = labelId ? intl.formatMessage({ id: labelId }) : this.props.label;
|
||||
const title = titleId ? intl.formatMessage({ id: titleId }) : this.props.title;
|
||||
const overflowClass = dialogOverflow && classes.dialogOverflow;
|
||||
|
@ -83,35 +88,39 @@ class ModalTrigger extends PureComponent {
|
|||
<Button className={classes.button} variant="contained" onClick={this.openModal}>{label}</Button>
|
||||
:
|
||||
<a className={classes.anchor} href="#" onClick={this.openModal}>{label}</a>;
|
||||
|
||||
|
||||
const childrenComponent = typeof children.type === 'function' ?
|
||||
React.cloneElement(children, { closeModal: this.closeModal }) :
|
||||
children;
|
||||
|
||||
|
||||
return (
|
||||
<span className={classNames('modal-trigger', classes.root, className)}>
|
||||
|
||||
|
||||
{triggerComponent}
|
||||
|
||||
<Dialog className={classNames(dialogClassName)}
|
||||
open={this.state.modalIsOpen}
|
||||
onClose={this.closeModal}
|
||||
fullWidth={true}
|
||||
classes={{ paper: classNames(classes.dialogPaper, overflowClass) }}
|
||||
>
|
||||
|
||||
{
|
||||
title &&
|
||||
|
||||
<DialogTitle className={classes.dialogTitle}>{title}</DialogTitle>
|
||||
}
|
||||
|
||||
<DialogContent className={classNames(classes.dialogContent, overflowClass)}>
|
||||
{childrenComponent}
|
||||
</DialogContent>
|
||||
|
||||
</Dialog>
|
||||
|
||||
<Dialog className={classNames(dialogClassName)}
|
||||
open={this.state.modalIsOpen}
|
||||
onClose={this.closeModal}
|
||||
fullWidth={true}
|
||||
classes={{ paper: classes.paper }}
|
||||
>
|
||||
<DialogTitle className={classes.dialogTitle}>
|
||||
{title}
|
||||
|
||||
<Components.Button iconButton aria-label="Close" className={classes.closeButton} onClick={this.closeModal}>
|
||||
<Tooltip title={intl.formatMessage({ id: 'modal.close' })}>
|
||||
<Close />
|
||||
</Tooltip>
|
||||
</Components.Button>
|
||||
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent className={classes.dialogContent}>
|
||||
<Components.ErrorCatcher>
|
||||
{childrenComponent}
|
||||
</Components.ErrorCatcher>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ FormComponentInner.propTypes = {
|
|||
showCharsRemaining: PropTypes.bool.isRequired,
|
||||
charsRemaining: PropTypes.number,
|
||||
charsCount: PropTypes.number,
|
||||
max: PropTypes.number,
|
||||
max: PropTypes.oneOfType([PropTypes.number, PropTypes.instanceOf(Date)]),
|
||||
formInput: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Components, replaceComponent, instantiateComponent, } from 'meteor/vulcan:core';
|
||||
import Users from 'meteor/vulcan:users';
|
||||
import withStyles from '@material-ui/core/styles/withStyles';
|
||||
import Collapse from '@material-ui/core/Collapse';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
import ExpandLessIcon from 'mdi-material-ui/ChevronUp';
|
||||
import ExpandMoreIcon from 'mdi-material-ui/ChevronDown';
|
||||
import classNames from 'classnames';
|
||||
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
minWidth: '320px'
|
||||
},
|
||||
paper: {
|
||||
padding: theme.spacing.unit * 3
|
||||
},
|
||||
subtitle1: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
paddingLeft: theme.spacing.unit / 2,
|
||||
marginTop: theme.spacing.unit * 5,
|
||||
marginBottom: theme.spacing.unit,
|
||||
color: theme.palette.primary[500],
|
||||
},
|
||||
collapsible: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
label: {},
|
||||
toggle: {
|
||||
'& svg': {
|
||||
width: 21,
|
||||
height: 21,
|
||||
display: 'block',
|
||||
}
|
||||
},
|
||||
container: {
|
||||
paddingLeft: 4,
|
||||
paddingRight: 4,
|
||||
marginLeft: -4,
|
||||
marginRight: -4,
|
||||
},
|
||||
entered: {
|
||||
overflow: 'visible',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
class FormGroup extends PureComponent {
|
||||
|
||||
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
this.isAdmin = props.name === 'admin';
|
||||
|
||||
this.state = {
|
||||
collapsed: props.startCollapsed || this.isAdmin,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
toggle = () => {
|
||||
const collapsible = this.props.collapsible || this.isAdmin;
|
||||
if (!collapsible) return;
|
||||
|
||||
this.setState({
|
||||
collapsed: !this.state.collapsed
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
renderHeading = () => {
|
||||
const { classes, label } = this.props;
|
||||
const collapsible = this.props.collapsible || this.isAdmin;
|
||||
|
||||
return (
|
||||
<Typography className={classNames(classes.subtitle1, collapsible && classes.collapsible)}
|
||||
variant="subtitle1"
|
||||
onClick={this.toggle}
|
||||
>
|
||||
|
||||
<div className={classes.label}>
|
||||
{label}
|
||||
</div>
|
||||
|
||||
{
|
||||
collapsible &&
|
||||
|
||||
<div className={classes.toggle}>
|
||||
{
|
||||
this.state.collapsed
|
||||
?
|
||||
<ExpandMoreIcon/>
|
||||
:
|
||||
<ExpandLessIcon/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
</Typography>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// if at least one of the fields in the group has an error, the group as a whole has an error
|
||||
hasErrors = () => _.some(this.props.fields, field => {
|
||||
return !!this.props.errors.filter(error => error.path === field.path).length;
|
||||
});
|
||||
|
||||
|
||||
render () {
|
||||
const {
|
||||
name,
|
||||
hidden,
|
||||
classes,
|
||||
currentUser,
|
||||
} = this.props;
|
||||
|
||||
if (this.isAdmin && !Users.isAdmin(currentUser)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof hidden === 'function' ? hidden({ ...this.props }) : hidden) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//do not display if no fields, no startComponent and no endComponent
|
||||
if (!this.props.startComponent && !this.props.endComponent && !this.props.fields.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const anchorName = name.split('.').length > 1 ? name.split('.')[1] : name;
|
||||
const collapseIn = !this.state.collapsed || this.hasErrors();
|
||||
|
||||
const FormComponents = this.props.formComponents;
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
|
||||
<a name={anchorName}/>
|
||||
|
||||
{
|
||||
name === 'default'
|
||||
?
|
||||
null
|
||||
:
|
||||
this.renderHeading()
|
||||
}
|
||||
|
||||
<Collapse classes={{ container: classes.container, entered: classes.entered }} in={collapseIn}>
|
||||
<Paper className={classes.paper}>
|
||||
|
||||
{instantiateComponent(this.props.startComponent)}
|
||||
|
||||
{this.props.fields.map(field => (
|
||||
<FormComponents.FormComponent
|
||||
key={field.name}
|
||||
disabled={this.props.disabled}
|
||||
{...field}
|
||||
errors={this.props.errors}
|
||||
throwError={this.props.throwError}
|
||||
currentValues={this.props.currentValues}
|
||||
updateCurrentValues={this.props.updateCurrentValues}
|
||||
deletedValues={this.props.deletedValues}
|
||||
addToDeletedValues={this.props.addToDeletedValues}
|
||||
clearFieldErrors={this.props.clearFieldErrors}
|
||||
formType={this.props.formType}
|
||||
currentUser={this.props.currentUser}
|
||||
formComponents={FormComponents}
|
||||
/>
|
||||
))}
|
||||
|
||||
{instantiateComponent(this.props.endComponent)}
|
||||
|
||||
</Paper>
|
||||
</Collapse>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
FormGroup.propTypes = {
|
||||
name: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
order: PropTypes.number,
|
||||
hidden: PropTypes.bool,
|
||||
fields: PropTypes.array,
|
||||
collapsible: PropTypes.bool,
|
||||
startCollapsed: PropTypes.bool,
|
||||
updateCurrentValues: PropTypes.func,
|
||||
startComponent: PropTypes.node,
|
||||
endComponent: PropTypes.node,
|
||||
currentUser: PropTypes.object,
|
||||
};
|
||||
|
||||
|
||||
replaceComponent('FormGroup', FormGroup, [withStyles, styles]);
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { replaceComponent } from 'meteor/vulcan:core';
|
||||
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
const FormNestedArrayLayout = ({ hasErrors, label, content }) => (
|
||||
<div>
|
||||
<Typography component="label" variant="caption" style={{ fontSize: 16 }}>
|
||||
{label}
|
||||
</Typography>
|
||||
<div>{content}</div>
|
||||
</div>
|
||||
);
|
||||
FormNestedArrayLayout.propTypes = {
|
||||
hasErrors: PropTypes.bool,
|
||||
label: PropTypes.node,
|
||||
content: PropTypes.node,
|
||||
};
|
||||
replaceComponent({
|
||||
name: 'FormNestedArrayLayout',
|
||||
component: FormNestedArrayLayout,
|
||||
});
|
|
@ -1,24 +1,20 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
import { FormattedMessage } from 'meteor/vulcan:i18n';
|
||||
import { replaceComponent } from 'meteor/vulcan:core';
|
||||
// import { FormattedMessage } from 'meteor/vulcan:i18n';
|
||||
import withStyles from '@material-ui/core/styles/withStyles';
|
||||
import Divider from '@material-ui/core/Divider';
|
||||
|
||||
|
||||
const styles = theme => ({
|
||||
|
||||
divider: {
|
||||
marginLeft: -24,
|
||||
marginRight: -24,
|
||||
// marginLeft: -24,
|
||||
// marginRight: -24,
|
||||
marginTop: 16,
|
||||
marginBottom: 23,
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
||||
const FormNestedDivider = ({ classes, label, addItem }) => <Divider className={classes.divider}/>;
|
||||
const FormNestedDivider = ({ classes, label, addItem }) => <Divider className={classes.divider} />;
|
||||
|
||||
FormNestedDivider.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
@ -26,4 +22,4 @@ FormNestedDivider.propTypes = {
|
|||
addItem: PropTypes.func,
|
||||
};
|
||||
|
||||
registerComponent('FormNestedDivider', FormNestedDivider, [withStyles, styles]);
|
||||
replaceComponent('FormNestedDivider', FormNestedDivider, [withStyles, styles]);
|
||||
|
|
|
@ -5,8 +5,8 @@ import { FormattedMessage } from 'meteor/vulcan:i18n';
|
|||
import Grid from '@material-ui/core/Grid';
|
||||
|
||||
const FormNestedFoot = ({ label, addItem }) => (
|
||||
<Grid container spacin={0} justify="flex-end">
|
||||
<Components.Button color="primary" variant="fab" mini onClick={addItem} className="form-nested-add">
|
||||
<Grid container spacing={0} justify="flex-end">
|
||||
<Components.Button color="primary" iconButton onClick={addItem}>
|
||||
<Components.IconAdd/>
|
||||
</Components.Button>
|
||||
</Grid>
|
||||
|
|
|
@ -73,11 +73,7 @@ const MuiRadioGroup = createReactClass({
|
|||
options: PropTypes.array.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function () {
|
||||
if (this.props.refFunction) {
|
||||
this.props.refFunction(this);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
|
|
|
@ -105,6 +105,7 @@ export default {
|
|||
'description',
|
||||
'clearField',
|
||||
'regEx',
|
||||
'allowedValues',
|
||||
'mustComplete',
|
||||
'renderComponent',
|
||||
'formInput',
|
||||
|
|
|
@ -7,7 +7,7 @@ import './accounts/AccountsPasswordOrService';
|
|||
import './accounts/AccountsSocialButtons';
|
||||
|
||||
import './bonus/LoadMore';
|
||||
import './bonus/SearchInput';
|
||||
// import './bonus/SearchInput';
|
||||
import './bonus/TooltipIntl';
|
||||
import './bonus/TooltipIconButton';
|
||||
|
||||
|
@ -20,10 +20,11 @@ import './core/NewButton';
|
|||
|
||||
import './forms/FormComponentInner';
|
||||
import './forms/FormErrors';
|
||||
import './forms/FormGroup';
|
||||
//import './forms/FormGroup';
|
||||
import './forms/FormGroupNone';
|
||||
import './forms/FormGroupWithLine';
|
||||
import './forms/FormNested';
|
||||
import './forms/FormNestedArrayLayout';
|
||||
import './forms/FormNestedDivider';
|
||||
import './forms/FormNestedFoot';
|
||||
import './forms/FormNestedHead';
|
||||
|
|
|
@ -3,10 +3,10 @@ import { addStrings } from 'meteor/vulcan:core';
|
|||
|
||||
addStrings('en', {
|
||||
|
||||
"search.search": "Search",
|
||||
"search.clear": "Clear search",
|
||||
"load_more.load_more": "Load more",
|
||||
"load_more.loaded_count": "Loaded {count} of {totalCount}",
|
||||
"load_more.loaded_all": "{totalCount, plural, =0 {No items} one {One item} other {# items}}",
|
||||
'search.search': 'Search',
|
||||
'search.clear': 'Clear search',
|
||||
'load_more.load_more': 'Load more',
|
||||
'load_more.loaded_count': 'Loaded {count} of {totalCount}',
|
||||
'load_more.loaded_all': '{totalCount, plural, =0 {No items} one {One item} other {# items}}',
|
||||
|
||||
});
|
||||
|
|
|
@ -74,63 +74,64 @@ const styles = theme => {
|
|||
};
|
||||
|
||||
|
||||
class Layout extends React.Component {
|
||||
state = {
|
||||
isOpen: { sideNav: true }
|
||||
};
|
||||
|
||||
toggle = (item, openOrClose) => {
|
||||
const newState = { isOpen: {} };
|
||||
newState.isOpen[item] = typeof openOrClose === 'string' ?
|
||||
openOrClose === 'open' :
|
||||
!this.state.isOpen[item];
|
||||
this.setState(newState);
|
||||
};
|
||||
class Layout extends React.Component {
|
||||
state = {
|
||||
isOpen: { sideNav: true }
|
||||
};
|
||||
|
||||
render = () => {
|
||||
const routeName = Utils.slugify(this.props.currentRoute.name);
|
||||
const classes = this.props.classes;
|
||||
const isOpen = this.state.isOpen;
|
||||
toggle = (item, openOrClose) => {
|
||||
const newState = { isOpen: {} };
|
||||
newState.isOpen[item] = typeof openOrClose === 'string' ?
|
||||
openOrClose === 'open' :
|
||||
!this.state.isOpen[item];
|
||||
this.setState(newState);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classNames(classes.root, 'wrapper', `wrapper-${routeName}`)}>
|
||||
<div className={classes.appFrame}>
|
||||
render = () => {
|
||||
const routeName = Utils.slugify(this.props.currentRoute.name);
|
||||
const classes = this.props.classes;
|
||||
const isOpen = this.state.isOpen;
|
||||
|
||||
<Components.Header isSideNavOpen={isOpen.sideNav}
|
||||
toggleSideNav={openOrClose =>
|
||||
this.toggle('sideNav', openOrClose)} />
|
||||
return (
|
||||
<div className={classNames(classes.root, 'wrapper', `wrapper-${routeName}`)}>
|
||||
<div className={classes.appFrame}>
|
||||
|
||||
<Drawer variant="persistent"
|
||||
classes={{ paper: classes.drawerPaper, }}
|
||||
open={isOpen.sideNav}
|
||||
>
|
||||
<AppBar className={classes.drawerHeader} elevation={4} square={true}>
|
||||
<Toolbar>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<Components.SideNavigation />
|
||||
</Drawer>
|
||||
<Components.Header isSideNavOpen={isOpen.sideNav}
|
||||
toggleSideNav={openOrClose =>
|
||||
this.toggle('sideNav', openOrClose)} />
|
||||
|
||||
<main className={classNames(classes.content, isOpen.sideNav && classes.mainShift)}>
|
||||
{this.props.children}
|
||||
</main>
|
||||
<Drawer variant="persistent"
|
||||
classes={{ paper: classes.drawerPaper, }}
|
||||
open={isOpen.sideNav}
|
||||
>
|
||||
<AppBar className={classes.drawerHeader} elevation={4} square={true}>
|
||||
<Toolbar>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<Components.SideNavigation />
|
||||
</Drawer>
|
||||
|
||||
<Components.FlashMessages />
|
||||
<main className={classNames(classes.content, isOpen.sideNav && classes.mainShift)}>
|
||||
{this.props.children}
|
||||
</main>
|
||||
|
||||
<Components.FlashMessages />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Layout.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Layout.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
Layout.displayName = 'Layout';
|
||||
|
||||
|
||||
Layout.displayName = 'Layout';
|
||||
|
||||
|
||||
replaceComponent('Layout', Layout, [withStyles, styles]);
|
||||
replaceComponent('Layout', Layout, [withStyles, styles]);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Components, registerComponent, withCurrentUser } from 'meteor/vulcan:core';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withRouter } from 'react-router';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
|
@ -38,15 +38,14 @@ class SideNavigation extends React.Component {
|
|||
};
|
||||
|
||||
render () {
|
||||
const currentUser = this.props.currentUser;
|
||||
const classes = this.props.classes;
|
||||
const { currentUser, classes, history } = this.props;
|
||||
const isOpen = this.state.isOpen;
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
|
||||
<List>
|
||||
<ListItem button onClick={() => {this.props.history.push('/');}}>
|
||||
<ListItem button onClick={() => {history.push('/');}}>
|
||||
<ListItemIcon>
|
||||
<HomeIcon/>
|
||||
</ListItemIcon>
|
||||
|
@ -69,14 +68,14 @@ class SideNavigation extends React.Component {
|
|||
</ListItem>
|
||||
<Collapse in={isOpen.admin} transitionduration="auto" unmountOnExit>
|
||||
<ListItem button className={classes.nested}
|
||||
onClick={() => {this.props.history.push('/admin');}}>
|
||||
onClick={() => {browserHistory.push('/admin');}}>
|
||||
<ListItemIcon>
|
||||
<UsersIcon/>
|
||||
</ListItemIcon>
|
||||
<ListItemText inset primary="Users"/>
|
||||
</ListItem>
|
||||
<ListItem button className={classes.nested}
|
||||
onClick={() => {this.props.history.push('/theme');}}>
|
||||
onClick={() => {browserHistory.push('/theme');}}>
|
||||
<ListItemIcon>
|
||||
<ThemeIcon/>
|
||||
</ListItemIcon>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { addStrings } from 'meteor/vulcan:core';
|
||||
|
||||
addStrings('fr', {
|
||||
|
||||
"search.search": "Recherche",
|
||||
"search.clear": "Effacer la recherche",
|
||||
|
||||
'search.search': 'Recherche',
|
||||
'search.clear': 'Effacer la recherche',
|
||||
'modal.close': 'Fermer',
|
||||
});
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { addRoute } from 'meteor/vulcan:core';
|
||||
|
||||
|
||||
addRoute({
|
||||
name: 'theme',
|
||||
path: '/theme',
|
||||
componentName: 'ThemeStyles',
|
||||
});
|
||||
//Only create route on dev mode, not production.
|
||||
if (Meteor.isDevelopment) {
|
||||
addRoute({
|
||||
name: 'theme',
|
||||
path: '/theme',
|
||||
componentName: 'ThemeStyles',
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ Package.describe({
|
|||
documentation: 'README.md'
|
||||
});
|
||||
|
||||
|
||||
Package.onUse(function (api) {
|
||||
api.versionsFrom('METEOR@1.6');
|
||||
|
||||
|
@ -23,4 +22,4 @@ Package.onUse(function (api) {
|
|||
|
||||
api.mainModule('client/main.js', 'client');
|
||||
api.mainModule('server/main.js', 'server');
|
||||
});
|
||||
});
|
|
@ -1,10 +1,10 @@
|
|||
# erikdakoda:vulcan-material-ui 1.12.8_13
|
||||
# vulcan:ui-material 1.12.8_13
|
||||
|
||||
Package initially created by [Erik Dakoda](https://github.com/ErikDakoda) ([`erikdakoda:vulcan-material-ui`](https://github.com/ErikDakoda/vulcan-material-ui))
|
||||
|
||||
|
||||
Replacement for [Vulcan](http://vulcanjs.org/) components using [Material-UI](https://material-ui.com/).
|
||||
This version has been tested against Vulcan 1.12.8 and Material-UI 3.1.0.
|
||||
|
||||
To give me feedback open an issue on GitHub or you can reach me on the [Vulcan Slack](https://vulcanjs.slack.com)
|
||||
channel as erikdakoda.
|
||||
|
||||
There are some nice bonus features like a CountrySelect with autocomplete and theming.
|
||||
|
||||
|
@ -15,9 +15,9 @@ All components in vulcan:ui-bootstrap, vulcan:forms and vulcan:accounts have bee
|
|||
To add vulcan-material-ui to an existing Vulcan project, enter the following:
|
||||
|
||||
``` sh
|
||||
meteor add erikdakoda:vulcan-material-ui
|
||||
meteor add vulcan:ui-material
|
||||
|
||||
meteor npm install --save @material-ui/core
|
||||
meteor npm install --save @material-ui/core@3.1.0
|
||||
meteor npm install --save react-jss
|
||||
meteor npm install --save mdi-material-ui
|
||||
meteor npm install --save react-autosuggest
|
||||
|
@ -48,7 +48,7 @@ For an example theme see `modules/sampleTheme.js`. For a complete list of values
|
|||
see the [MUI Default Theme](https://material-ui-next.com/customization/default-theme/).
|
||||
|
||||
Register your theme in the Vulcan environment by giving it a name: `registerTheme('MyTheme', theme);`.
|
||||
You can have multiple themes registered and you can specify which one to use in your settings file using the `muiTheme` public setting.
|
||||
You can have multiple themes registered and you can specify which one to use in your settings file using the `muiTheme` **public** setting.
|
||||
|
||||
In addition to the Material UI spec, I use a `utils` section in my themes where I place global variables for reusable styles.
|
||||
For example the sample theme contains
|
||||
|
|
Loading…
Add table
Reference in a new issue