mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: Should be possible to remove applications
https://github.com/Unleash/unleash/issues/634
This commit is contained in:
		
							parent
							
								
									a097a90dbe
								
							
						
					
					
						commit
						b1d30b045e
					
				| @ -23,7 +23,7 @@ exports[`renders correctly with permissions 1`] = ` | ||||
|     <react-mdl-Icon | ||||
|       name="apps" | ||||
|     /> | ||||
|       | ||||
|       | ||||
|     test-app | ||||
|   </react-mdl-CardTitle> | ||||
|   <react-mdl-CardText> | ||||
| @ -41,27 +41,48 @@ exports[`renders correctly with permissions 1`] = ` | ||||
|       /> | ||||
|     </a> | ||||
|   </react-mdl-CardMenu> | ||||
|   <hr /> | ||||
|   <react-mdl-Tabs | ||||
|     activeTab={0} | ||||
|     className="mdl-color--grey-100" | ||||
|     onChange={[Function]} | ||||
|     ripple={true} | ||||
|     tabBarProps={ | ||||
|       Object { | ||||
|         "style": Object { | ||||
|           "width": "100%", | ||||
|         }, | ||||
|   <div> | ||||
|     <react-mdl-CardActions | ||||
|       border={true} | ||||
|       style={ | ||||
|         Object { | ||||
|           "alignItems": "center", | ||||
|           "display": "flex", | ||||
|           "justifyContent": "space-between", | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   > | ||||
|     <react-mdl-Tab> | ||||
|       Details | ||||
|     </react-mdl-Tab> | ||||
|     <react-mdl-Tab> | ||||
|       Edit | ||||
|     </react-mdl-Tab> | ||||
|   </react-mdl-Tabs> | ||||
|     > | ||||
|       <span /> | ||||
|       <react-mdl-Button | ||||
|         accent={true} | ||||
|         onClick={[Function]} | ||||
|         title="Delete application" | ||||
|       > | ||||
|         Delete | ||||
|       </react-mdl-Button> | ||||
|     </react-mdl-CardActions> | ||||
|     <hr /> | ||||
|     <react-mdl-Tabs | ||||
|       activeTab={0} | ||||
|       className="mdl-color--grey-100" | ||||
|       onChange={[Function]} | ||||
|       ripple={true} | ||||
|       tabBarProps={ | ||||
|         Object { | ||||
|           "style": Object { | ||||
|             "width": "100%", | ||||
|           }, | ||||
|         } | ||||
|       } | ||||
|     > | ||||
|       <react-mdl-Tab> | ||||
|         Details | ||||
|       </react-mdl-Tab> | ||||
|       <react-mdl-Tab> | ||||
|         Edit | ||||
|       </react-mdl-Tab> | ||||
|     </react-mdl-Tabs> | ||||
|   </div> | ||||
|   <react-mdl-Grid | ||||
|     style={ | ||||
|       Object { | ||||
| @ -214,7 +235,7 @@ exports[`renders correctly without permission 1`] = ` | ||||
|     <react-mdl-Icon | ||||
|       name="apps" | ||||
|     /> | ||||
|       | ||||
|       | ||||
|     test-app | ||||
|   </react-mdl-CardTitle> | ||||
|   <react-mdl-CardText> | ||||
| @ -232,7 +253,6 @@ exports[`renders correctly without permission 1`] = ` | ||||
|       /> | ||||
|     </a> | ||||
|   </react-mdl-CardMenu> | ||||
|   <hr /> | ||||
|    | ||||
|   <react-mdl-Grid | ||||
|     style={ | ||||
|  | ||||
| @ -4,9 +4,11 @@ import PropTypes from 'prop-types'; | ||||
| 
 | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { | ||||
|     Button, | ||||
|     Grid, | ||||
|     Cell, | ||||
|     Card, | ||||
|     CardActions, | ||||
|     CardTitle, | ||||
|     CardText, | ||||
|     CardMenu, | ||||
| @ -64,7 +66,9 @@ class ClientApplications extends PureComponent { | ||||
|         application: PropTypes.object, | ||||
|         location: PropTypes.object, | ||||
|         storeApplicationMetaData: PropTypes.func.isRequired, | ||||
|         deleteApplication: PropTypes.func.isRequired, | ||||
|         hasPermission: PropTypes.func.isRequired, | ||||
|         history: PropTypes.object.isRequired, | ||||
|     }; | ||||
| 
 | ||||
|     constructor(props) { | ||||
| @ -78,6 +82,14 @@ class ClientApplications extends PureComponent { | ||||
|     formatFullDateTime(v) { | ||||
|         return formatFullDateTimeWithLocale(v, this.props.location.locale); | ||||
|     } | ||||
| 
 | ||||
|     deleteApplication = async evt => { | ||||
|         evt.preventDefault(); | ||||
|         const { deleteApplication, appName } = this.props; | ||||
|         await deleteApplication(appName); | ||||
|         this.props.history.push('/applications'); | ||||
|     }; | ||||
| 
 | ||||
|     render() { | ||||
|         if (!this.props.application) { | ||||
|             return <ProgressBar indeterminate />; | ||||
| @ -173,9 +185,6 @@ class ClientApplications extends PureComponent { | ||||
|                 </Grid> | ||||
|             ) : ( | ||||
|                 <Grid> | ||||
|                     <Cell col={12}> | ||||
|                         <h5>Edit app meta data</h5> | ||||
|                     </Cell> | ||||
|                     <Cell col={6} tablet={12}> | ||||
|                         <StatefulTextfield | ||||
|                             value={url} | ||||
| @ -194,7 +203,7 @@ class ClientApplications extends PureComponent { | ||||
|                     <Cell col={6} tablet={12}> | ||||
|                         <MySelect | ||||
|                             label="Icon" | ||||
|                             options={icons.map(v => ({ name: v, label: v }))} | ||||
|                             options={icons.map(v => ({ key: v, label: v }))} | ||||
|                             value={icon} | ||||
|                             onChange={e => storeApplicationMetaData(appName, 'icon', e.target.value)} | ||||
|                             filled | ||||
| @ -211,7 +220,7 @@ class ClientApplications extends PureComponent { | ||||
|         return ( | ||||
|             <Card shadow={0} className={commonStyles.fullwidth}> | ||||
|                 <CardTitle style={{ paddingTop: '24px', paddingRight: '64px', wordBreak: 'break-all' }}> | ||||
|                     <Icon name={icon} /> | ||||
|                     <Icon name={icon || 'apps'} /> | ||||
|                      {appName} | ||||
|                 </CardTitle> | ||||
|                 {description && <CardText>{description}</CardText>} | ||||
| @ -220,18 +229,33 @@ class ClientApplications extends PureComponent { | ||||
|                         <IconLink url={url} icon="link" /> | ||||
|                     </CardMenu> | ||||
|                 )} | ||||
|                 <hr /> | ||||
|                 {hasPermission(UPDATE_APPLICATION) ? ( | ||||
|                     <Tabs | ||||
|                         activeTab={this.state.activeTab} | ||||
|                         onChange={tabId => this.setState({ activeTab: tabId })} | ||||
|                         ripple | ||||
|                         tabBarProps={{ style: { width: '100%' } }} | ||||
|                         className="mdl-color--grey-100" | ||||
|                     > | ||||
|                         <Tab>Details</Tab> | ||||
|                         <Tab>Edit</Tab> | ||||
|                     </Tabs> | ||||
|                     <div> | ||||
|                         <CardActions | ||||
|                             border | ||||
|                             style={{ | ||||
|                                 display: 'flex', | ||||
|                                 alignItems: 'center', | ||||
|                                 justifyContent: 'space-between', | ||||
|                             }} | ||||
|                         > | ||||
|                             <span /> | ||||
|                             <Button accent title="Delete application" onClick={this.deleteApplication}> | ||||
|                                 Delete | ||||
|                             </Button> | ||||
|                         </CardActions> | ||||
|                         <hr /> | ||||
|                         <Tabs | ||||
|                             activeTab={this.state.activeTab} | ||||
|                             onChange={tabId => this.setState({ activeTab: tabId })} | ||||
|                             ripple | ||||
|                             tabBarProps={{ style: { width: '100%' } }} | ||||
|                             className="mdl-color--grey-100" | ||||
|                         > | ||||
|                             <Tab>Details</Tab> | ||||
|                             <Tab>Edit</Tab> | ||||
|                         </Tabs> | ||||
|                     </div> | ||||
|                 ) : ( | ||||
|                     '' | ||||
|                 )} | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| import { connect } from 'react-redux'; | ||||
| import ApplicationEdit from './application-edit-component'; | ||||
| import { fetchApplication, storeApplicationMetaData } from './../../store/application/actions'; | ||||
| import { fetchApplication, storeApplicationMetaData, deleteApplication } from './../../store/application/actions'; | ||||
| import { hasPermission } from '../../permissions'; | ||||
| 
 | ||||
| const mapStateToProps = (state, props) => { | ||||
| @ -19,6 +19,7 @@ const mapStateToProps = (state, props) => { | ||||
| const Constainer = connect(mapStateToProps, { | ||||
|     fetchApplication, | ||||
|     storeApplicationMetaData, | ||||
|     deleteApplication, | ||||
| })(ApplicationEdit); | ||||
| 
 | ||||
| export default Constainer; | ||||
|  | ||||
| @ -34,9 +34,18 @@ function storeApplicationMetaData(appName, key, value) { | ||||
|     }).then(throwIfNotSuccess); | ||||
| } | ||||
| 
 | ||||
| function deleteApplication(appName) { | ||||
|     return fetch(`${URI}/${appName}`, { | ||||
|         method: 'DELETE', | ||||
|         headers, | ||||
|         credentials: 'include', | ||||
|     }).then(throwIfNotSuccess); | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|     fetchApplication, | ||||
|     fetchAll, | ||||
|     fetchApplicationsWithStrategyName, | ||||
|     storeApplicationMetaData, | ||||
|     deleteApplication, | ||||
| }; | ||||
|  | ||||
| @ -2,10 +2,11 @@ import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import ApplicationEditComponent from '../../component/application/application-edit-container'; | ||||
| 
 | ||||
| const render = ({ match: { params } }) => <ApplicationEditComponent appName={params.name} />; | ||||
| const render = ({ match: { params }, history }) => <ApplicationEditComponent appName={params.name} history={history} />; | ||||
| 
 | ||||
| render.propTypes = { | ||||
|     match: PropTypes.object.isRequired, | ||||
|     history: PropTypes.object.isRequired, | ||||
| }; | ||||
| 
 | ||||
| export default render; | ||||
|  | ||||
| @ -7,6 +7,8 @@ export const ERROR_UPDATING_APPLICATION_DATA = 'ERROR_UPDATING_APPLICATION_DATA' | ||||
| 
 | ||||
| export const RECEIVE_APPLICATION = 'RECEIVE_APPLICATION'; | ||||
| export const UPDATE_APPLICATION_FIELD = 'UPDATE_APPLICATION_FIELD'; | ||||
| export const DELETE_APPLICATION = 'DELETE_APPLICATION'; | ||||
| export const ERROR_DELETE_APPLICATION = 'ERROR_DELETE_APPLICATION'; | ||||
| 
 | ||||
| const recieveAllApplications = json => ({ | ||||
|     type: RECEIVE_ALL_APPLICATIONS, | ||||
| @ -41,3 +43,11 @@ export function fetchApplication(appName) { | ||||
|             .then(json => dispatch(recieveApplication(json))) | ||||
|             .catch(dispatchAndThrow(dispatch, ERROR_RECEIVE_ALL_APPLICATIONS)); | ||||
| } | ||||
| 
 | ||||
| export function deleteApplication(appName) { | ||||
|     return dispatch => | ||||
|         api | ||||
|             .deleteApplication(appName) | ||||
|             .then(() => dispatch({ type: DELETE_APPLICATION, appName })) | ||||
|             .catch(dispatchAndThrow(dispatch, ERROR_DELETE_APPLICATION)); | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| import { fromJS, List, Map } from 'immutable'; | ||||
| import { RECEIVE_ALL_APPLICATIONS, RECEIVE_APPLICATION, UPDATE_APPLICATION_FIELD } from './actions'; | ||||
| import { RECEIVE_ALL_APPLICATIONS, RECEIVE_APPLICATION, UPDATE_APPLICATION_FIELD, DELETE_APPLICATION } from './actions'; | ||||
| import { USER_LOGOUT, USER_LOGIN } from '../user/actions'; | ||||
| 
 | ||||
| function getInitState() { | ||||
| @ -14,6 +14,11 @@ const store = (state = getInitState(), action) => { | ||||
|             return state.set('list', new List(action.value.applications)); | ||||
|         case UPDATE_APPLICATION_FIELD: | ||||
|             return state.setIn(['apps', action.appName, action.key], action.value); | ||||
|         case DELETE_APPLICATION: { | ||||
|             const index = state.get('list').findIndex(item => item.appName === action.appName); | ||||
|             const result = state.removeIn(['list', index]); | ||||
|             return result.removeIn(['apps', action.appName]); | ||||
|         } | ||||
|         case USER_LOGOUT: | ||||
|         case USER_LOGIN: | ||||
|             return getInitState(); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user