RecordList.jsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. var cloudflare = require('../cloudflare');
  2. var React = require('react');
  3. var CloudActive = React.createClass({
  4. render: function() {
  5. var record = this.props.record;
  6. if(record.type === 'A' || record.type === 'AAAA' || record.type === 'CNAME') {
  7. var active = record.service_mode === '1';
  8. if(active) {
  9. return <button className='btn btn-warning' onClick={this.props.onClick}>On</button>
  10. }
  11. else {
  12. return <button className='btn btn-default' onClick={this.props.onClick}>Off</button>
  13. }
  14. }
  15. else {
  16. return <span></span>;
  17. }
  18. }
  19. });
  20. var RecordCreate = React.createClass({
  21. getInitialState: function() {
  22. return {saving: false};
  23. },
  24. types: ['A', 'AAAA', 'CNAME'],
  25. finishSave: function(promise) {
  26. promise.then(this.props.onEdit).then(function() {
  27. this.setState({saving: false});
  28. this.reset();
  29. }.bind(this));
  30. },
  31. reset: function() {
  32. this.refs.type.getDOMNode().value = this.types[0];
  33. this.refs.name.getDOMNode().value = "";
  34. this.refs.value.getDOMNode().value = "";
  35. },
  36. commitAdd: function() {
  37. this.setState({saving: true});
  38. var newRecord = {
  39. type: this.refs.type.getDOMNode().value,
  40. name: this.refs.name.getDOMNode().value.trim(),
  41. content: this.refs.value.getDOMNode().value.trim()
  42. };
  43. this.finishSave(cloudflare.record_add(this.props.domain, newRecord));
  44. },
  45. render: function() {
  46. var className = this.state.saving ? 'saving' : '';
  47. var options = this.types.map(function(type) {
  48. return <option key={type} value={type}>{type}</option>
  49. });
  50. return (
  51. <tr className={className}>
  52. <td>
  53. <select ref="type">
  54. {options}
  55. </select>
  56. </td>
  57. <td><input type="text" ref="name" /></td>
  58. <td><input type="text" ref="value" /></td>
  59. <td></td>
  60. <td>
  61. <button className="btn btn-success" onClick={this.commitAdd}>Add</button>
  62. </td>
  63. </tr>
  64. )
  65. }
  66. });
  67. var Record = React.createClass({
  68. getInitialState: function() {
  69. return {state: 'view', saving: false};
  70. },
  71. setDeleting: function() {
  72. this.setState({state: 'delete'});
  73. },
  74. setEditing: function() {
  75. this.setState({state: 'edit'});
  76. },
  77. cancelEdit: function() {
  78. this.setState({state: 'view'});
  79. },
  80. finishSave: function(promise) {
  81. promise.then(this.props.onEdit).then(function() {
  82. this.setState({state: 'view', saving: false});
  83. }.bind(this));
  84. },
  85. commitDelete: function() {
  86. this.setState({saving: true});
  87. var record = this.props.record;
  88. this.finishSave(cloudflare.record_delete(record.zone_name, record.rec_id));
  89. },
  90. commitEdit: function() {
  91. this.setState({saving: true});
  92. var record = this.props.record;
  93. var newRecord = {
  94. id: record.rec_id,
  95. type: record.type,
  96. name: this.refs.name.getDOMNode().value.trim(),
  97. content: this.refs.value.getDOMNode().value.trim()
  98. };
  99. if(record.service_mode) {
  100. newRecord.service_mode = record.service_mode;
  101. }
  102. this.finishSave(cloudflare.record_edit(record.zone_name, newRecord));
  103. },
  104. toggleProxy: function() {
  105. this.setState({saving: true});
  106. var record = this.props.record;
  107. var newRecord = {
  108. id: record.rec_id,
  109. type: record.type,
  110. name: record.name,
  111. content: record.content,
  112. service_mode: record.service_mode === "1" ? "0" : "1"
  113. };
  114. this.finishSave(cloudflare.record_edit(record.zone_name, newRecord));
  115. },
  116. render: function() {
  117. var record = this.props.record;
  118. var className = this.state.saving ? 'saving' : '';
  119. if(this.state.state === 'edit') {
  120. return (
  121. <tr className={className}>
  122. <td className="record-type"><span className={record.type}>{record.type}</span></td>
  123. <td><input type="text" ref="name" defaultValue={record.display_name} /></td>
  124. <td><input type="text" ref="value" defaultValue={record.display_content} /></td>
  125. <td>
  126. <a onClick={this.cancelEdit}>Cancel</a>
  127. </td>
  128. <td>
  129. <button className="btn btn-success" onClick={this.commitEdit}>Save</button>
  130. </td>
  131. </tr>
  132. );
  133. }
  134. else if(this.state.state === 'delete') {
  135. return (
  136. <tr className={className}>
  137. <td className="record-type"><span className={record.type}>{record.type}</span></td>
  138. <td><strong>{record.display_name}</strong></td>
  139. <td>{record.display_content}</td>
  140. <td>
  141. <a onClick={this.cancelEdit}>Cancel</a>
  142. </td>
  143. <td>
  144. <button className="btn btn-danger" onClick={this.commitDelete}>Delete</button>
  145. </td>
  146. </tr>
  147. );
  148. }
  149. else {
  150. return (
  151. <tr className={className}>
  152. <td className="record-type"><span className={record.type}>{record.type}</span></td>
  153. <td><strong>{record.display_name}</strong></td>
  154. <td className="value">{record.display_content}</td>
  155. <td><CloudActive record={record} onClick={this.toggleProxy} /></td>
  156. <td className="actions">
  157. <button className="btn btn-primary" onClick={this.setEditing}>Edit</button>
  158. <span> </span>
  159. <button className="btn btn-danger" onClick={this.setDeleting}>Delete</button>
  160. </td>
  161. </tr>
  162. );
  163. }
  164. }
  165. });
  166. var RecordList = React.createClass({
  167. getInitialState: function() {
  168. return {records: []};
  169. },
  170. componentDidMount: function() {
  171. this.reload();
  172. },
  173. componentWillReceiveProps: function(nextProps) {
  174. if(nextProps.domain != this.props.domain) {
  175. this.setState({records: []});
  176. this.reload(nextProps);
  177. }
  178. },
  179. reload: function(props) {
  180. if(!props) {
  181. props = this.props;
  182. }
  183. return cloudflare.records(props.domain).then(function(data) {
  184. this.setState({records: data.response.recs.objs});
  185. }.bind(this));
  186. },
  187. render: function() {
  188. var records = this.state.records.map(function(record) {
  189. return <Record key={record.rec_id} record={record} onEdit={this.reload} />
  190. }.bind(this));
  191. return (
  192. <div id="records">
  193. <table className="table">
  194. <thead>
  195. <tr>
  196. <th className="type">Type</th>
  197. <th className="name">Name</th>
  198. <th className="value">Value</th>
  199. <th className="proxy">Proxy</th>
  200. <th className="actions">Actions</th>
  201. </tr>
  202. </thead>
  203. <tbody>
  204. <RecordCreate domain={this.props.domain} onEdit={this.reload} />
  205. {records}
  206. </tbody>
  207. </table>
  208. </div>
  209. );
  210. }
  211. });
  212. module.exports = RecordList;