Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: live update after activate or deactivate user #350

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ please see [changelog_updates.md](docs/dev/changelog_updates.md).
- Fixed Confirm and Delete buttons' behavior in confirmation modals ([#304](https://github.com/sovity/authority-portal/issues/304))
- Fixed final step not showing when registering a central component ([#305](https://github.com/sovity/authority-portal/issues/305))
- Fixed My Organization page not updated when switching between environments ([#255](https://github.com/sovity/authority-portal/issues/255))
- Added live update when deactivating/reactivating users ([#287](https://github.com/sovity/authority-portal/issues/287))
- Fixed Website title not updating in some scenarios [#237](https://github.com/sovity/authority-portal/issues/237)
- Fixed security vulnerabilities

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,13 @@ export const AUTHORITY_PORTAL_FAKE_BACKEND: FetchAPI = async (

.url('authority/users/*/deactivate')
.on('PUT', (userId) => {
deactivateUser(userId);
return ok(userId);
})

.url('authority/users/*/reactivate')
.on('PUT', (userId) => {
reactivateUser(userId);
return ok(userId);
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,14 @@ export const getOrganizationDetails = (
) as OrganizationDetailsDto;
};

export const findOrganizationByUserId = (
userId: string,
): string | undefined => {
return TEST_ORGANIZATIONS.find((organization) =>
organization.memberList.some((member) => member.userId === userId),
)?.id;
};

export const getOrganizations = (): OrganizationDetailsDto[] => {
return TEST_ORGANIZATIONS;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
UserDeletionCheck,
UserDetailDto,
UserInfo,
UserRegistrationStatusDto,
UserRoleDto,
} from '@sovity.de/authority-portal-client';
import {Patcher, patchObj} from 'src/app/core/utils/object-utils';
Expand All @@ -32,6 +33,7 @@ import {
} from '../../../utils/user-role-utils';
import {
deleteOrganization,
findOrganizationByUserId,
getOrganizationDetails,
getParticipantAdmins,
updateOrganization,
Expand Down Expand Up @@ -447,12 +449,37 @@ export const clearApplicationRole = (
return {id: request.userId, changedDate: new Date()};
};

const updateUserStatusOfOrganizationById = (
userId: string,
status: UserRegistrationStatusDto,
) => {
const organizationId = findOrganizationByUserId(userId);
if (organizationId) {
updateOrganization(organizationId, (organization) => {
return {
...organization,
memberList: organization.memberList.map((member) => {
if (member.userId === userId) {
return {
...member,
registrationStatus: status,
};
}
return member;
}),
};
});
}
};

export const deactivateUser = (userId: string): IdResponse => {
updateUserStatusOfOrganizationById(userId, 'DEACTIVATED');
patchUser(userId, () => ({registrationStatus: 'DEACTIVATED'}));
return {id: userId, changedDate: new Date()};
};

export const reactivateUser = (userId: string): IdResponse => {
updateUserStatusOfOrganizationById(userId, 'ACTIVE');
patchUser(userId, () => ({registrationStatus: 'ACTIVE'}));
return {id: userId, changedDate: new Date()};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ export class AuthorityOrganizationDetailPageComponent
this.store.dispatch(RefreshOrganizations);
} else {
this.store
.dispatch(RefreshOrganization)
.dispatch(new RefreshOrganization())
.pipe(take(1))
.subscribe(() => {
this.slideOverService.setSlideOverViews(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class SetOrganizationId {

export class RefreshOrganization {
static readonly type = `[${tag}] Refresh Organization`;
constructor(public cb?: () => void) {}
}

export class ApproveOrganization {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {SlideOverService} from 'src/app/core/services/slide-over.service';
import {Fetched} from 'src/app/core/utils/fetched';
import {ToastService} from 'src/app/shared/common/toast-notifications/toast.service';
import {RefreshOrganizations} from '../../authority-organization-list-page/authority-organization-list-page/state/authority-organization-list-page-actions';
import {AuthorityOrganizationDetailTab} from '../authority-organization-detail-page/authority-organization-detail-page.model';
import {
ApproveOrganization,
DeactivateUser,
Expand Down Expand Up @@ -82,6 +83,7 @@ export class AuthorityOrganizationDetailPageStateImpl {
@Action(RefreshOrganization, {cancelUncompleted: true})
onRefreshOrganization(
ctx: StateContext<AuthorityOrganizationDetailPageState>,
action: RefreshOrganization,
): Observable<never> {
return this.globalStateUtils.getDeploymentEnvironmentId().pipe(
switchMap((deploymentEnvironmentId) =>
Expand All @@ -91,20 +93,26 @@ export class AuthorityOrganizationDetailPageStateImpl {
),
),
Fetched.wrap({failureMessage: 'Failed loading organizations'}),
tap((organization) => this.organizationRefreshed(ctx, organization)),
tap((organization) =>
this.organizationRefreshed(ctx, organization, action.cb),
),
ignoreElements(),
);
}

private organizationRefreshed(
ctx: StateContext<AuthorityOrganizationDetailPageState>,
organization: Fetched<OrganizationDetailsDto>,
cb?: () => void,
) {
this.globalStateUtils.updateNestedProperty(
ctx,
'organizationDetail.organization',
organization,
);
if (cb) {
cb();
}
}

@Action(ApproveOrganization)
Expand Down Expand Up @@ -251,6 +259,13 @@ export class AuthorityOrganizationDetailPageStateImpl {
);
}

redirectToMembersTab() {
this.slideOverService.setSlideOverViews(
{viewName: AuthorityOrganizationDetailTab.MEMBERS},
{viewName: AuthorityOrganizationDetailTab.DETAIL},
);
}

@Action(DeactivateUser)
onDeactivateUser(
ctx: StateContext<AuthorityOrganizationDetailPageState>,
Expand All @@ -275,13 +290,19 @@ export class AuthorityOrganizationDetailPageStateImpl {
this.toast.showSuccess(`User deactivated successfully`);
this.organizationUserRefreshed(ctx, Fetched.ready(data));
}),
finalize(() =>
this.globalStateUtils.updateNestedProperty(
finalize(() => {
ctx.dispatch(
new RefreshOrganization(() => {
this.redirectToMembersTab();
}),
);

return this.globalStateUtils.updateNestedProperty(
ctx,
'openedUserDetail.busy',
false,
),
),
);
}),
ignoreElements(),
);
}
Expand Down Expand Up @@ -310,13 +331,18 @@ export class AuthorityOrganizationDetailPageStateImpl {
this.toast.showSuccess(`User re-activated successfully`);
this.organizationUserRefreshed(ctx, Fetched.ready(data));
}),
finalize(() =>
this.globalStateUtils.updateNestedProperty(
finalize(() => {
ctx.dispatch(
new RefreshOrganization(() => {
this.redirectToMembersTab();
}),
);
return this.globalStateUtils.updateNestedProperty(
ctx,
'openedUserDetail.busy',
false,
),
),
);
}),
ignoreElements(),
);
}
Expand Down
Loading