Skip to content

Commit 3042a3d

Browse files
authored
Allow default metadata fields to be overridden and edited in place (#597)
This allows a user to see the default fields for a new or existing document, choose to "override" the defaults, and revert back to the default at any time.
1 parent 64d92e0 commit 3042a3d

File tree

15 files changed

+170
-1290
lines changed

15 files changed

+170
-1290
lines changed

src/components/MarkdownPageBody.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import Splitter from './Splitter';
44
import InputPath from './form/InputPath';
55
import InputTitle from './form/InputTitle';
66
import MarkdownEditor from './MarkdownEditor';
7-
import StaticMetaData from './metadata/StaticMetaFields';
87
import Metadata from '../containers/MetaFields';
98

109
export default function MarkdownPageBody({
@@ -30,8 +29,7 @@ export default function MarkdownPageBody({
3029
initialValue={body}
3130
/>
3231
<Splitter />
33-
<StaticMetaData fields={staticmetafields} />
34-
<Metadata fields={metafields} />
32+
<Metadata fields={metafields} staticFields={staticmetafields} />
3533
</div>
3634
);
3735
}

src/components/metadata/MetaButtons.js

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,30 @@ export default class MetaButtons extends Component {
3636

3737
if (parentKey === 'tags') return null;
3838

39-
return this.fieldTypeKeys.map((ftype, i) => {
40-
if (type !== ftype) {
41-
const { icon, label } = this.fieldTypes[ftype];
42-
return (
43-
<span key={i} onMouseDown={() => onConvertClick(ftype)}>
44-
<Icon name={icon} />
45-
Convert to {label}
46-
</span>
47-
);
48-
}
39+
return this.fieldTypeKeys
40+
.map((ftype, i) => {
41+
if (type !== ftype) {
42+
const { icon, label } = this.fieldTypes[ftype];
43+
return (
44+
<span key={i} onMouseDown={() => onConvertClick(ftype)}>
45+
<Icon name={icon} />
46+
Convert to {label}
47+
</span>
48+
);
49+
}
4950

50-
return null;
51-
}).filter(Boolean);
51+
return null;
52+
})
53+
.filter(Boolean);
5254
}
5355

5456
render() {
55-
const { currentType, parentType, onRemoveClick } = this.props;
57+
const {
58+
currentType,
59+
parentType,
60+
onRemoveClick,
61+
isDefaultField,
62+
} = this.props;
5663
const sortableHandle = (
5764
<span className="move">
5865
<Icon name="arrows" />
@@ -78,8 +85,8 @@ export default class MetaButtons extends Component {
7885
<div className="dropdown-wrap">
7986
{this.renderDropdownItems(currentType)}
8087
<span onMouseDown={() => onRemoveClick()} className="remove-field">
81-
<Icon name="trash-o" />
82-
Remove field
88+
<Icon name={isDefaultField ? 'undo' : 'trash-o'} />
89+
{isDefaultField ? 'Revert to default' : 'Remove field'}
8390
</span>
8491
</div>
8592
</span>
@@ -94,4 +101,5 @@ MetaButtons.propTypes = {
94101
onConvertClick: PropTypes.func.isRequired,
95102
onRemoveClick: PropTypes.func.isRequired,
96103
parentKey: PropTypes.string,
104+
isDefaultField: PropTypes.bool,
97105
};

src/components/metadata/MetaField.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export class MetaField extends Component {
4545
convertField,
4646
key_prefix,
4747
siteMeta,
48+
isInDefaultState,
49+
isDefaultField,
4850
} = this.props;
4951

5052
const FieldTypes = {
@@ -63,9 +65,11 @@ export class MetaField extends Component {
6365
className="field key-field"
6466
type="text"
6567
placeholder="Key"
68+
disabled={isInDefaultState}
6669
/>
6770
<MetaButtons
6871
currentType={type}
72+
isDefaultField={isDefaultField}
6973
parentType="top"
7074
parentKey={fieldKey}
7175
onConvertClick={type => this.handleConvertClick(type)}
@@ -86,6 +90,7 @@ export class MetaField extends Component {
8690
nameAttr={`${namePrefix}['${fieldKey}']`}
8791
namePrefix={`${namePrefix}['${fieldKey}']`}
8892
siteMeta={siteMeta}
93+
isInDefaultState={isInDefaultState}
8994
/>
9095
</div>
9196
);
@@ -107,6 +112,8 @@ MetaField.propTypes = {
107112
namePrefix: PropTypes.string.isRequired,
108113
key_prefix: PropTypes.string.isRequired,
109114
siteMeta: PropTypes.object,
115+
isInDefaultState: PropTypes.bool,
116+
isDefaultField: PropTypes.bool,
110117
};
111118

112119
export default MetaField;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
import Icon from '../Icon';
4+
import classnames from 'classnames';
5+
6+
export default class StaticMetaButton extends Component {
7+
state = {
8+
dropdown: false,
9+
};
10+
11+
toggleDropdownState = () => {
12+
this.setState(state => ({ dropdown: !state.dropdown }));
13+
};
14+
15+
render() {
16+
const { onEnableField } = this.props;
17+
18+
const dropdownClasses = classnames('dropdown', {
19+
'showing-dropdown': this.state.dropdown,
20+
});
21+
22+
return (
23+
<div className="meta-buttons">
24+
<span className={dropdownClasses}>
25+
<a
26+
className="meta-button"
27+
tabIndex="1"
28+
onClick={this.toggleDropdownState}
29+
onBlur={() => this.setState({ dropdown: false })}
30+
>
31+
<Icon name="chevron-down" />
32+
</a>
33+
<div className="dropdown-wrap">
34+
<span onMouseDown={() => onEnableField()}>
35+
<Icon name="pencil" /> Override default
36+
</span>
37+
</div>
38+
</span>
39+
</div>
40+
);
41+
}
42+
}
43+
44+
StaticMetaButton.propTypes = {
45+
onEnableField: PropTypes.func.isRequired,
46+
};

src/components/metadata/StaticMetaFields.js

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/components/metadata/statics/StaticMetaField.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,36 @@ import PropTypes from 'prop-types';
33
import StaticMetaArray from './StaticMetaArray';
44
import StaticMetaObject from './StaticMetaObject';
55
import StaticMetaSimple from './StaticMetaSimple';
6+
import StaticMetaButton from '../StaticMetaButton';
67

78
const FieldTypes = {
89
array: StaticMetaArray,
910
object: StaticMetaObject,
1011
simple: StaticMetaSimple,
1112
};
1213

13-
export default function StaticMetaField({ type, fieldKey, fieldValue }) {
14+
export default function StaticMetaField({
15+
type,
16+
fieldKey,
17+
fieldValue,
18+
enableField,
19+
}) {
1420
const CurrentComponent = FieldTypes[type];
1521

1622
return (
17-
<div className="metafield">
23+
<div className="metafield default-field">
1824
<div className={`meta-key ${type}`}>
1925
<input
2026
value={fieldKey}
2127
className="field key-field"
2228
type="text"
2329
disabled
2430
/>
31+
<StaticMetaButton
32+
onEnableField={() => {
33+
enableField(`metadata['${fieldKey}']`, fieldValue);
34+
}}
35+
/>
2536
</div>
2637
<CurrentComponent fieldValue={fieldValue} />
2738
</div>
@@ -32,4 +43,5 @@ StaticMetaField.propTypes = {
3243
type: PropTypes.string.isRequired,
3344
fieldKey: PropTypes.string.isRequired,
3445
fieldValue: PropTypes.any.isRequired,
46+
enableField: PropTypes.func.isRequired,
3547
};

0 commit comments

Comments
 (0)