11import React from 'react' ;
22import _ from 'underscore' ;
33
4- import AlertActions from '../actions/alertActions' ;
5- import ApiMixin from '../mixins/apiMixin' ;
6- import IndicatorStore from '../stores/indicatorStore' ;
7- import LoadingIndicator from '../components/loadingIndicator' ;
4+ import AsyncView from './asyncView' ;
85import { t } from '../locale' ;
96import { getOption , getOptionField } from '../options' ;
10- import { Form } from '../components/forms' ;
7+ import { ApiForm } from '../components/forms' ;
118
129const optionsAvailable = [
1310 'system.url-prefix' ,
@@ -21,190 +18,52 @@ const optionsAvailable = [
2118 'api.rate-limit.org-create'
2219] ;
2320
24- const SettingsList = React . createClass ( {
25- propTypes : {
26- formDisabled : React . PropTypes . bool ,
27- options : React . PropTypes . object . isRequired ,
28- onSubmit : React . PropTypes . func . isRequired
29- } ,
21+ export default class AdminSettings extends AsyncView {
22+ getEndpoint ( ) {
23+ return '/internal/options/' ;
24+ }
25+
26+ renderBody ( ) {
27+ let { data} = this . state ;
3028
31- getInitialState ( ) {
32- let options = this . props . options ;
33- let formData = { } ;
34- let required = [ ] ;
29+ let initialData = { } ;
3530 let fields = { } ;
3631 for ( let key of optionsAvailable ) {
3732 // TODO(dcramer): we should not be mutating options
38- let option = options [ key ] || { field : { } } ;
33+ let option = data [ key ] || { field : { } } ;
3934 if ( _ . isUndefined ( option . value ) || option . value === '' ) {
4035 let defn = getOption ( key ) ;
41- formData [ key ] = defn . defaultValue ? defn . defaultValue ( ) : '' ;
36+ initialData [ key ] = defn . defaultValue ? defn . defaultValue ( ) : '' ;
4237 } else {
43- formData [ key ] = option . value ;
44- }
45- if ( option . field . required ) {
46- required . push ( key ) ;
38+ initialData [ key ] = option . value ;
4739 }
48- fields [ key ] = getOptionField (
49- key ,
50- this . onFieldChange . bind ( this , key ) ,
51- formData [ key ] ,
52- option . field
53- ) ;
40+ fields [ key ] = getOptionField ( key , option . field ) ;
5441 }
5542
56- return {
57- required : required ,
58- formData : formData ,
59- fields : fields
60- } ;
61- } ,
62-
63- onFieldChange ( name , value ) {
64- let formData = this . state . formData ;
65- formData [ name ] = value ;
66- this . setState ( {
67- formData : formData
68- } ) ;
69- } ,
70-
71- onSubmit ( e ) {
72- this . props . onSubmit ( this . state . formData ) ;
73- } ,
74-
75- render ( ) {
76- let { fields, required, formData} = this . state ;
77- let formValid = ! required . filter ( option => ! formData [ option ] ) . length ;
78- let submitDisabled = ! formValid || this . props . formDisabled ;
79-
80- return (
81- < Form onSubmit = { this . onSubmit } submitDisabled = { submitDisabled } >
82- < h4 > General</ h4 >
83- { fields [ 'system.url-prefix' ] }
84- { fields [ 'system.admin-email' ] }
85- { fields [ 'system.support-email' ] }
86- { fields [ 'system.security-email' ] }
87- { fields [ 'system.rate-limit' ] }
88-
89- < h4 > Security & Abuse </ h4 >
90- { fields [ 'auth.allow-registration' ] }
91- { fields [ 'auth.ip-rate-limit' ] }
92- { fields [ 'auth.user-rate-limit' ] }
93- { fields [ 'api.rate-limit.org-create' ] }
94- </ Form >
95- ) ;
96- }
97- } ) ;
98-
99- const AdminSettings = React . createClass ( {
100- mixins : [ ApiMixin ] ,
101-
102- getInitialState ( ) {
103- return {
104- loading : true ,
105- error : false ,
106- submitInProgress : false ,
107- submitError : null ,
108- options : { }
109- } ;
110- } ,
111-
112- componentWillMount ( ) {
113- this . fetchData ( ) ;
114- } ,
115-
116- remountComponent ( ) {
117- this . setState ( this . getInitialState ( ) , this . fetchData ) ;
118- } ,
119-
120- fetchData ( callback ) {
121- this . api . request ( '/internal/options/' , {
122- method : 'GET' ,
123- success : data => {
124- this . setState ( {
125- options : data ,
126- loading : false ,
127- error : false
128- } ) ;
129- } ,
130- error : ( ) => {
131- this . setState ( {
132- loading : false ,
133- error : true
134- } ) ;
135- }
136- } ) ;
137- } ,
138-
139- onSubmit ( formData ) {
140- this . setState ( {
141- submitInProgress : true ,
142- submitError : false
143- } ) ;
144- let loadingIndicator = IndicatorStore . add ( t ( 'Saving changes..' ) ) ;
145-
146- // We only want to send back the values which weren't disabled
147- formData = _ . pick ( formData , ( value , key ) => {
148- return ! this . state . options [ key ] . field . disabled ;
149- } ) ;
150- this . api . request ( '/internal/options/' , {
151- method : 'PUT' ,
152- data : formData ,
153- success : ( ) => {
154- this . setState ( {
155- submitInProgress : false
156- } ) ;
157- AlertActions . addAlert ( {
158- message : t ( 'Your changes were saved, and will propagate to services shortly.' ) ,
159- type : 'success'
160- } ) ;
161- } ,
162- error : ( ) => {
163- this . setState ( {
164- submitInProgress : false ,
165- submitError : true
166- } ) ;
167- } ,
168- complete : ( ) => {
169- IndicatorStore . remove ( loadingIndicator ) ;
170- }
171- } ) ;
172- } ,
173-
174- render ( ) {
175- let { error, loading, options, submitError, submitInProgress} = this . state ;
176-
17743 return (
17844 < div >
17945 < h3 > { t ( 'Settings' ) } </ h3 >
18046
181- { loading
182- ? < LoadingIndicator >
183- { t ( 'Please wait while we load configuration.' ) }
184- </ LoadingIndicator >
185- : error
186- ? < div className = "loading-error" >
187- < span className = "icon" />
188- { t (
189- 'We were unable to load the required configuration from the Sentry server. Please take a look at the service logs.'
190- ) }
191- </ div >
192- : < div >
193- { submitError &&
194- < div className = "alert alert-block alert-error" >
195- { t (
196- 'We were unable to submit your changes to the Sentry server. Please take a look at the service logs.'
197- ) }
198- </ div > }
199- < SettingsList
200- options = { options }
201- onSubmit = { this . onSubmit }
202- formDisabled = { submitInProgress }
203- />
204- </ div > }
47+ < ApiForm
48+ apiMethod = "PUT"
49+ apiEndpoint = { this . getEndpoint ( ) }
50+ onSubmit = { this . onSubmit }
51+ initialData = { initialData }
52+ requireChanges = { true } >
53+ < h4 > General</ h4 >
54+ { fields [ 'system.url-prefix' ] }
55+ { fields [ 'system.admin-email' ] }
56+ { fields [ 'system.support-email' ] }
57+ { fields [ 'system.security-email' ] }
58+ { fields [ 'system.rate-limit' ] }
59+
60+ < h4 > Security & Abuse </ h4 >
61+ { fields [ 'auth.allow-registration' ] }
62+ { fields [ 'auth.ip-rate-limit' ] }
63+ { fields [ 'auth.user-rate-limit' ] }
64+ { fields [ 'api.rate-limit.org-create' ] }
65+ </ ApiForm >
20566 </ div >
20667 ) ;
20768 }
208- } ) ;
209-
210- export default AdminSettings ;
69+ }
0 commit comments