Skip to content

Commit

Permalink
Merge pull request #704 from upb-uc4/feature/soft_deletion_ui
Browse files Browse the repository at this point in the history
Feature/soft deletion ui
  • Loading branch information
bastihav authored Nov 26, 2020
2 parents fff3abe + 212cce7 commit 088511c
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Feature
- added governmentId to user creation [#701](https://github.com/upb-uc4/ui-web/pull/701)
- add soft deletion of users [#702](https://github.com/upb-uc4/ui-web/pull/702)
- add soft deletion of users [#702](https://github.com/upb-uc4/ui-web/pull/702), [#704](https://github.com/upb-uc4/ui-web/pull/704)

## Refactoring
- Merge endpoints for user creation [#700](https://github.com/upb-uc4/ui-web/pull/700)
Expand Down
15 changes: 14 additions & 1 deletion src/components/account/list/AccountList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
type: String,
required: true,
},
showInactive: {
type: Boolean,
required: true,
},
},
setup(props: any) {
let busy = ref(false);
Expand All @@ -43,12 +47,21 @@
await getUsers();
});
watch(
() => props.showInactive,
() => {
getUsers();
}
);
async function getUsers() {
busy.value = true;
const userManagement: UserManagement = new UserManagement();
const genericResponseHandler = new GenericResponseHandler("users");
const response = await userManagement.getUsers();
const response = props.showInactive
? await userManagement.getUsers()
: await userManagement.getUsers(undefined, undefined, true);
const userLists = genericResponseHandler.handleResponse(response);
users.value = Object.values(userLists).flat();
busy.value = false;
Expand Down
11 changes: 11 additions & 0 deletions src/components/account/list/RoleFilter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@
{{ vrole }}
</button>
</div>
<div class="flex w-full ml-3 items-center justify-end">
<input id="toggleInactive" v-model="showInactiveAccounts" type="checkbox" class="m-2" />
<label class="text-sm text-gray-700">inactive</label>
</div>
</div>
</template>
<script lang="ts">
import { Role } from "@/entities/Role";
import { ref } from "vue";
import { useModelWrapper } from "@/use/helpers/ModelWrapper";
export default {
name: "RoleFilter",
Expand All @@ -26,6 +32,10 @@
type: String,
required: true,
},
showInactive: {
type: Boolean,
default: false,
},
},
emits: ["update:selectedRole"],
setup(props: any, { emit }: any) {
Expand All @@ -39,6 +49,7 @@
return {
roles,
select,
showInactiveAccounts: useModelWrapper(props, emit, "showInactive"),
};
},
};
Expand Down
22 changes: 16 additions & 6 deletions src/components/account/list/UserRow.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
<template>
<div
:id="'user_' + user.username"
class="px-6 py-4 whitespace-no-wrap border-gray-200 cursor-pointer hover:bg-gray-200"
:class="{ 'rounded-t-lg': isFirstRow, 'rounded-b-lg': isLastRow, 'border-b': !isLastRow }"
class="px-6 py-4 whitespace-no-wrap border-gray-200"
:class="{
'rounded-t-lg': isFirstRow,
'rounded-b-lg': isLastRow,
'border-b': !isLastRow,
'cursor-pointer hover:bg-gray-200': user.isActive,
}"
@click="editAccount(user.username)"
>
<div class="flex items-center">
<div class="w-full flex justify-between">
<div class="flex items-center">
<img class="hidden sm:block w-12 h-12 rounded-full" :src="profilePicture" alt="profile_picture" />
<div class="sm:ml-4">
<div class="text leading-5 font-medium text-blue-900 mb-1 truncate">{{ user.firstName }} {{ user.lastName }}</div>
<div v-if="user.isActive" class="mb-1 truncate">
<label class="text leading-5 font-medium text-blue-900 mr-2">{{ user.firstName }} {{ user.lastName }}</label>
</div>
<div v-if="!user.isActive" class="mb-1 truncate">
<label v-if="isLecturer" class="text leading-5 font-medium text-blue-900 mr-2">{{ user.firstName }} {{ user.lastName }}</label>
<label class="text-gray-600 italic">(inactive)</label>
</div>
<div class="hidden sm:flex text leading-5 text-gray-500 truncate">@{{ user.username }}</div>
<span
class="sm:hidden inline-block text-xs px-2 rounded-lg font-semibold leading-5 tracking-wide mb-1 w-16 text-center"
Expand Down Expand Up @@ -39,7 +50,7 @@
</span>
</div>

<div class="flex-col hidden sm:flex items-baseline" :class="[isStudent ? 'sm:flex' : 'sm:invisible']">
<div class="flex-col hidden sm:flex items-baseline" :class="[isStudent && user.isActive ? 'sm:flex' : 'sm:invisible']">
<div class="leading-5 text-blue-900 ml-1 mb-1">{{ student.matriculationId }}</div>
<div class="hidden sm:flex items-center leading-5 text-gray-500">
<span class="mr-2 fa-stack text-xs" style="font-size: 0.63em">
Expand Down Expand Up @@ -86,13 +97,12 @@
setup(props: any) {
let profilePicture = ref("");
function editAccount(username: string) {
router.push({ path: "/editAccount/" + username });
if (props.user.isActive) router.push({ path: "/editAccount/" + username });
}
const isStudent = props.user.role === Role.STUDENT;
const isLecturer = props.user.role === Role.LECTURER;
const isAdmin = props.user.role === Role.ADMIN;
const student = props.user as Student;
profilePicture.value = process.env.VUE_APP_API_BASE_URL + "/user-management/users/" + props.user.username + "/thumbnail?";
return { editAccount, isStudent, isLecturer, isAdmin, student, profilePicture };
Expand Down
7 changes: 5 additions & 2 deletions src/views/admin/AdminAccountList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
</div>
</div>

<role-filter v-model:selected-role="selectedRole" class="w-full my-4" />
<role-filter v-model:selected-role="selectedRole" v-model:show-inactive="showInactive" class="w-full my-4" />

<accountList :key="refreshKey" :selected-role="selectedRole" :filter="message" />
<accountList :key="refreshKey" :selected-role="selectedRole" :filter="message" :show-inactive="showInactive" />
<div class="flex justify-center mt-16">
<router-link to="/createAccount">
<button id="addAccount" title="Add a new User" class="px-4 btn btn-green-primary-500">New Account</button>
Expand Down Expand Up @@ -62,6 +62,8 @@
let selectedRole = ref("All" as Role);
let showInactive = ref(false);
function refresh() {
refreshKey.value = !refreshKey.value;
}
Expand All @@ -70,6 +72,7 @@
refresh,
message,
selectedRole,
showInactive,
};
},
};
Expand Down
3 changes: 2 additions & 1 deletion src/views/lecturer/PublicProfile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
<div class="flex items-center mt-12">
<img id="picture" class="w-32 h-32 mb-4 rounded-full object-cover mx-16 border-4 border-blue-700" :src="profilePicture" />
<div class="flex flex-col">
<label v-if="!lecturer.isActive" class="text-md italic text-red-400">(inactive)</label>
<h1 class="text-3xl font-medium text-gray-700">
{{ lecturer.firstName + " " + lecturer.lastName }}
<span class="text-xl"> (@{{ lecturer.username }}) </span>
</h1>
<h2 class="text-xl text-gray-700 text-blue-700 italic">{{ lecturer.role }}</h2>
</div>
</div>
<div class="flex flex-col mx-64">
<div v-if="lecturer.isActive" class="flex flex-col mx-64">
<div class="w-full mr-12 flex flex-col mb-4">
<div class="flex mb-2 align-baseline">
<label class="block text-gray-700 text-lg font-medium">Research Area</label>
Expand Down
1 change: 1 addition & 0 deletions src/views/student/PublicProfile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<div class="flex items-center my-12">
<img id="picture" class="w-32 h-32 mb-4 rounded-full object-cover mx-16 border-4 border-blue-700" :src="profilePicture" />
<div class="flex flex-col">
<label v-if="!student.isActive" class="text-md italic text-red-400">(inactive)</label>
<h1 class="text-3xl font-medium text-gray-700">
{{ student.firstName + " " + student.lastName }}
<span class="text-xl"> (@{{ student.username }}) </span>
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/helpers/UserHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export async function createUsers(users: UserWithAuth[]) {
export async function deleteUsers(users: Account[], adminAuth: Account) {
let userNames: string[] = [];
users.forEach((user) => userNames.push(user.username));
MachineUserAuthenticationManagement.setVueEnvVariable();
MachineUserAuthenticationManagement.setVueEnvVariable(Cypress.env("NODE_ENV"));
await MachineUserAuthenticationManagement._getRefreshToken(adminAuth);

const user_management = new UserManagement();
Expand Down
112 changes: 112 additions & 0 deletions tests/e2e/softAccountDeletion.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import Course from "@/api/api_models/course_management/Course";
import Lecturer from "@/api/api_models/user_management/Lecturer";
import { Account } from "@/entities/Account";
import { CourseType } from "@/entities/CourseType";
import { getMachineUserAuth, loginAsDefaultAdmin, loginAsDefaultStudent, logout } from "./helpers/AuthHelper";
import { createCourses, deleteCourses } from "./helpers/CourseHelper";
import { navigateToAccountList, navigateToCourseListStudent } from "./helpers/NavigationHelper";
import { createUsers, deleteUsers, getRandomizedGovernmentId } from "./helpers/UserHelper";
import { UserWithAuth } from "./helpers/UserWithAuth";

describe("Course Filtering", function () {
const random = Math.floor(Math.random() * 9999);

let course1: Course;

let adminAuth: Account;
let lecturer: Lecturer;
let lecturerGovId: string;
let lecturerAuth: Account;
let usersWithAuth: UserWithAuth[] = [];

before(function () {
cy.clearCookies();
Cypress.Cookies.defaults({
preserve: ["refresh", "login"],
});

cy.fixture("course.json")
.then((course) => {
course1 = { ...(course as Course) };
course1.courseName += random;
course1.courseType = CourseType.LECTURE;
})
.then(() => {
cy.fixture("logins/admin.json").then((admin) => {
adminAuth = admin;
});
})
.then(async () => {
await getMachineUserAuth(adminAuth);
})
.then(() => {
cy.fixture("lecturer.json").then((l) => {
(l as Lecturer).username += random;
lecturer = l as Lecturer;
course1.lecturerId = lecturer.username;
});
})
.then(() => {
cy.fixture("lecturerAuthUser.json").then((l) => {
(l as Account).username += random;
lecturerAuth = l as Account;
lecturerGovId = getRandomizedGovernmentId();
usersWithAuth.push({ governmentId: lecturerGovId, userInfo: lecturer, auth: lecturerAuth });
});
})
.then(async () => {
await createUsers(usersWithAuth);
await new Promise((r) => setTimeout(r, 3000));
await createCourses([course1]);
await deleteUsers([lecturerAuth], adminAuth);
})
.then(() => {
console.log("Setup finished");
});
});

after(() => {
deleteCourses([course1]);
logout();
});

it("Login as student and navigate to course list", () => {
loginAsDefaultStudent();
navigateToCourseListStudent();
});

it("Course of deleted lecturer is shown", () => {
cy.get("div").contains(course1.courseName).should("exist");
cy.get("div")
.contains(course1.courseName)
.parent()
.parent()
.find("a[id='showLecturer']")
.should("contain", `${lecturer.firstName} ${lecturer.lastName}`);
});

it("Public profile is shown correctly", () => {
cy.get("div").contains(course1.courseName).parent().parent().find("a[id='showLecturer']").click();
cy.url().should("contain", `/user/${lecturer.username}`);
cy.get("label").contains("(inactive)").should("exist");
cy.get("div").contains(`${lecturer.firstName} ${lecturer.lastName}`).should("exist");
cy.get("div").contains(`(@${lecturer.username})`).should("exist");
cy.get("div").contains("Research Area").should("not.exist");
cy.get("div").contains("Description").should("not.exist");
});

it("Logout and login as admin", () => {
logout();
loginAsDefaultAdmin();
});

it("Deleted lecturer is shown in account list after checking 'inactive'", () => {
navigateToAccountList();
cy.get("input[id='toggleInactive']").should("not.be.checked");
cy.get(`div[id='user_${lecturer.username}']`).should("not.exist");
cy.get("input[id='toggleInactive']").check();
cy.wait(1000);
cy.get(`div[id='user_${lecturer.username}']`).should("exist");
cy.get(`div[id='user_${lecturer.username}']`).should("contain", "(inactive)");
});
});

0 comments on commit 088511c

Please sign in to comment.