RecordList.jsx 6.4 KB

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