Skip to content

Commit c0d6d1c

Browse files
committed
added delete account button
1 parent 18d4bcd commit c0d6d1c

File tree

6 files changed

+281
-30
lines changed

6 files changed

+281
-30
lines changed
Loading

src/main/java/org/mskcc/cbio/oncokb/service/impl/CompanyServiceImpl.java

+36-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
import org.mskcc.cbio.oncokb.service.CompanyService;
55
import org.mskcc.cbio.oncokb.config.cache.CacheNameResolver;
66
import org.mskcc.cbio.oncokb.domain.Company;
7+
import org.mskcc.cbio.oncokb.domain.User;
8+
import org.mskcc.cbio.oncokb.domain.UserDetails;
79
import org.mskcc.cbio.oncokb.domain.enumeration.LicenseStatus;
10+
import org.mskcc.cbio.oncokb.domain.enumeration.LicenseType;
811
import org.mskcc.cbio.oncokb.repository.CompanyRepository;
12+
import org.mskcc.cbio.oncokb.repository.UserDetailsRepository;
13+
import org.mskcc.cbio.oncokb.repository.UserRepository;
914
import org.mskcc.cbio.oncokb.service.dto.CompanyDTO;
1015
import org.mskcc.cbio.oncokb.service.dto.UserDTO;
1116
import org.mskcc.cbio.oncokb.service.mapper.CompanyDomainMapper;
@@ -49,6 +54,10 @@ public class CompanyServiceImpl implements CompanyService {
4954

5055
private final CacheNameResolver cacheNameResolver;
5156

57+
private final UserRepository userRepository;
58+
59+
private final UserDetailsRepository userDetailsRepository;
60+
5261
public CompanyServiceImpl(
5362
CompanyRepository companyRepository,
5463
CompanyMapper companyMapper,
@@ -57,14 +66,18 @@ public CompanyServiceImpl(
5766
UserService userService,
5867
UserMapper userMapper,
5968
CacheManager cacheManager,
60-
CacheNameResolver cacheNameResolver
69+
CacheNameResolver cacheNameResolver,
70+
UserRepository userRepository,
71+
UserDetailsRepository userDetailsRepository
6172
) {
6273
this.companyRepository = companyRepository;
6374
this.companyMapper = companyMapper;
6475
this.userMapper = userMapper;
6576
this.userService = userService;
6677
this.cacheManager = cacheManager;
6778
this.cacheNameResolver = cacheNameResolver;
79+
this.userRepository = userRepository;
80+
this.userDetailsRepository = userDetailsRepository;
6881
}
6982

7083
@Override
@@ -168,8 +181,30 @@ public Optional<CompanyDTO> findOneByNameIgnoreCase(String name) {
168181
}
169182

170183
@Override
184+
@Transactional()
171185
public void delete(Long id) {
172186
log.debug("Request to delete Company : {}", id);
187+
Optional<CompanyDTO> maybeCompanyDTO = this.findOne(id);
188+
if (!maybeCompanyDTO.isPresent()) {
189+
return;
190+
}
191+
192+
CompanyDTO companyDTO = maybeCompanyDTO.get();
193+
Boolean isCommercial = companyDTO.getLicenseType().equals(LicenseType.COMMERCIAL);
194+
List<UserDetails> userDetails = userDetailsRepository.findByCompanyId(id);
195+
for (UserDetails userDetail : userDetails) {
196+
userDetail.setCompany(null);
197+
}
198+
199+
if (isCommercial) {
200+
List<User> users = userDetails.stream().map(UserDetails::getUser).collect(Collectors.toList());
201+
for (User user : users) {
202+
user.setActivated(false);
203+
}
204+
userRepository.saveAll(users);
205+
}
206+
207+
userDetailsRepository.saveAll(userDetails);
173208
companyRepository.deleteById(id);
174209
}
175210

src/main/java/org/mskcc/cbio/oncokb/web/rest/CompanyResource.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package org.mskcc.cbio.oncokb.web.rest;
22

33
import org.mskcc.cbio.oncokb.domain.Company;
4+
import org.mskcc.cbio.oncokb.domain.User;
5+
import org.mskcc.cbio.oncokb.domain.UserDetails;
46
import org.mskcc.cbio.oncokb.domain.enumeration.LicenseType;
57
import org.mskcc.cbio.oncokb.repository.CompanyRepository;
8+
import org.mskcc.cbio.oncokb.repository.UserDetailsRepository;
9+
import org.mskcc.cbio.oncokb.repository.UserRepository;
610
import org.mskcc.cbio.oncokb.security.AuthoritiesConstants;
711
import org.mskcc.cbio.oncokb.service.CompanyService;
12+
import org.mskcc.cbio.oncokb.service.UserDetailsService;
813
import org.mskcc.cbio.oncokb.service.UserService;
914
import org.mskcc.cbio.oncokb.web.rest.errors.BadRequestAlertException;
1015
import org.mskcc.cbio.oncokb.web.rest.vm.CompanyVM;
@@ -47,7 +52,10 @@ public class CompanyResource {
4752

4853
private final CompanyRepository companyRepository;
4954

50-
public CompanyResource(CompanyService companyService, UserService userService, CompanyRepository companyRepository) {
55+
public CompanyResource(
56+
CompanyService companyService,
57+
UserService userService,
58+
CompanyRepository companyRepository) {
5159
this.companyService = companyService;
5260
this.userService = userService;
5361
this.companyRepository = companyRepository;
@@ -174,4 +182,17 @@ public ResponseEntity<Boolean> verifyCompanyName(@Valid @RequestBody VerifyCompa
174182
}
175183
return new ResponseEntity<>(isValid, HttpStatus.OK);
176184
}
185+
186+
/**
187+
* {@code DELETE /companies/:id} : delete the "id" company.
188+
*
189+
* @param id the id of the companyDTO to delete.
190+
* @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
191+
*/
192+
@DeleteMapping("/companies/{id}")
193+
public ResponseEntity<Void> deleteCompany(@PathVariable Long id) {
194+
log.debug("REST request to delete Company : {}", id);
195+
companyService.delete(id);
196+
return ResponseEntity.ok().build();
197+
}
177198
}

src/main/webapp/app/pages/companyPage/CompanyPage.tsx

+113-28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { observer } from 'mobx-react';
2+
import { inject, observer } from 'mobx-react';
33
import { getSectionClassName } from 'app/pages/account/AccountUtils';
44
import { AvField, AvForm } from 'availity-reactstrap-validation';
55
import {
@@ -10,6 +10,7 @@ import {
1010
LicenseModel,
1111
LicenseStatus,
1212
PAGE_ROUTE,
13+
REDIRECT_TIMEOUT_MILLISECONDS,
1314
} from 'app/config/constants';
1415
import { Alert, Button, Col, Row } from 'react-bootstrap';
1516
import {
@@ -67,11 +68,16 @@ import {
6768
import UsageText from 'app/shared/texts/UsageText';
6869
import { DateSelector } from 'app/components/dateSelector/DateSelector';
6970
import { DownloadButton } from 'app/components/downloadButton/DownloadButton';
71+
import { RouterStore } from 'mobx-react-router';
7072

7173
interface MatchParams {
7274
id: string;
7375
}
7476

77+
interface ICompanyPage extends RouteComponentProps<MatchParams> {
78+
routing: RouterStore;
79+
}
80+
7581
type SelectOptionType = {
7682
label: string;
7783
value: string;
@@ -97,18 +103,23 @@ const LICENSE_STATUS_UPDATE_MESSAGES = {
97103
},
98104
};
99105

106+
enum SimpleConfirmModalType {
107+
NA,
108+
DELETE_COMPANY,
109+
UPDATE_COMPANY,
110+
}
111+
112+
@inject('routing')
100113
@observer
101-
export default class CompanyPage extends React.Component<
102-
RouteComponentProps<MatchParams>
103-
> {
114+
export default class CompanyPage extends React.Component<ICompanyPage> {
104115
@observable getCompanyStatus = PromiseStatus.pending;
105116
@observable getCompanyUsersStatus = PromiseStatus.pending;
106117
@observable getDropdownUsersStatus = PromiseStatus.pending;
107118

108119
@observable selectedLicenseStatus: LicenseStatus;
109120
@observable conflictingDomains: string[] = [];
110121

111-
@observable showLicenseChangeModal = false;
122+
@observable showModal = false;
112123
@observable confirmLicenseChangeModalText = '';
113124
@observable formValues: any;
114125

@@ -118,10 +129,13 @@ export default class CompanyPage extends React.Component<
118129
@observable dropDownUsers: SelectOptionType[] = [];
119130
@observable selectedUsersOptions: SelectOptionType[] = [];
120131

132+
@observable simpleConfirmModalType: SimpleConfirmModalType =
133+
SimpleConfirmModalType.NA;
134+
121135
@observable resourcesTypeToggleValue: ToggleValue =
122136
ToggleValue.PUBLIC_RESOURCES;
123137

124-
constructor(props: RouteComponentProps<MatchParams>) {
138+
constructor(props: ICompanyPage) {
125139
super(props);
126140
this.getCompany();
127141
this.getDropdownUsers();
@@ -182,8 +196,8 @@ export default class CompanyPage extends React.Component<
182196
}
183197

184198
@action.bound
185-
updateCompany() {
186-
this.showLicenseChangeModal = false;
199+
onConfirmUpdateCompany() {
200+
this.showModal = false;
187201
this.getCompanyStatus = PromiseStatus.pending;
188202
this.getCompanyUsersStatus = PromiseStatus.pending;
189203
this.getDropdownUsersStatus = PromiseStatus.pending;
@@ -218,6 +232,38 @@ export default class CompanyPage extends React.Component<
218232
});
219233
}
220234

235+
@autobind
236+
onConfirmDeleteAccountButton() {
237+
this.showModal = false;
238+
client.deleteCompanyUsingDELETE({ id: this.company.id }).then(
239+
() => {
240+
notifySuccess(
241+
'Deleted company, we will redirect you to the company details page.'
242+
);
243+
setTimeout(() => {
244+
this.props.routing.history.push(PAGE_ROUTE.ADMIN_COMPANY_DETAILS);
245+
}, REDIRECT_TIMEOUT_MILLISECONDS);
246+
},
247+
(error: Error) => notifyError(error)
248+
);
249+
}
250+
251+
@autobind
252+
onConfirmSimpleConfirmModal() {
253+
switch (this.simpleConfirmModalType) {
254+
case SimpleConfirmModalType.UPDATE_COMPANY:
255+
this.onConfirmUpdateCompany();
256+
break;
257+
case SimpleConfirmModalType.DELETE_COMPANY:
258+
this.onConfirmDeleteAccountButton();
259+
break;
260+
case SimpleConfirmModalType.NA:
261+
default:
262+
break;
263+
}
264+
this.simpleConfirmModalType = SimpleConfirmModalType.NA;
265+
}
266+
221267
@action.bound
222268
async verifyUserEmail(user: UserDTO) {
223269
try {
@@ -247,13 +293,13 @@ export default class CompanyPage extends React.Component<
247293
this.company.licenseStatus !== this.selectedLicenseStatus &&
248294
this.companyUsers.length > 0
249295
) {
250-
this.showLicenseChangeModal = true;
296+
this.showModal = true;
251297
this.confirmLicenseChangeModalText =
252298
LICENSE_STATUS_UPDATE_MESSAGES[this.company.licenseStatus][
253299
this.selectedLicenseStatus
254300
];
255301
} else {
256-
this.updateCompany();
302+
this.onConfirmUpdateCompany();
257303
}
258304
}
259305

@@ -323,23 +369,41 @@ export default class CompanyPage extends React.Component<
323369
option => !hideOptions.includes(option.value)
324370
);
325371
}
372+
@computed
373+
get licenseChangeModalTitle() {
374+
if (this.simpleConfirmModalType === SimpleConfirmModalType.UPDATE_COMPANY) {
375+
return 'Review Company Changes';
376+
} else if (
377+
this.simpleConfirmModalType === SimpleConfirmModalType.DELETE_COMPANY
378+
) {
379+
return 'Confirm Deleting Company';
380+
}
381+
}
326382

327383
@computed
328384
get licenseChangeModalBody() {
329-
return (
330-
<>
331-
<div>
332-
Are you sure you want to change the company's license status from{' '}
333-
<span className="font-weight-bold">{this.company.licenseStatus}</span>{' '}
334-
to{' '}
335-
<span className="font-weight-bold">{this.selectedLicenseStatus}</span>
336-
?
337-
</div>
338-
<Alert variant={'warning'} style={{ marginTop: '20px' }}>
339-
Warning: {this.confirmLicenseChangeModalText}
340-
</Alert>
341-
</>
342-
);
385+
if (this.simpleConfirmModalType === SimpleConfirmModalType.UPDATE_COMPANY) {
386+
return (
387+
<>
388+
<div>
389+
Are you sure you want to change the company's license status from{' '}
390+
<span className="font-weight-bold">
391+
{this.company.licenseStatus}
392+
</span>{' '}
393+
to{' '}
394+
<span className="font-weight-bold">
395+
{this.selectedLicenseStatus}
396+
</span>
397+
?
398+
</div>
399+
<Alert variant={'warning'} style={{ marginTop: '20px' }}>
400+
Warning: {this.confirmLicenseChangeModalText}
401+
</Alert>
402+
</>
403+
);
404+
} else {
405+
return undefined;
406+
}
343407
}
344408

345409
@computed
@@ -876,13 +940,34 @@ export default class CompanyPage extends React.Component<
876940
</Button>
877941
</Col>
878942
</Row>
943+
<Row>
944+
<Col className={getSectionClassName()}>
945+
<div className={'my-2 text-danger'}>Danger Zone</div>
946+
<div>
947+
<Button
948+
variant="danger"
949+
onClick={() => {
950+
this.showModal = true;
951+
this.simpleConfirmModalType =
952+
SimpleConfirmModalType.DELETE_COMPANY;
953+
}}
954+
>
955+
Delete Account
956+
</Button>
957+
</div>
958+
</Col>
959+
</Row>
879960
</AvForm>
880961
<SimpleConfirmModal
881-
show={this.showLicenseChangeModal}
882-
title={'Review Company Changes'}
962+
key="company-page-simple-confirm-modal"
963+
show={this.showModal}
964+
title={this.licenseChangeModalTitle}
883965
body={this.licenseChangeModalBody}
884-
onCancel={() => (this.showLicenseChangeModal = false)}
885-
onConfirm={this.updateCompany}
966+
onCancel={() => {
967+
this.showModal = false;
968+
this.simpleConfirmModalType = SimpleConfirmModalType.NA;
969+
}}
970+
onConfirm={this.onConfirmSimpleConfirmModal}
886971
/>
887972
</>
888973
</DocumentTitle>

src/main/webapp/app/shared/api/generated/API-docs.json

+35
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,41 @@
10051005
}
10061006
},
10071007
"deprecated": false
1008+
},
1009+
"delete": {
1010+
"tags": [
1011+
"company-resource"
1012+
],
1013+
"summary": "deleteCompany",
1014+
"operationId": "deleteCompanyUsingDELETE",
1015+
"produces": [
1016+
"*/*"
1017+
],
1018+
"parameters": [
1019+
{
1020+
"name": "id",
1021+
"in": "path",
1022+
"description": "id",
1023+
"required": true,
1024+
"type": "integer",
1025+
"format": "int64"
1026+
}
1027+
],
1028+
"responses": {
1029+
"200": {
1030+
"description": "OK"
1031+
},
1032+
"204": {
1033+
"description": "No Content"
1034+
},
1035+
"401": {
1036+
"description": "Unauthorized"
1037+
},
1038+
"403": {
1039+
"description": "Forbidden"
1040+
}
1041+
},
1042+
"deprecated": false
10081043
}
10091044
},
10101045
"/api/companies/{id}/users": {

0 commit comments

Comments
 (0)