mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
Merge branch 'development' into 'staging'
Development See merge request mbugroup/lti-web-client!286
This commit is contained in:
@@ -114,11 +114,13 @@ export const MAIN_DRAWER_LINKS: SidebarMenuItem[] = [
|
||||
text: 'Penjualan',
|
||||
link: '/marketing',
|
||||
icon: 'heroicons-outline:currency-dollar',
|
||||
permission: ['lti.marketing.delivery_order.list'],
|
||||
},
|
||||
{
|
||||
text: 'Keuangan',
|
||||
link: '/finance',
|
||||
icon: 'heroicons-outline:banknotes',
|
||||
permission: ['lti.finance.transactions.list'],
|
||||
},
|
||||
{
|
||||
text: 'Biaya',
|
||||
|
||||
@@ -127,6 +127,10 @@ export function DailyChecklistContent() {
|
||||
{ id: number; name: string }[]
|
||||
>([]);
|
||||
|
||||
const sortedSelectedEmployees = selectedEmployees.toSorted((a, b) =>
|
||||
a.name.localeCompare(b.name)
|
||||
);
|
||||
|
||||
const [dailyChecklistId, setDailyChecklistId] = useState<string | null>(null);
|
||||
const [checklistStatus, setChecklistStatus] = useState<string>('DRAFT');
|
||||
// const [isEditMode, setIsEditMode] = useState(false);
|
||||
@@ -486,6 +490,11 @@ export function DailyChecklistContent() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tempSelectedPhaseIds.length) {
|
||||
toast.error('Pilih minimal satu fase');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Insert new phase links
|
||||
const setDailyChecklistPhaseRes =
|
||||
@@ -535,14 +544,6 @@ export function DailyChecklistContent() {
|
||||
}
|
||||
};
|
||||
|
||||
const toggleSelectAllAbk = () => {
|
||||
if (tempSelectedEmployees.length === employees.length) {
|
||||
setTempSelectedEmployees([]);
|
||||
} else {
|
||||
setTempSelectedEmployees([...employees]);
|
||||
}
|
||||
};
|
||||
|
||||
const applyAbkSelection = async () => {
|
||||
if (!dailyChecklistId) {
|
||||
toast.error('Checklist belum tersedia');
|
||||
@@ -853,10 +854,34 @@ export function DailyChecklistContent() {
|
||||
);
|
||||
|
||||
const isAllAbkSelected =
|
||||
tempSelectedEmployees.length === employees.length && employees.length > 0;
|
||||
tempSelectedEmployees.length === filteredEmployees.length &&
|
||||
filteredEmployees.length > 0 &&
|
||||
tempSelectedEmployees.every((tempSelectedEmployee) => {
|
||||
return (
|
||||
filteredEmployees.findIndex(
|
||||
(filteredEmployee) => filteredEmployee.id === tempSelectedEmployee.id
|
||||
) >= 0
|
||||
);
|
||||
});
|
||||
const isAllPhasesSelected =
|
||||
tempSelectedPhaseIds.length === availablePhases.length &&
|
||||
availablePhases.length > 0;
|
||||
tempSelectedPhaseIds.length === filteredPhases.length &&
|
||||
filteredPhases.length > 0 &&
|
||||
tempSelectedPhaseIds.every((tempSelectedPhaseId) => {
|
||||
return (
|
||||
filteredPhases.findIndex(
|
||||
(filteredPhase) =>
|
||||
String(filteredPhase.id) === String(tempSelectedPhaseId)
|
||||
) >= 0
|
||||
);
|
||||
});
|
||||
|
||||
const toggleSelectAllAbk = () => {
|
||||
if (isAllAbkSelected) {
|
||||
setTempSelectedEmployees([]);
|
||||
} else {
|
||||
setTempSelectedEmployees([...filteredEmployees]);
|
||||
}
|
||||
};
|
||||
|
||||
// Group activities by PHASE → TIME_TYPE → ACTIVITIES
|
||||
const groupActivitiesByPhase = () => {
|
||||
@@ -1130,7 +1155,7 @@ export function DailyChecklistContent() {
|
||||
<th className='text-left py-3 px-4 text-sm font-semibold text-gray-700 border-r border-gray-200 min-w-[200px]'>
|
||||
Aktivitas
|
||||
</th>
|
||||
{selectedEmployees.map((emp) => (
|
||||
{sortedSelectedEmployees.map((emp) => (
|
||||
<th
|
||||
key={emp.id}
|
||||
className='text-center py-3 px-4 text-sm font-semibold text-gray-700 border-r border-gray-200 min-w-[100px]'
|
||||
@@ -1216,6 +1241,14 @@ export function DailyChecklistContent() {
|
||||
}
|
||||
|
||||
// ACTIVITY rows (Child rows with checkboxes)
|
||||
activities.sort((a, b) =>
|
||||
a.name.localeCompare(b.name, undefined, {
|
||||
sensitivity: 'base',
|
||||
})
|
||||
);
|
||||
|
||||
console.log(activities);
|
||||
|
||||
activities.forEach((activity, index) => {
|
||||
const taskId =
|
||||
taskIdsByPhaseActivityId[activity.id];
|
||||
@@ -1244,7 +1277,7 @@ export function DailyChecklistContent() {
|
||||
</p>
|
||||
)}
|
||||
</td>
|
||||
{selectedEmployees.map((emp) => (
|
||||
{sortedSelectedEmployees.map((emp) => (
|
||||
<td
|
||||
key={emp.id}
|
||||
className='text-center py-3 px-4 border-r border-gray-200'
|
||||
@@ -1519,14 +1552,14 @@ export function DailyChecklistContent() {
|
||||
setTempSelectedPhaseIds([]);
|
||||
} else {
|
||||
setTempSelectedPhaseIds(
|
||||
availablePhases.map((p) => String(p.id))
|
||||
filteredPhases.map((p) => String(p.id))
|
||||
);
|
||||
}
|
||||
}}
|
||||
className='checkbox-clean'
|
||||
/>
|
||||
<span className='text-sm font-medium text-gray-700 group-hover:text-gray-900'>
|
||||
Pilih Semua ({availablePhases.length} Fase)
|
||||
Pilih Semua ({filteredPhases.length} Fase)
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
@@ -1621,7 +1654,7 @@ export function DailyChecklistContent() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{employees.length > 0 && (
|
||||
{filteredEmployees.length > 0 && (
|
||||
<div className='flex items-center gap-3 px-1 py-2'>
|
||||
<label className='flex items-center gap-2 cursor-pointer group'>
|
||||
<input
|
||||
@@ -1631,7 +1664,7 @@ export function DailyChecklistContent() {
|
||||
className='checkbox-clean'
|
||||
/>
|
||||
<span className='text-sm font-medium text-gray-700 group-hover:text-gray-900'>
|
||||
Pilih Semua ({employees.length} ABK)
|
||||
Pilih Semua ({filteredEmployees.length} ABK)
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
+28
-3
@@ -275,6 +275,13 @@ export function DetailDailyChecklistContent() {
|
||||
])
|
||||
).values()
|
||||
);
|
||||
|
||||
uniqueEmployees.sort((a, b) =>
|
||||
a.name.localeCompare(b.name, undefined, {
|
||||
sensitivity: 'base',
|
||||
})
|
||||
);
|
||||
|
||||
setEmployees(uniqueEmployees);
|
||||
|
||||
// Group data by Phase → Time Type → Activity
|
||||
@@ -779,11 +786,23 @@ export function DetailDailyChecklistContent() {
|
||||
}
|
||||
|
||||
// ACTIVITY rows
|
||||
timeGroup.activities.forEach((activity, index) => {
|
||||
const activities = timeGroup.activities;
|
||||
|
||||
activities.sort((a, b) =>
|
||||
a.name.localeCompare(b.name, undefined, {
|
||||
sensitivity: 'base',
|
||||
})
|
||||
);
|
||||
|
||||
activities.forEach((activity, index) => {
|
||||
const indentClass = hasMultipleTimeTypes
|
||||
? 'pl-12'
|
||||
: 'pl-8';
|
||||
|
||||
console.log({
|
||||
activity,
|
||||
});
|
||||
|
||||
rows.push(
|
||||
<tr
|
||||
key={`activity-${activity.id}-${index}`}
|
||||
@@ -823,9 +842,15 @@ export function DetailDailyChecklistContent() {
|
||||
})}
|
||||
<td className='py-3 px-4'>
|
||||
{activity.employees.length > 0 &&
|
||||
activity.employees[0].note ? (
|
||||
activity.employees[
|
||||
activity.employees.length - 1
|
||||
].note ? (
|
||||
<p className='text-sm text-gray-600'>
|
||||
{activity.employees[0].note}
|
||||
{
|
||||
activity.employees[
|
||||
activity.employees.length - 1
|
||||
].note
|
||||
}
|
||||
</p>
|
||||
) : (
|
||||
<p className='text-xs text-gray-400 italic'>
|
||||
|
||||
+17
-2
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Plus, MoreVertical, Pencil, Trash2 } from 'lucide-react';
|
||||
import { Card, CardContent } from '@/figma-make/components/base/card';
|
||||
import { Button } from '@/figma-make/components/base/button';
|
||||
@@ -404,7 +404,22 @@ export function MasterConfigurationContent() {
|
||||
</div>
|
||||
|
||||
{/* Add/Edit Modal */}
|
||||
<Dialog open={showModal} onOpenChange={setShowModal}>
|
||||
<Dialog
|
||||
open={showModal}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) {
|
||||
setIsFormInvalid(false);
|
||||
setConfigurationForm({
|
||||
id: 0,
|
||||
date: '',
|
||||
percentage_threshold_bad: '',
|
||||
percentage_threshold_enough: '',
|
||||
});
|
||||
}
|
||||
|
||||
setShowModal(open);
|
||||
}}
|
||||
>
|
||||
<DialogContent className='sm:max-w-md bg-white rounded-xl shadow-lg'>
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
|
||||
Reference in New Issue
Block a user