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: add an ability to mark contributors as hidden gf-346 #400

Merged
merged 36 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f419a30
feat: add new icons gf-346
kolibri753 Sep 19, 2024
ead4874
feat: add is_hidden column to contributors table gf-346
kolibri753 Sep 19, 2024
fd50a2d
feat: add is_hidden to the table and adjust backend gf-346
kolibri753 Sep 19, 2024
e1aa127
feat: exclude hidden contributors from project contributors page gf-346
kolibri753 Sep 19, 2024
29b1145
refactor: add isHiddenHeader component gf-346
kolibri753 Sep 19, 2024
2007813
refactor: rename visibleContributors into visibleProjectContributors …
kolibri753 Sep 19, 2024
e16be20
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 19, 2024
59ea2c7
feat: add checkbox to the edit modal gf-346
kolibri753 Sep 19, 2024
e0df714
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 19, 2024
9bc81dd
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 19, 2024
8d35b9a
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 20, 2024
09d059f
feat: filter logs on analytics page based on hidden contributors gf-346
kolibri753 Sep 20, 2024
999e8f0
feat: simplify isHidden header by changing to Do Not Track gf-346
kolibri753 Sep 22, 2024
cbae90c
feat: remove circle-question icon gf-346
kolibri753 Sep 22, 2024
06c1af3
refactor: update findAllByProjectId to handle filtering hidden contri…
kolibri753 Sep 22, 2024
85804d2
refactor: update findAll in activity-log service to handle hidden con…
kolibri753 Sep 22, 2024
13b4cb6
refactor: wrap return in curly brakets gf-346
kolibri753 Sep 22, 2024
2fb866c
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 22, 2024
c7ee254
refactor: group contributor-related fields under contributor gf-346
kolibri753 Sep 23, 2024
a3f55f9
refactor: add isHidden to findAll in repository gf-346
kolibri753 Sep 23, 2024
2dd50cc
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 23, 2024
495e46b
refactor: remove JSX.Element in cell for consistency gf-346
kolibri753 Sep 23, 2024
8738c5c
refactor: simplify isHidden contributors check gf-346
kolibri753 Sep 23, 2024
ce1581b
refactor: remove check and use hasHidden instead gf-346
kolibri753 Sep 23, 2024
0f6754b
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 23, 2024
8b9c75d
refactor: make hasHidden true by default and update findAllByProjectI…
kolibri753 Sep 24, 2024
e43e642
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 24, 2024
170e8c5
Merge branch 'main' into 346-feat-add-an-ability-to-mark-contributors…
kolibri753 Sep 24, 2024
f95fb50
refactor: use hiddenAt instead of isHidden gf-346
kolibri753 Sep 24, 2024
c27f689
fix: add useFormWatch to be able to see value from checkbox gf-346
kolibri753 Sep 24, 2024
f3f1474
fix: use dateTime instead of timestamp gf-346
kolibri753 Sep 24, 2024
7152a81
refactor: improve code readability and fix small typos gf-346
kolibri753 Sep 24, 2024
851eab1
refactor: update patch types by changing hiddenAt to isHidden gf-346
kolibri753 Sep 24, 2024
c851970
feat: add hidden_at column to contributors table in database schema g…
kolibri753 Sep 24, 2024
02651c2
refactor: simplify handleSubmit in handleFormSubmit gf-346
kolibri753 Sep 25, 2024
70a4679
fix: change isHidden ot hiddenAt in ContributorPatchResponseDto gf-346
kolibri753 Sep 25, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { type Knex } from "knex";

const TABLE_NAME = "contributors";

const ColumnName = {
IS_HIDDEN: "is_hidden",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's rename this column to hidden_at and record datetime

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so I'm changing it everywhere, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

} as const;

function up(knex: Knex): Promise<void> {
return knex.schema.alterTable(TABLE_NAME, (table) => {
table.boolean(ColumnName.IS_HIDDEN).defaultTo(false).notNullable();
});
}

function down(knex: Knex): Promise<void> {
return knex.schema.alterTable(TABLE_NAME, (table) => {
table.dropColumn(ColumnName.IS_HIDDEN);
});
}

export { down, up };
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ class ActivityLogRepository implements Repository {
}: ActivityLogQueryParameters): Promise<{ items: ActivityLogEntity[] }> {
const query = this.activityLogModel
.query()
.withGraphFetched("[gitEmail.contributor, project, createdByUser]")
.withGraphFetched("[project, createdByUser]")
.withGraphJoined("gitEmail.contributor")
.modifyGraph("gitEmail.contributor", (builder) => {
builder.select("id", "name");
builder.select("id", "name", "isHidden");
})
.where("gitEmail:contributor.isHidden", false)
.whereBetween("activity_logs.date", [startDate, endDate])
.orderBy("date");

Expand Down
11 changes: 8 additions & 3 deletions apps/backend/src/modules/activity-logs/activity-log.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,13 @@ class ActivityLogService implements Service {

public async findAll({
endDate,
hasHidden = false,
projectId,
startDate,
}: ActivityLogQueryParameters): Promise<ActivityLogGetAllAnalyticsResponseDto> {
const activityLogsEntities = await this.activityLogRepository.findAll({
endDate,
hasHidden,
projectId,
startDate,
});
Expand All @@ -148,7 +150,7 @@ class ActivityLogService implements Service {

const allContributors = await (projectId
? this.contributorService.findAllByProjectId(Number(projectId))
: this.contributorService.findAllWithoutPagination());
: this.contributorService.findAllWithoutPagination({ hasHidden }));

const dateRange = getDateRange(startDate, endDate);

Expand Down Expand Up @@ -184,8 +186,11 @@ class ActivityLogService implements Service {

return {
commitsNumber: commitsArray,
contributorId: contributorId ?? "",
contributorName: contributorName ?? "",
contributor: {
id: contributorId ?? "",
isHidden: false,
name: contributorName ?? "",
},
};
}),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,10 @@ class ContributorController extends BaseController {
}

return {
payload: await this.contributorService.findAll(options.query),
payload: await this.contributorService.findAll({
...options.query,
hasHidden: true,
}),
status: HTTPCode.OK,
};
}
Expand Down
17 changes: 15 additions & 2 deletions apps/backend/src/modules/contributors/contributor.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,53 @@ import { type ContributorGetAllItemResponseDto } from "./libs/types/types.js";
class ContributorEntity implements Entity {
private gitEmails: { email: string; id: number }[];
private id: null | number;
private isHidden: boolean;
private lastActivityDate: null | string;
private name: string;
private projects: { id: number; name: string }[];

private constructor({
gitEmails,
id,
isHidden,
lastActivityDate,
name,
projects,
}: {
gitEmails: { email: string; id: number }[];
id: null | number;
isHidden: boolean;
lastActivityDate: null | string;
name: string;
projects: { id: number; name: string }[];
}) {
this.gitEmails = gitEmails;
this.id = id;
this.name = name;
this.isHidden = isHidden;
this.lastActivityDate = lastActivityDate;
this.gitEmails = gitEmails;
this.name = name;
this.projects = projects;
}

public static initialize({
gitEmails,
id,
isHidden,
lastActivityDate,
name,
projects,
}: {
gitEmails: { email: string; id: number }[];
id: number;
isHidden: boolean;
lastActivityDate: null | string;
name: string;
projects: { id: number; name: string }[];
}): ContributorEntity {
return new ContributorEntity({
gitEmails,
id,
isHidden,
lastActivityDate,
name,
projects,
Expand All @@ -53,16 +60,19 @@ class ContributorEntity implements Entity {

public static initializeNew({
gitEmails = [],
isHidden = false,
name,
projects = [],
}: {
gitEmails?: { email: string; id: number }[];
isHidden?: boolean;
name: string;
projects?: { id: number; name: string }[];
}): ContributorEntity {
return new ContributorEntity({
gitEmails,
id: null,
isHidden,
lastActivityDate: null,
name,
projects,
Expand All @@ -71,12 +81,14 @@ class ContributorEntity implements Entity {

public toNewObject(): {
gitEmails: { email: string; id: number }[];
isHidden: boolean;
lastActivityDate: null | string;
name: string;
projects: { id: number; name: string }[];
} {
return {
gitEmails: this.gitEmails,
isHidden: this.isHidden,
lastActivityDate: this.lastActivityDate,
name: this.name,
projects: this.projects,
Expand All @@ -87,6 +99,7 @@ class ContributorEntity implements Entity {
return {
gitEmails: this.gitEmails,
id: this.id as number,
isHidden: this.isHidden,
lastActivityDate: this.lastActivityDate,
name: this.name,
projects: this.projects,
Expand Down
5 changes: 5 additions & 0 deletions apps/backend/src/modules/contributors/contributor.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import { type ProjectModel } from "../projects/project.model.js";

class ContributorModel extends AbstractModel {
public gitEmails!: GitEmailModel[];

public isHidden!: boolean;

public lastActivityDate!: null | string;

public name!: string;

public projects!: ProjectModel[];

public static override get relationMappings(): RelationMappings {
Expand Down
31 changes: 26 additions & 5 deletions apps/backend/src/modules/contributors/contributor.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ class ContributorRepository implements Repository {
}

public async findAll({
hasHidden = false,
page,
pageSize,
}: PaginationQueryParameters): Promise<
}: { hasHidden?: boolean } & PaginationQueryParameters): Promise<
Vitaliistf marked this conversation as resolved.
Show resolved Hide resolved
PaginationResponseDto<ContributorEntity>
> {
const { results, total } = await this.contributorModel
const query = this.contributorModel
.query()
.orderBy("createdAt", SortType.DESCENDING)
.page(page, pageSize)
Expand All @@ -77,6 +78,12 @@ class ContributorRepository implements Repository {
.groupBy("contributors.id")
.withGraphFetched("gitEmails");

if (!hasHidden) {
query.where("contributors.isHidden", false);
}

const { results, total } = await query;

return {
items: results.map((contributor) => {
return ContributorEntity.initialize(contributor);
Expand Down Expand Up @@ -105,6 +112,7 @@ class ContributorRepository implements Repository {
.leftJoin("activity_logs", "git_emails.id", "activity_logs.git_email_id")
.leftJoin("projects", "activity_logs.project_id", "projects.id")
.where("projects.id", projectId)
.andWhere("contributors.isHidden", false)
.groupBy("contributors.id")
.withGraphFetched("gitEmails");

Expand All @@ -115,10 +123,14 @@ class ContributorRepository implements Repository {
};
}

public async findAllWithoutPagination(): Promise<{
public async findAllWithoutPagination({
hasHidden = true,
}: {
hasHidden?: boolean;
}): Promise<{
items: ContributorEntity[];
}> {
const results = await this.contributorModel
const query = this.contributorModel
.query()
.select("contributors.*")
.select(
Expand All @@ -132,6 +144,12 @@ class ContributorRepository implements Repository {
.groupBy("contributors.id")
.withGraphFetched("gitEmails");

if (!hasHidden) {
query.where("contributors.isHidden", false);
}

const results = await query;

return {
items: results.map((contributor) => {
return ContributorEntity.initialize(contributor);
Expand Down Expand Up @@ -210,7 +228,10 @@ class ContributorRepository implements Repository {
): Promise<ContributorEntity | null> {
const contributor = await this.contributorModel
.query()
.patchAndFetchById(contributorId, { name: data.name });
.patchAndFetchById(contributorId, {
isHidden: data.isHidden,
name: data.name,
});

return ContributorEntity.initialize(contributor);
}
Expand Down
23 changes: 16 additions & 7 deletions apps/backend/src/modules/contributors/contributor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,17 @@ class ContributorService implements Service {
return item.toObject();
}

public async findAll(
parameters: PaginationQueryParameters,
): Promise<ContributorGetAllResponseDto> {
public async findAll({
hasHidden = true,
page,
pageSize,
}: {
hasHidden?: boolean;
} & PaginationQueryParameters): Promise<ContributorGetAllResponseDto> {
const contributors = await this.contributorRepository.findAll({
page: parameters.page - PAGE_INDEX_OFFSET,
pageSize: parameters.pageSize,
hasHidden,
page: page - PAGE_INDEX_OFFSET,
pageSize,
});

return {
Expand Down Expand Up @@ -106,9 +111,13 @@ class ContributorService implements Service {
};
}

public async findAllWithoutPagination(): Promise<ContributorGetAllResponseDto> {
public async findAllWithoutPagination({
hasHidden = true,
}: {
hasHidden?: boolean;
}): Promise<ContributorGetAllResponseDto> {
const contributors =
await this.contributorRepository.findAllWithoutPagination();
await this.contributorRepository.findAllWithoutPagination({ hasHidden });

return {
items: contributors.items.map((item) => {
Expand Down
3 changes: 3 additions & 0 deletions apps/frontend/src/assets/images/icons/check.svg
GvoFor marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/frontend/src/libs/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import styles from "./styles.module.css";
type Properties<T extends FieldValues> = {
control: Control<T, null>;
errors: FieldErrors<T>;
id?: string;
name: FieldPath<T>;
};

const Checkbox = <T extends FieldValues>({
control,
errors,
id,
name,
}: Properties<T>): JSX.Element => {
const { field } = useFormController({ control, name });
Expand All @@ -30,6 +32,7 @@ const Checkbox = <T extends FieldValues>({
<input
className={styles["checkbox"]}
defaultChecked={field.value}
id={id}
name={name}
onChange={field.onChange}
type="checkbox"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type FC } from "react";
import Access from "~/assets/images/icons/access.svg?react";
import Analytics from "~/assets/images/icons/analytics.svg?react";
import Calendar from "~/assets/images/icons/calendar.svg?react";
import Check from "~/assets/images/icons/check.svg?react";
import Clipboard from "~/assets/images/icons/clipboard.svg?react";
import Contributors from "~/assets/images/icons/contributors.svg?react";
import Cross from "~/assets/images/icons/cross.svg?react";
Expand All @@ -27,6 +28,7 @@ const iconNameToSvg: Record<IconName, FC<React.SVGProps<SVGSVGElement>>> = {
access: Access,
analytics: Analytics,
calendar: Calendar,
check: Check,
clipboard: Clipboard,
contributors: Contributors,
cross: Cross,
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/src/libs/types/icon-name.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ type IconName =
| "access"
| "analytics"
| "calendar"
| "check"
| "clipboard"
| "contributors"
| "cross"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const getAnalyticsRows = (
): AnalyticsRow[] => {
return activityLogs.map((log) => ({
commitsNumber: log.commitsNumber,
contributorId: log.contributorId,
contributorName: log.contributorName,
contributorId: log.contributor.id,
contributorName: log.contributor.name,
}));
};

Expand Down
Loading