refactor: clean up code formatting and improve readability

- Standardized table formatting in `api.md` for privilege keys, enhancing clarity.
- Removed unnecessary line breaks and improved inline formatting in various components, including `right-section.tsx`, `company-settings.remote.service.ts`, and `timeline-helpers.tsx`, to streamline code readability.
- Updated test cases in `privilege-key-hierarchy.test.ts` and `filter-menu-by-view-privilege.test.ts` for better alignment and consistency in assertions.

These changes improve the overall code quality and maintainability, making it easier for developers to navigate and understand the codebase.
This commit is contained in:
shancheas
2026-09-02 08:14:37 +07:00
parent 87bfe50f0e
commit e316afa51d
18 changed files with 69 additions and 170 deletions
@@ -104,12 +104,6 @@ export function RightSection() {
</div>
</div>
<p className="text-[13px] text-center text-gray-600 mt-6 max-w-[85%] z-10 leading-[1.6]">
Compatible with{' '}
<span className="font-bold italic text-gray-900">Gmail, Outlook Web, LinkedIn and most web editors</span> for a
smooth writing experience anywhere online.
</p>
{/* Pagination Indicators */}
<div className="flex gap-1.5 mt-8 z-10 mb-2">
<div className="w-6 h-1 rounded-full bg-brand-500"></div>
@@ -1,8 +1,5 @@
import type { AxiosInstance } from '@repo/core-api/http-client';
import type {
CompanySettingsEntity,
UpdateCompanySettingsPayload,
} from '../domain/entities/company-settings.entity';
import type { CompanySettingsEntity, UpdateCompanySettingsPayload } from '../domain/entities/company-settings.entity';
export class CompanySettingsRemoteService {
constructor(private readonly client: AxiosInstance) {}
@@ -1,10 +1,7 @@
import { BaseDataTransformer } from '@repo/core-api/data-services';
import { apiClient } from '../../../../../../../core/lib/api-client';
import { TrackGoRemoteDataServices } from '../../../../../../../core/lib/trackgo-remote-data-services';
import {
companySettingsModuleConfig,
type CompanySettingsShellEntity,
} from '../constants/company-settings.constants';
import { companySettingsModuleConfig, type CompanySettingsShellEntity } from '../constants/company-settings.constants';
import { CompanySettingsRemoteService } from '../../data/company-settings.remote.service';
class CompanySettingsShellTransformer extends BaseDataTransformer<CompanySettingsShellEntity> {
@@ -25,10 +25,7 @@ export default function CompanySettingsModule() {
>
<Routes>
<Route path="/index" element={<IndexPage />} />
<Route
path="/"
element={<Navigate to={`${companySettingsModuleConfig.webUrl}/index`} replace />}
/>
<Route path="/" element={<Navigate to={`${companySettingsModuleConfig.webUrl}/index`} replace />} />
<Route path="*" element={<Navigate to="/404" replace />} />
</Routes>
</EnterpriseModuleProvider>
@@ -91,11 +91,7 @@ export default function CompanySettingsPage() {
<Stack gap="md" component="form" onSubmit={onSubmit}>
<Grid gutter="md">
<Grid.Col span={{ base: 12, md: 6 }}>
<FieldDatePicker
control={form.control}
name="cycleStartDate"
label={t('fields.cycleStartDate')}
/>
<FieldDatePicker control={form.control} name="cycleStartDate" label={t('fields.cycleStartDate')} />
</Grid.Col>
<Grid.Col span={{ base: 12, md: 6 }}>
<FieldNumberInput
@@ -49,9 +49,7 @@ export function TimelineActivityList({
radius="md"
shadow={selected ? 'sm' : undefined}
style={{
borderColor: selected
? 'var(--mantine-color-blue-filled)'
: 'var(--mantine-color-default-border)',
borderColor: selected ? 'var(--mantine-color-blue-filled)' : 'var(--mantine-color-default-border)',
borderWidth: selected ? 2 : 1,
}}
>
@@ -1,12 +1,5 @@
import type { ReactNode } from 'react';
import {
Paper,
ScrollArea,
SegmentedControl,
Stack,
Text,
TextInput,
} from '@repo/ui/components';
import { Paper, ScrollArea, SegmentedControl, Stack, Text, TextInput } from '@repo/ui/components';
import { Search } from 'lucide-react';
import { TimelineActivityList } from './timeline-activity-list';
import type { TimelineActivityGroup, TimelineActivityTab } from './timeline-helpers';
@@ -115,7 +115,9 @@ describe('timeline helpers', () => {
'visit-1',
'ungrouped',
]);
expect(filterActivityGroups(groups, { tab: 'completed', query: '' }).map((group) => group.key)).toEqual(['visit-2']);
expect(filterActivityGroups(groups, { tab: 'completed', query: '' }).map((group) => group.key)).toEqual([
'visit-2',
]);
expect(filterActivityGroups(groups, { tab: 'on_the_way', query: 'maju' }).map((group) => group.title)).toEqual([
'Toko Maju',
]);
@@ -1,7 +1,4 @@
import type {
TimelineActivityEntity,
TimelineFootprintEntity,
} from '../../domain/entities/timeline.entity';
import type { TimelineActivityEntity, TimelineFootprintEntity } from '../../domain/entities/timeline.entity';
export type TimelineActivityGroup = {
key: string;
@@ -46,9 +43,7 @@ export function groupActivities(activities: TimelineActivityEntity[]): TimelineA
const sorted = sortByRecordedAt(items);
const last = sorted[sorted.length - 1];
const first = sorted[0];
const title =
last?.customer?.name ??
(key === 'ungrouped' ? 'ungrouped' : (last?.customer?.code ?? key));
const title = last?.customer?.name ?? (key === 'ungrouped' ? 'ungrouped' : (last?.customer?.code ?? key));
return {
key,
@@ -95,10 +90,7 @@ export function resolvePlaybackPositions(
return [];
}
const latestByEmployee = new Map<
string,
{ latitude: number; longitude: number; label: string }
>();
const latestByEmployee = new Map<string, { latitude: number; longitude: number; label: string }>();
for (const footprint of footprints) {
if (footprint.recordedAt > playbackTime) {
@@ -155,10 +147,6 @@ export function shouldRestartPlayback(
return playbackTime === null || playbackTime >= bounds.max;
}
export function advancePlaybackTime(
current: number,
bounds: { min: number; max: number },
step: number,
): number {
export function advancePlaybackTime(current: number, bounds: { min: number; max: number }, step: number): number {
return Math.min(bounds.max, current + step);
}
@@ -104,10 +104,7 @@ export function TimelinePlaybackOverlay({
value={last ? `${formatClock(last.recordedAt)} · ${activityLabel(last.type)}` : '—'}
/>
<OverlayMetric label={currentLocationLabel} value={currentLocation || '—'} />
<OverlayMetric
label={activitiesLabel}
value={group ? String(group.activities.length) : '—'}
/>
<OverlayMetric label={activitiesLabel} value={group ? String(group.activities.length) : '—'} />
</SimpleGrid>
</Stack>
@@ -25,10 +25,7 @@ export default function SalesTimelineModule() {
>
<Routes>
<Route path="/index" element={<IndexPage />} />
<Route
path="/"
element={<Navigate to={`${salesTimelineModuleConfig.webUrl}/index`} replace />}
/>
<Route path="/" element={<Navigate to={`${salesTimelineModuleConfig.webUrl}/index`} replace />} />
<Route path="*" element={<Navigate to="/404" replace />} />
</Routes>
</EnterpriseModuleProvider>
@@ -153,10 +153,7 @@ export default function TimelinePage() {
[footprints, playbackTime],
);
const groups = useMemo(() => groupActivities(visibleActivities), [visibleActivities]);
const filteredGroups = useMemo(
() => filterActivityGroups(groups, { tab, query: search }),
[groups, search, tab],
);
const filteredGroups = useMemo(() => filterActivityGroups(groups, { tab, query: search }), [groups, search, tab]);
useEffect(() => {
if (filteredGroups.length === 0) {
@@ -179,9 +176,7 @@ export default function TimelinePage() {
);
const focusPositions = useMemo(() => {
if (selectedGroup && selectedGroup.activities.length > 0) {
return selectedGroup.activities.map(
(activity): [number, number] => [activity.latitude, activity.longitude],
);
return selectedGroup.activities.map((activity): [number, number] => [activity.latitude, activity.longitude]);
}
return dayPositions;
}, [dayPositions, selectedGroup]);
@@ -195,10 +190,7 @@ export default function TimelinePage() {
})),
[visibleFootprints],
);
const activityLabel = useCallback(
(type: string) => t(`activities.types.${type}`, { defaultValue: type }),
[t],
);
const activityLabel = useCallback((type: string) => t(`activities.types.${type}`, { defaultValue: type }), [t]);
const mapActivities = useMemo(
() =>
visibleActivities.map((activity) => ({
@@ -282,13 +274,7 @@ export default function TimelinePage() {
</Box>
</FormProvider>
<Box
pos="absolute"
bottom={16}
left={{ base: 12, md: 432 }}
right={{ base: 12, md: 16 }}
style={{ zIndex: 2 }}
>
<Box pos="absolute" bottom={16} left={{ base: 12, md: 432 }} right={{ base: 12, md: 16 }} style={{ zIndex: 2 }}>
<TimelinePlaybackOverlay
group={selectedGroup}
ungroupedLabel={t('activities.ungrouped')}
@@ -52,14 +52,9 @@ describe('groupPrivilegeKeys', () => {
expect(grouped.map((tab) => tab.group)).toEqual(['ADMIN', 'MOBILE']);
expect(grouped[0]?.parents[0]?.parent).toBe('SALES');
expect(grouped[0]?.parents[0]?.modules.map((m) => m.module)).toEqual([
'ACTIVITIES',
'DATA',
]);
expect(grouped[0]?.parents[0]?.modules.map((m) => m.module)).toEqual(['ACTIVITIES', 'DATA']);
expect(grouped[1]?.parents[0]?.modules[0]?.directRow?.code).toBe('MOBILE.SALES.PLAN');
expect(grouped[1]?.parents[0]?.modules[0]?.submodules[0]?.code).toBe(
'MOBILE.SALES.PLAN.ATTENDANCE',
);
expect(grouped[1]?.parents[0]?.modules[0]?.submodules[0]?.code).toBe('MOBILE.SALES.PLAN.ATTENDANCE');
});
});
@@ -72,10 +67,7 @@ describe('flattenParentSectionRows', () => {
expect(salesParent).toBeDefined();
const tableRows = flattenParentSectionRows(salesParent!);
expect(tableRows.map((r) => r.code)).toEqual([
'ADMIN.SALES.DATA.CYCLE',
'ADMIN.SALES.ACTIVITIES.PLAN',
]);
expect(tableRows.map((r) => r.code)).toEqual(['ADMIN.SALES.DATA.CYCLE', 'ADMIN.SALES.ACTIVITIES.PLAN']);
expect(tableRows[0]).toMatchObject({ module: 'DATA', submodule: 'CYCLE' });
expect(tableRows[1]).toMatchObject({ module: 'ACTIVITIES', submodule: 'PLAN' });
});
@@ -28,10 +28,7 @@ function segmentLabel(t: (key: string) => string, kind: string, value: string) {
return translated === key ? formatPrivilegeSegment(value) : translated;
}
function submoduleCellLabel(
t: (key: string) => string,
row: PrivilegeTableRow,
) {
function submoduleCellLabel(t: (key: string) => string, row: PrivilegeTableRow) {
if (row.submodule) {
return row.label || segmentLabel(t, 'submodule', row.submodule);
}
@@ -53,11 +50,7 @@ function MatrixActionCells({
<Table.Td key={action} ta="center" w={ACTION_COL_WIDTH} miw={ACTION_COL_WIDTH} maw={ACTION_COL_WIDTH}>
<Box display="flex" style={{ justifyContent: 'center', alignItems: 'center' }}>
{mode === 'edit' && formControl ? (
<FieldCheckbox
control={formControl.control}
name={`matrix.${row.keyId}.${action}`}
label=""
/>
<FieldCheckbox control={formControl.control} name={`matrix.${row.keyId}.${action}`} label="" />
) : row.cell[action] ? (
<Check size={16} />
) : (
@@ -137,12 +130,7 @@ function ParentMatrixTable({
);
}
export function PrivilegeMatrixLayout({
groups,
t,
mode,
formControl,
}: PrivilegeMatrixLayoutProps) {
export function PrivilegeMatrixLayout({ groups, t, mode, formControl }: PrivilegeMatrixLayoutProps) {
if (groups.length === 0) {
return null;
}
@@ -27,7 +27,9 @@ describe('enterpriseStorageAdapter', () => {
return null;
});
await expect(enterpriseStorageAdapter.getPrivileges('ADMIN.SETTINGS.USER.PRIVILEGES')).resolves.toEqual(defaultPrivileges);
await expect(enterpriseStorageAdapter.getPrivileges('ADMIN.SETTINGS.USER.PRIVILEGES')).resolves.toEqual(
defaultPrivileges,
);
await expect(enterpriseStorageAdapter.getPrivileges('UNKNOWN')).resolves.toEqual(defaultPrivileges);
});
@@ -94,7 +94,11 @@ describe('filterMenuByViewPrivilege', () => {
},
];
const filtered = filterMenuByViewPrivilege(menu, { 'ADMIN.SALES.ACTIVITIES.ORDER': { ...noPrivileges, ALLOW_VIEW: true } }, false);
const filtered = filterMenuByViewPrivilege(
menu,
{ 'ADMIN.SALES.ACTIVITIES.ORDER': { ...noPrivileges, ALLOW_VIEW: true } },
false,
);
expect(filtered.find((item) => item.key === 'sales')?.children?.map((child) => child.key)).toEqual([
'orders',