Убрал упоминания LogStorm/LogShtorm из frontend-слоя EUSRR

This commit is contained in:
lizerk 2026-04-22 14:43:57 +03:00
parent 1bf3fac8b5
commit 0ec0e1c75b
5 changed files with 57 additions and 61 deletions

View File

@ -23,7 +23,7 @@ import type {
MonthlyAttendanceMatrixCell,
MonthlyAttendanceMatrixEmployee,
MonthlyAttendanceMatrixRow,
LogStormSchedulePayload,
AttendanceSchedulePayload,
} from "@/lib/api/attendance";
import type { User } from "@/types/api";
@ -339,7 +339,7 @@ export default function AttendancePage() {
}
}
function getSchedulePayload(): LogStormSchedulePayload | undefined {
function getSchedulePayload(): AttendanceSchedulePayload | undefined {
if (!useManualSchedule) return undefined;
return {
start_time: scheduleStart,
@ -365,7 +365,7 @@ export default function AttendancePage() {
return true;
}
async function loadStatistics(options?: { refreshFromLogStorm?: boolean }) {
async function loadStatistics(options?: { refreshFromAnalyzer?: boolean }) {
setError(null);
setMatrices([]);
setSelectedCell(null);
@ -378,8 +378,8 @@ export default function AttendancePage() {
const employeeIds = selectedEmployees.map((employee) => employee.id).join(",");
for (const employee of selectedEmployees) {
if (options?.refreshFromLogStorm) {
await apiClient.analyzeLogStormAttendance({
if (options?.refreshFromAnalyzer) {
await apiClient.analyzeAttendance({
employee_id: employee.id,
period_start: periodStart,
period_end: periodEnd,
@ -424,7 +424,7 @@ export default function AttendancePage() {
Посещаемость
</h1>
<p className="app-text-muted mt-1 text-xs sm:text-sm">
Выбор сотрудников и периода для статистики LogStorm
Выбор сотрудников и периода для статистики посещаемости
</p>
</div>
<ChevronDown
@ -677,7 +677,7 @@ export default function AttendancePage() {
</button>
<button
type="button"
onClick={() => void loadStatistics({ refreshFromLogStorm: true })}
onClick={() => void loadStatistics({ refreshFromAnalyzer: true })}
disabled={loadingStats || loadingEmployees}
className="app-action-primary inline-flex min-h-10 items-center justify-center gap-2 rounded-lg px-4 py-2 text-sm font-semibold disabled:cursor-not-allowed disabled:opacity-60"
>

View File

@ -173,12 +173,6 @@ export default function ProfilePage() {
<ProfileInfoCard items={infoItems} />
<ProfileWorkScheduleCard
canEdit={Boolean(user.auth?.is_staff || user.auth?.is_superuser)}
currentAction={currentAction}
employeeId={user.id}
/>
{user.departments?.length ? (
<ProfileDepartmentsCard departments={user.departments} />
) : null}
@ -195,6 +189,12 @@ export default function ProfilePage() {
expandedCommentLength={240}
/>
<ProfileWorkScheduleCard
canEdit={Boolean(user.auth?.is_staff || user.auth?.is_superuser)}
currentAction={currentAction}
employeeId={user.id}
/>
<EmployeeAttendanceCard employeeActions={user.actions} employeeId={user.id} />
</div>
</AppShell>

View File

@ -509,12 +509,6 @@ export default function UserDetailPage() {
<ProfileInfoCard items={infoItems} />
<ProfileWorkScheduleCard
canEdit={Boolean(currentUser?.auth?.is_staff || currentUser?.auth?.is_superuser)}
currentAction={latestAction}
employeeId={person.id}
/>
{person.departments?.length ? (
<ProfileDepartmentsCard departments={person.departments} />
) : null}
@ -532,6 +526,12 @@ export default function UserDetailPage() {
expandedCommentLength={240}
/>
<ProfileWorkScheduleCard
canEdit={Boolean(currentUser?.auth?.is_staff || currentUser?.auth?.is_superuser)}
currentAction={latestAction}
employeeId={person.id}
/>
<EmployeeAttendanceCard employeeActions={person.actions} employeeId={person.id} />
</>
) : null}

View File

@ -3,7 +3,6 @@
import { useEffect, useMemo, useState, type FormEvent } from "react";
import {
AlertTriangle,
CalendarCheck,
ChevronDown,
Clock,
Edit3,
@ -21,9 +20,9 @@ import { apiClient } from "@/lib/api";
import { displayUserName, formatDate } from "@/lib/shared";
import type {
AttendanceRecordComment,
LogStormAttendanceRecord,
LogStormAttendanceRecordUpdatePayload,
LogStormAttendanceResponse,
AttendanceAnalysisResponse,
AttendanceRecord,
AttendanceRecordUpdatePayload,
} from "@/lib/api/attendance";
import type { EmployeeAction } from "@/types/api";
@ -160,7 +159,7 @@ function formatAttendanceIssueLabel(label: string) {
return attendanceIssueLabelMap[normalized] || label;
}
function hasWorked(record: LogStormAttendanceRecord) {
function hasWorked(record: AttendanceRecord) {
const hours = Number(record.work_hours || 0);
return Boolean(record.arrival_time || record.departure_time || hours > 0);
}
@ -176,7 +175,7 @@ function getDateEnd(value: unknown) {
function getPersonnelDayMeta(
actions: EmployeeAction[] | null | undefined,
dateValue: unknown,
record?: LogStormAttendanceRecord,
record?: AttendanceRecord,
): PersonnelDayMeta | null {
if (record?.personnel_status && record.personnel_status !== "normal") {
return {
@ -255,7 +254,7 @@ function getPersonnelDayMeta(
return null;
}
function issueLabels(record: LogStormAttendanceRecord, personnelMeta?: PersonnelDayMeta | null) {
function issueLabels(record: AttendanceRecord, personnelMeta?: PersonnelDayMeta | null) {
const labels = [
...(record.statuses || []),
...(record.employee_issues || []),
@ -281,7 +280,7 @@ function issueLabels(record: LogStormAttendanceRecord, personnelMeta?: Personnel
return Array.from(new Set(result));
}
function getRecordTone(record: LogStormAttendanceRecord, personnelMeta?: PersonnelDayMeta | null) {
function getRecordTone(record: AttendanceRecord, personnelMeta?: PersonnelDayMeta | null) {
const nonWorking = personnelMeta?.nonWorking || record.effective_is_workday === false || record.is_workday === false;
if (nonWorking && hasWorked(record)) {
@ -317,7 +316,7 @@ function getRecordTone(record: LogStormAttendanceRecord, personnelMeta?: Personn
};
}
function getWorkdayMeta(record: LogStormAttendanceRecord, personnelMeta?: PersonnelDayMeta | null) {
function getWorkdayMeta(record: AttendanceRecord, personnelMeta?: PersonnelDayMeta | null) {
if (personnelMeta?.nonWorking) {
return {
className: personnelMeta.className,
@ -357,7 +356,7 @@ function getErrorMessage(error: unknown, fallback: string) {
return String((error as Error)?.message || fallback);
}
function getRecordId(record: LogStormAttendanceRecord) {
function getRecordId(record: AttendanceRecord) {
const value = Number(record.id);
return Number.isFinite(value) && value > 0 ? value : null;
}
@ -367,7 +366,7 @@ function valueToEditString(value: unknown) {
return String(value);
}
function recordToEditForm(record: LogStormAttendanceRecord): AttendanceRecordEditForm | null {
function recordToEditForm(record: AttendanceRecord): AttendanceRecordEditForm | null {
const recordId = getRecordId(record);
if (!recordId) return null;
@ -415,7 +414,7 @@ export default function EmployeeAttendanceCard({
const [loadingMode, setLoadingMode] = useState<"saved" | "analyze" | null>(null);
const [busyKey, setBusyKey] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const [result, setResult] = useState<LogStormAttendanceResponse | null>(null);
const [result, setResult] = useState<AttendanceAnalysisResponse | null>(null);
const [expandedRecordKey, setExpandedRecordKey] = useState<string | null>(null);
const [expandedComments, setExpandedComments] = useState<Record<number, boolean>>({});
const [commentsMap, setCommentsMap] = useState<Record<number, AttendanceRecordComment[]>>({});
@ -465,12 +464,12 @@ export default function EmployeeAttendanceCard({
try {
setLoading(true);
setLoadingMode("analyze");
await apiClient.analyzeLogStormAttendance({
await apiClient.analyzeAttendance({
employee_id: employeeId,
period_start: periodStart,
period_end: periodEnd,
});
const savedRecords = await apiClient.getLogStormAttendanceRecords({
const savedRecords = await apiClient.getAttendanceRecords({
employee_id: employeeId,
date_from: periodStart,
date_to: periodEnd,
@ -514,7 +513,7 @@ export default function EmployeeAttendanceCard({
setLoading(true);
setLoadingMode("saved");
setError(null);
const response = await apiClient.getLogStormAttendanceRecords({
const response = await apiClient.getAttendanceRecords({
employee_id: employeeId,
date_from: periodStart,
date_to: periodEnd,
@ -658,7 +657,7 @@ export default function EmployeeAttendanceCard({
async function saveEditedRecord() {
if (!editForm) return;
const payload: LogStormAttendanceRecordUpdatePayload = {
const payload: AttendanceRecordUpdatePayload = {
arrival_time: nullableTime(editForm.arrival_time),
departure_time: nullableTime(editForm.departure_time),
work_hours: nullableNumber(editForm.work_hours),
@ -704,11 +703,8 @@ export default function EmployeeAttendanceCard({
<form onSubmit={handleSubmit} className="mb-4 space-y-3">
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
<div>
<div className="flex items-center gap-2 text-sm font-semibold text-[var(--foreground)]">
<CalendarCheck size={18} />
Посещаемость
</div>
<p className="app-text-muted mt-1 text-sm">Анализ проходов LogStorm по сотруднику</p>
<h2 className="app-card-caption">Посещаемость</h2>
<p className="app-text-muted mt-2 text-sm">Анализ проходов по сотруднику</p>
</div>
<div className="flex items-center gap-2 sm:shrink-0">

View File

@ -1,7 +1,7 @@
import { buildQuery, type RequestFn } from './utils';
import type { User } from '@/types/api';
export type LogStormDateOverridePayload = {
export type AttendanceDateOverridePayload = {
date: string;
is_workday: boolean;
reason?: string;
@ -10,15 +10,15 @@ export type LogStormDateOverridePayload = {
expected_hours?: number;
};
export type LogStormSchedulePayload = {
export type AttendanceSchedulePayload = {
start_time: string;
end_time: string;
expected_hours: number;
workdays: string[];
date_overrides?: LogStormDateOverridePayload[];
date_overrides?: AttendanceDateOverridePayload[];
};
export type EmployeeWorkSchedule = LogStormSchedulePayload & {
export type EmployeeWorkSchedule = AttendanceSchedulePayload & {
id: number | null;
employee_id: number;
is_active: boolean;
@ -28,14 +28,14 @@ export type EmployeeWorkSchedule = LogStormSchedulePayload & {
updated_at?: string | null;
};
export type LogStormAttendanceAnalyzePayload = {
export type AttendanceAnalyzePayload = {
employee_id: number;
period_start: string;
period_end: string;
schedule?: LogStormSchedulePayload;
schedule?: AttendanceSchedulePayload;
};
export type LogStormAttendanceRecord = {
export type AttendanceRecord = {
id?: number;
date?: string;
employee_id?: string;
@ -78,12 +78,12 @@ export type AttendanceRecordComment = {
created_at: string;
};
export type LogStormAttendanceResponse = {
records?: LogStormAttendanceRecord[];
export type AttendanceAnalysisResponse = {
records?: AttendanceRecord[];
[key: string]: unknown;
};
export type LogStormAttendanceRecordsQuery = {
export type AttendanceRecordsQuery = {
employee_id?: number | string;
date_from?: string;
date_to?: string;
@ -91,8 +91,8 @@ export type LogStormAttendanceRecordsQuery = {
limit?: number;
};
export type LogStormAttendanceRecordUpdatePayload = Partial<Pick<
LogStormAttendanceRecord,
export type AttendanceRecordUpdatePayload = Partial<Pick<
AttendanceRecord,
| 'arrival_time'
| 'departure_time'
| 'work_hours'
@ -110,11 +110,11 @@ export type LogStormAttendanceRecordUpdatePayload = Partial<Pick<
| 'is_absent'
>>;
export type PaginatedLogStormAttendanceRecords = {
export type PaginatedAttendanceRecords = {
count: number;
next: string | null;
previous: string | null;
results: LogStormAttendanceRecord[];
results: AttendanceRecord[];
};
export type MonthlyAttendanceMatrixCell = {
@ -173,30 +173,30 @@ export type MonthlyAttendanceMatrixQuery = {
export function createAttendanceApi(request: RequestFn) {
return {
analyzeLogStormAttendance: (data: LogStormAttendanceAnalyzePayload) =>
analyzeAttendance: (data: AttendanceAnalyzePayload) =>
request('/api/v1/attendance/logstorm/analyze/', {
method: 'POST',
body: JSON.stringify(data),
}) as Promise<LogStormAttendanceResponse>,
getLogStormAttendanceRecords: (params?: LogStormAttendanceRecordsQuery) =>
request(`/api/v1/attendance/records/${buildQuery(params)}`) as Promise<PaginatedLogStormAttendanceRecords>,
}) as Promise<AttendanceAnalysisResponse>,
getAttendanceRecords: (params?: AttendanceRecordsQuery) =>
request(`/api/v1/attendance/records/${buildQuery(params)}`) as Promise<PaginatedAttendanceRecords>,
getMonthlyAttendanceMatrix: (params: MonthlyAttendanceMatrixQuery) =>
request(`/api/v1/attendance/monthly-matrix/${buildQuery(params)}`) as Promise<MonthlyAttendanceMatrix>,
getEmployeeWorkSchedule: (employeeId: number | string) =>
request(`/api/v1/attendance/work-schedules/${employeeId}/`) as Promise<EmployeeWorkSchedule>,
updateEmployeeWorkSchedule: (
employeeId: number | string,
data: Partial<LogStormSchedulePayload & { is_active: boolean }>,
data: Partial<AttendanceSchedulePayload & { is_active: boolean }>,
) =>
request(`/api/v1/attendance/work-schedules/${employeeId}/`, {
method: 'PATCH',
body: JSON.stringify(data),
}) as Promise<EmployeeWorkSchedule>,
updateAttendanceRecord: (recordId: number, data: LogStormAttendanceRecordUpdatePayload) =>
updateAttendanceRecord: (recordId: number, data: AttendanceRecordUpdatePayload) =>
request(`/api/v1/attendance/records/${recordId}/`, {
method: 'PATCH',
body: JSON.stringify(data),
}) as Promise<LogStormAttendanceRecord>,
}) as Promise<AttendanceRecord>,
getAttendanceRecordComments: (recordId: number) =>
request(`/api/v1/attendance/records/${recordId}/comments/`) as Promise<AttendanceRecordComment[]>,
addAttendanceRecordComment: (recordId: number, text: string) =>