Skip to content
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
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/** @format */

import { DestroyRef, ElementRef, inject, Injectable } from "@angular/core";
import { concatMap, filter, map, tap } from "rxjs";
import { DestroyRef, inject, Injectable } from "@angular/core";
import { filter, map, switchMap, tap } from "rxjs";
import { ProfileNews } from "@domain/profile/profile-news.model";
import { ActivatedRoute } from "@angular/router";
import { ExpandService } from "../../../expand/expand.service";
import { calculateProfileProgress } from "@utils/calculateProgress";
import { ProfileDetailUIInfoService } from "./ui/profile-detail-ui-info.service";
import { NewsInfoService } from "../../../news/news-info.service";
Expand All @@ -23,7 +22,6 @@ export class ProfileDetailInfoService {
private readonly route = inject(ActivatedRoute);
private readonly destroyRef = inject(DestroyRef);

private readonly expandService = inject(ExpandService);
private readonly profileDetailUIInfoService = inject(ProfileDetailUIInfoService);
private readonly profileInfoService = inject(ProfileInfoService);
private readonly newsInfoService = inject(NewsInfoService);
Expand Down Expand Up @@ -69,16 +67,10 @@ export class ProfileDetailInfoService {
},
});

this.initializationProfileVields();
this.initializationProfileFields();
this.initializationProfileNews();
}

initCheckDescription(descEl?: ElementRef): void {
setTimeout(() => {
this.expandService.checkExpandable("description", !!this.profile()?.personal.aboutMe, descEl);
}, 150);
}

onAddNews(news: { text: string; files: string[] }) {
return this.addProfileNewsUseCase.execute(this.route.snapshot.params["id"], news).pipe(
tap(result => {
Expand Down Expand Up @@ -136,16 +128,16 @@ export class ProfileDetailInfoService {
.subscribe();
}

private initializationProfileVields(): void {
private initializationProfileFields(): void {
this.profileDetailUIInfoService.applySetLoggedUserId("logged", this.profile()!.id);
this.profileDetailUIInfoService.applyProfileEmpty();
}

private initializationProfileNews(descEl?: ElementRef): void {
private initializationProfileNews(): void {
this.route.params
.pipe(
map(r => r["id"]),
concatMap(userId => this.fetchProfileNewsUseCase.execute(Number(userId))),
tap(() => this.newsInfoService.applySetNews({ results: [], count: 0 })),
switchMap(userId => this.fetchProfileNewsUseCase.execute(Number(userId))),
takeUntilDestroyed(this.destroyRef),
)
.subscribe(result => {
Expand All @@ -157,8 +149,6 @@ export class ProfileDetailInfoService {
this.setupNewsObserver();
}, 100);
});

this.initCheckDescription(descEl);
}

private setupNewsObserver(): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @format */

import { Injectable, signal } from "@angular/core";
import { computed, Injectable, signal } from "@angular/core";
import { DirectionItem, directionItemBuilder } from "@utils/directionItemBuilder";
import { User } from "@domain/auth/user.model";

Expand All @@ -12,7 +12,18 @@ export class ProfileDetailUIInfoService {
readonly loggedUserId = signal<number>(0);
readonly profileId = signal<number>(0); // ID текущего пользователя.

readonly isProfileEmpty = signal<boolean | undefined>(undefined);
readonly isProfileEmpty = computed<boolean | undefined>(() => {
const user = this.user();
if (!user) return undefined;

return !(
user.firstName &&
user.lastName &&
user.email &&
user.personal.avatar &&
user.personal.birthday
);
});
readonly isProfileFill = signal<boolean>(false);

readonly directions = signal<DirectionItem[]>([]);
Expand All @@ -35,18 +46,6 @@ export class ProfileDetailUIInfoService {
}
}

applyProfileEmpty(): void {
this.isProfileEmpty.set(
!(
this.user()?.firstName &&
this.user()?.lastName &&
this.user()?.email &&
this.user()?.personal.avatar &&
this.user()?.personal.birthday
),
);
}

applySetLoggedUserId(type: "logged" | "profile", profileId: number): void {
type === "logged" ? this.loggedUserId.set(profileId) : this.profileId.set(profileId);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/** @format */

import { Project } from "@domain/project/project.model";
import { ProjectsDetailUIInfoService } from "./projects-detail-ui.service";

describe("ProjectsDetailUIInfoService", () => {
it("показывает полное название блока актуальности", () => {
const service = new ProjectsDetailUIInfoService();
service.applySetProject(Project.default());

service.applyDirectionItems();

expect(service.directions()[2].direction).toBe("актуальность");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class ProjectsDetailUIInfoService {
this.directions.set(
directionItemBuilder(
5,
["проблема", "целевая аудитория", "актуаль-сть", "цели", "партнеры"],
["проблема", "целевая аудитория", "актуальность", "цели", "партнеры"],
["key", "smile", "graph", "goal", "team"],
[
this.project()!.problem,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe("VacancyDetailInfoService", () => {
let downloadCvUseCase: any;
let fileService: any;
let snackbar: any;
let queryParams$: Subject<Record<string, unknown>>;

beforeEach(() => {
sendUseCase = { execute: vi.fn() };
Expand All @@ -38,6 +39,7 @@ describe("VacancyDetailInfoService", () => {
downloadCvUseCase = { execute: vi.fn() };
fileService = { uploadFile: vi.fn() };
snackbar = { success: vi.fn(), error: vi.fn() };
queryParams$ = new Subject<Record<string, unknown>>();

TestBed.configureTestingModule({
providers: [
Expand All @@ -48,7 +50,7 @@ describe("VacancyDetailInfoService", () => {
provide: ActivatedRoute,
useValue: {
data: of({}),
queryParams: of({}),
queryParams: queryParams$,
snapshot: { paramMap: { get: () => "10" } },
},
},
Expand Down Expand Up @@ -110,6 +112,28 @@ describe("VacancyDetailInfoService", () => {
expect(ui.openModal()).toBe(false);
});

it("opens manager responses from a guarded query parameter", () => {
ui.vacancy.update(vacancy =>
vacancy ? Object.assign(new Vacancy(), vacancy, { canManageResponses: true }) : vacancy,
);
getResponsesUseCase.execute.mockReturnValue(of(ok([])));
service.initializeDetailInfoQueryParams();

queryParams$.next({ manageResponses: "true" });

expect(ui.responsesModal()).toBe(true);
expect(getResponsesUseCase.execute).toHaveBeenCalledExactlyOnceWith(10);
});

it("does not open or load manager responses without backend permission", () => {
service.initializeDetailInfoQueryParams();

queryParams$.next({ manageResponses: "true" });

expect(ui.responsesModal()).toBe(false);
expect(getResponsesUseCase.execute).not.toHaveBeenCalled();
});

it.each([
[["Вы уже откликнулись на эту вакансию."], "Вы уже откликнулись на эту вакансию"],
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export class VacancyDetailInfoService {
initializeDetailInfoQueryParams(): void {
this.route.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
next: r => {
if (r["manageResponses"] === true || r["manageResponses"] === "true") {
this.openVacancyResponses();
return;
}

this.vacancyDetailUIInfoService.applyNoResponseOpenModal(r);
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ <h4 class="text-heading-4">библиотека</h4>
[title]="skillGroup.name"
[options]="skillGroup.skills"
[selected]="stageForm.getRawValue().skills"
[disabled]="isSkillGroupDisabled(skillGroup.name)"
[hasOpenGroups]="hasOpenSkillsGroups()"
[isOpen]="openSkillGroup() === skillGroup.name"
(groupToggled)="onSkillGroupToggled($event, skillGroup.name)"
(optionToggled)="onOptionToggled($event)"
></app-skills-group>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
}

&__skills-groups {
position: relative;
height: 100%;
overflow: auto;
scrollbar-width: thin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,7 @@ <h3 class="text-body-12 about__title">обо мне</h3>
</div>

<div class="text-body-10 about__text">
<p #descEl [innerHTML]="about | parseLinks | parseBreaks"></p>
@if (descriptionExpandable()) {
<div
class="read-more text-body-10"
(click)="onExpandDescription(descEl, 'expanded', readFullDescription())"
>
{{ readFullDescription() ? "скрыть" : "подробнее" }}
</div>
}
<p [innerHTML]="about | parseLinks | parseBreaks"></p>
</div>
</div>
}
Expand All @@ -37,7 +29,7 @@ <h3 class="text-body-12 about__title">обо мне</h3>
}
@if (isProfileEmpty()) {
@if (loggedUserId() === user()!.id) {
<div class="profile__empty">
<div class="profile__empty" data-testid="empty-profile-state">
<i appIcon icon="empty-chat" appSquare="44"></i>
<p class="profile__empty--text text-body-12">
заполните профиль и начните пользоваться PROCOLLAB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
flex-direction: column;
gap: 24px;
align-items: center;
justify-content: center;
min-height: min(480px, calc(100vh - 240px));
padding: 24px;
text-align: center;

&--text {
color: var(--grey-for-text);
Expand Down Expand Up @@ -64,21 +68,11 @@
margin-bottom: 8px;
color: var(--accent);
}
/* stylelint-disable value-no-vendor-prefix */

&__text {
p {
display: -webkit-box;
overflow: hidden;
color: var(--black);
text-overflow: ellipsis;
word-break: break-word;
transition: all 0.7s ease-in-out;
-webkit-box-orient: vertical;
-webkit-line-clamp: 5;

&.expanded {
-webkit-line-clamp: unset;
}
}

::ng-deep a {
Expand All @@ -94,8 +88,6 @@
}
}

/* stylelint-enable value-no-vendor-prefix */

&__read-full {
margin-top: 2px;
color: var(--accent);
Expand All @@ -114,14 +106,3 @@
margin-top: 20px;
}
}

.read-more {
margin-top: 12px;
color: var(--accent);
cursor: pointer;
transition: color 0.2s;

&:hover {
color: var(--accent-dark);
}
}
Loading