Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7fffcde4e6 | |||
| 391ab66229 | |||
| 3583079abb | |||
| 0d7211861e | |||
| 75c727e020 | |||
| ef5ec10fdd |
@@ -1 +1 @@
|
|||||||
@tnsu:registry=http://git.tnsu.kz/api/packages/timur.gorodetskiy/npm/
|
@tnsu:registry=http://git.tnsu.kz/api/packages/Tansu/npm/
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ services:
|
|||||||
image: nexus.tnsu.kz:8082/hr-appeals-web:${IMAGE_TAG:-latest}
|
image: nexus.tnsu.kz:8082/hr-appeals-web:${IMAGE_TAG:-latest}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "127.0.0.1:8082:80"
|
||||||
depends_on:
|
depends_on:
|
||||||
- hr-appeals-auth
|
- hr-appeals-auth
|
||||||
|
|
||||||
|
|||||||
Generated
+4
-4
@@ -9,7 +9,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluentui/react": "^8.106.4",
|
"@fluentui/react": "^8.106.4",
|
||||||
"@tnsu/ui-kit": "^0.8.0",
|
"@tnsu/ui-kit": "^0.14.0",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"tslib": "^2.3.1"
|
"tslib": "^2.3.1"
|
||||||
@@ -1701,9 +1701,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tnsu/ui-kit": {
|
"node_modules/@tnsu/ui-kit": {
|
||||||
"version": "0.8.0",
|
"version": "0.14.0",
|
||||||
"resolved": "http://git.tnsu.kz/api/packages/timur.gorodetskiy/npm/%40tnsu%2Fui-kit/-/0.8.0/ui-kit-0.8.0.tgz",
|
"resolved": "http://git.tnsu.kz/api/packages/Tansu/npm/%40tnsu%2Fui-kit/-/0.14.0/ui-kit-0.14.0.tgz",
|
||||||
"integrity": "sha512-PdAxr09JVkbK8XmxSM5Lgfz1Iq56RGFsoz4bI1YBd8quPzM3g/r4gRqqjbhCxyemzfK1d4w4WJD0ZBSs8jJbdA==",
|
"integrity": "sha512-Vun9AUM9jL8rttbsbKo5Yh6TUz1srkNqxiO6mmzebrSo1JOASNJqNjJPMTS+8Jt3MTrJPklvh0TbeqGQzw7qxQ==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@fluentui/react": "^8.106.4",
|
"@fluentui/react": "^8.106.4",
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluentui/react": "^8.106.4",
|
"@fluentui/react": "^8.106.4",
|
||||||
"@tnsu/ui-kit": "^0.8.0",
|
"@tnsu/ui-kit": "^0.14.0",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"tslib": "^2.3.1"
|
"tslib": "^2.3.1"
|
||||||
|
|||||||
+15
-1
@@ -11,6 +11,19 @@ export interface ICompany {
|
|||||||
Name: string;
|
Name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Компании из справочника, которые по сути не действуют и не должны попадать
|
||||||
|
* в форму (просьба HR, 2026-09-09): СЛМ (CL MANAGEMENT), Selin Invest,
|
||||||
|
* ОСН Беркут, ТехЛаб, Seline Holding Ltd.
|
||||||
|
*/
|
||||||
|
const EXCLUDED_COMPANY_IDS = new Set<string>([
|
||||||
|
'9de064a4-44c8-88ef-11ec-831c058b1141', // ТОО CL MANAGEMENT (СЛМ)
|
||||||
|
'15009595-005d-00fa-11ef-11309f5e395d', // ТОО Selin Invest
|
||||||
|
'8028beac-ac23-8fd8-11f0-5351706e5996', // ТОО ОСН Беркут
|
||||||
|
'15009595-005d-00fa-11ef-1131801d9f3e', // ТОО ТехЛаб
|
||||||
|
'03f4deac-f543-e8cf-11f1-84f51483f59e' // Частная компания Seline Holding Ltd
|
||||||
|
]);
|
||||||
|
|
||||||
let cached: { companies: ICompany[]; expiresAt: number } | null = null;
|
let cached: { companies: ICompany[]; expiresAt: number } | null = null;
|
||||||
|
|
||||||
export async function getCompanies(): Promise<ICompany[]> {
|
export async function getCompanies(): Promise<ICompany[]> {
|
||||||
@@ -29,7 +42,8 @@ export async function getCompanies(): Promise<ICompany[]> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const companies = (await response.json()) as ICompany[];
|
const allCompanies = (await response.json()) as ICompany[];
|
||||||
|
const companies = allCompanies.filter((company) => !EXCLUDED_COMPANY_IDS.has(company.Id));
|
||||||
cached = { companies, expiresAt: Date.now() + CACHE_TTL_MS };
|
cached = { companies, expiresAt: Date.now() + CACHE_TTL_MS };
|
||||||
return companies;
|
return companies;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,26 @@ export interface IFeedbackSubmission {
|
|||||||
suggestion: string;
|
suggestion: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5 рабочих дней от текущей даты, выходные (сб/вс) не считаются днём срока —
|
||||||
|
// используется как крайний срок обработки обращения (AppealDueDate).
|
||||||
|
function addBusinessDays(from: Date, days: number): Date {
|
||||||
|
const result = new Date(from);
|
||||||
|
let remaining = days;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
result.setDate(result.getDate() + 1);
|
||||||
|
const dayOfWeek = result.getDay(); // 0 = воскресенье, 6 = суббота
|
||||||
|
if (dayOfWeek !== 0 && dayOfWeek !== 6) {
|
||||||
|
remaining -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Имена полей — internal name столбцов списка SharePoint (Company/Name/Position/
|
// Имена полей — internal name столбцов списка SharePoint (Company/Name/Position/
|
||||||
// Type/IssueDescription/SuggestionText/WantsFeedback), не отображаемые названия.
|
// Type/IssueDescription/SuggestionText/WantsFeedback/AppealDueDate), не
|
||||||
|
// отображаемые названия.
|
||||||
async function buildFields(data: IFeedbackSubmission): Promise<Record<string, unknown>> {
|
async function buildFields(data: IFeedbackSubmission): Promise<Record<string, unknown>> {
|
||||||
const typeLabel = data.kind === 'other' ? data.kindOther : KIND_LABELS[data.kind];
|
const typeLabel = data.kind === 'other' ? data.kindOther : KIND_LABELS[data.kind];
|
||||||
const name = data.isAnonymous ? '' : data.fullName;
|
const name = data.isAnonymous ? '' : data.fullName;
|
||||||
@@ -38,7 +56,8 @@ async function buildFields(data: IFeedbackSubmission): Promise<Record<string, un
|
|||||||
Type: typeLabel,
|
Type: typeLabel,
|
||||||
IssueDescription: data.situation,
|
IssueDescription: data.situation,
|
||||||
SuggestionText: data.suggestion,
|
SuggestionText: data.suggestion,
|
||||||
WantsFeedback: data.wantsFeedback
|
WantsFeedback: data.wantsFeedback,
|
||||||
|
AppealDueDate: addBusinessDays(new Date(), 5).toISOString()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Состав полей зависит от вида обращения и анонимности, поэтому часть строк
|
// Состав полей зависит от вида обращения и анонимности, поэтому часть строк
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ export const FeedbackForm: React.FC = () => {
|
|||||||
// (App.tsx) — второй здесь был бы дублем. Пустая строка убирает текст,
|
// (App.tsx) — второй здесь был бы дублем. Пустая строка убирает текст,
|
||||||
// а гэпа не оставляет: у ui-kit пустой title-блок не создаёт строки.
|
// а гэпа не оставляет: у ui-kit пустой title-блок не создаёт строки.
|
||||||
<FormCard title="">
|
<FormCard title="">
|
||||||
|
<div className={styles.notice}>
|
||||||
|
<Alert variant="ok">{TEXTS.helpText}</Alert>
|
||||||
|
</div>
|
||||||
|
|
||||||
{formError ? (
|
{formError ? (
|
||||||
<div className={styles.notice}>
|
<div className={styles.notice}>
|
||||||
<Alert variant="err">{formError}</Alert>
|
<Alert variant="err">{formError}</Alert>
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ export const TEXTS = {
|
|||||||
pageTitle: 'Обращение',
|
pageTitle: 'Обращение',
|
||||||
pageSubtitle: 'Данное обращение будет направлено в HR департамент',
|
pageSubtitle: 'Данное обращение будет направлено в HR департамент',
|
||||||
|
|
||||||
|
helpText:
|
||||||
|
'Обращение в HR — единый канал для вопросов, предложений и обратной связи ' +
|
||||||
|
'сотрудников по трудовым отношениям, рабочим процессам, условиям труда, ' +
|
||||||
|
'взаимодействию, адаптации, развитию и другим вопросам, связанным с работой в компании.',
|
||||||
|
|
||||||
// Две сноски с разным числом звёздочек — как в исходной форме, чтобы читалось
|
// Две сноски с разным числом звёздочек — как в исходной форме, чтобы читалось
|
||||||
// как два отдельных примечания, а не слитный абзац. Field рендерит их построчно.
|
// как два отдельных примечания, а не слитный абзац. Field рендерит их построчно.
|
||||||
anonymousHint:
|
anonymousHint:
|
||||||
|
|||||||
Reference in New Issue
Block a user