fix
This commit is contained in:
@@ -20,7 +20,7 @@ type CurrentEmployee = {
|
||||
avatar?: string | null;
|
||||
};
|
||||
|
||||
type MainTabKey = "incoming" | "transfer" | "review" | "outgoing" | "archive";
|
||||
type MainTabKey = "incoming" | "transfer" | "review" | "outgoing";
|
||||
type DocTabKey =
|
||||
| "all"
|
||||
| "simple"
|
||||
@@ -40,6 +40,22 @@ const employeeLoading = ref(false);
|
||||
const refreshing = ref(false);
|
||||
const switchingList = ref(false);
|
||||
let suppressDocTabReload = false;
|
||||
const mainTabCounts = ref<Record<MainTabKey, number>>({
|
||||
incoming: 0,
|
||||
transfer: 0,
|
||||
review: 0,
|
||||
outgoing: 0,
|
||||
});
|
||||
const docTabCounts = ref<Record<DocTabKey, number>>({
|
||||
all: 0,
|
||||
simple: 0,
|
||||
memo: 0,
|
||||
bill: 0,
|
||||
contract: 0,
|
||||
contract_application: 0,
|
||||
entry_letter: 0,
|
||||
outgoing_letter: 0,
|
||||
});
|
||||
|
||||
const {
|
||||
items: tasks,
|
||||
@@ -48,6 +64,7 @@ const {
|
||||
load: loadTasks,
|
||||
} = useModelApi<Task, TaskCreate, TaskUpdate, TaskListParams>(taskApi, {
|
||||
defaultListParams: { ordering: "-id" },
|
||||
autoLoad: false,
|
||||
loadErrorMessage: "Не удалось загрузить задачи",
|
||||
});
|
||||
|
||||
@@ -63,6 +80,7 @@ const {
|
||||
TaskTransferListParams
|
||||
>(taskTransferApi, {
|
||||
defaultListParams: { ordering: "-id" },
|
||||
autoLoad: false,
|
||||
loadErrorMessage: "Не удалось загрузить переносы срока",
|
||||
});
|
||||
|
||||
@@ -71,7 +89,6 @@ const mainTabs = [
|
||||
{ key: "transfer", label: "Перенос срока", icon: "underway-o" },
|
||||
{ key: "review", label: "Для проверки", icon: "eye-o" },
|
||||
{ key: "outgoing", label: "Исходящие", icon: "send-gift-o" },
|
||||
{ key: "archive", label: "Архив", icon: "folder-o" },
|
||||
] as const;
|
||||
|
||||
const docTabs = [
|
||||
@@ -91,6 +108,7 @@ const visibleItems = computed(() =>
|
||||
const activeLoading = computed(() =>
|
||||
mainTab.value === "transfer" ? taskTransferLoading.value : taskLoading.value,
|
||||
);
|
||||
const showLoading = computed(() => activeLoading.value || refreshing.value);
|
||||
const showEmployeeLoading = computed(
|
||||
() =>
|
||||
employeeLoading.value &&
|
||||
@@ -101,6 +119,11 @@ const activeError = computed(() =>
|
||||
mainTab.value === "transfer" ? taskTransferError.value : taskError.value,
|
||||
);
|
||||
const showDocTabs = computed(() => mainTab.value !== "transfer");
|
||||
const visibleDocTabs = computed(() =>
|
||||
showDocTabs.value
|
||||
? docTabs.filter((tab) => (docTabCounts.value[tab.key] ?? 0) > 0)
|
||||
: [],
|
||||
);
|
||||
|
||||
function personName(
|
||||
person: { short_name?: string | null; name?: string | null } | null,
|
||||
@@ -120,6 +143,10 @@ function taskTitle(task: {
|
||||
return task.text?.trim() || task.result?.trim() || `Задача #${task.id}`;
|
||||
}
|
||||
|
||||
function badgeValue(count: number) {
|
||||
return count > 0 ? count : undefined;
|
||||
}
|
||||
|
||||
function isTaskTransfer(item: Task | TaskTransfer): item is TaskTransfer {
|
||||
return "employee_from" in item;
|
||||
}
|
||||
@@ -144,19 +171,17 @@ function itemPath(item: Task | TaskTransfer) {
|
||||
return isTaskTransfer(item) ? `/tasks/${item.task.id}` : `/tasks/${item.id}`;
|
||||
}
|
||||
|
||||
function taskParams(): TaskListParams | TaskTransferListParams | null {
|
||||
if (!employee.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const employeeId = employee.value.id;
|
||||
|
||||
switch (mainTab.value) {
|
||||
function buildTaskParams(
|
||||
tab: MainTabKey,
|
||||
doc: DocTabKey,
|
||||
employeeId: number,
|
||||
): TaskListParams | TaskTransferListParams | null {
|
||||
switch (tab) {
|
||||
case "incoming":
|
||||
return {
|
||||
doer: employeeId,
|
||||
archive: false,
|
||||
typ: docTab.value === "all" ? undefined : docTab.value,
|
||||
typ: doc === "all" ? undefined : doc,
|
||||
q: "entry",
|
||||
incomplete: true,
|
||||
};
|
||||
@@ -164,24 +189,50 @@ function taskParams(): TaskListParams | TaskTransferListParams | null {
|
||||
return {
|
||||
q: "to_approve",
|
||||
incomplete: true,
|
||||
typ: docTab.value === "all" ? undefined : docTab.value,
|
||||
archive: false,
|
||||
typ: doc === "all" ? undefined : doc,
|
||||
};
|
||||
case "outgoing":
|
||||
return {
|
||||
q: "outgoing",
|
||||
archive: false,
|
||||
incomplete: true,
|
||||
typ: docTab.value === "all" ? undefined : docTab.value,
|
||||
typ: doc === "all" ? undefined : doc,
|
||||
};
|
||||
case "archive":
|
||||
case "transfer":
|
||||
return {
|
||||
typ: docTab.value === "all" ? undefined : docTab.value,
|
||||
employee_to: employeeId,
|
||||
status: "A",
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function taskParams(): TaskListParams | TaskTransferListParams | null {
|
||||
if (!employee.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return buildTaskParams(mainTab.value, docTab.value, employee.value.id);
|
||||
}
|
||||
|
||||
function taskCountParams(tab: MainTabKey): TaskListParams | TaskTransferListParams | null {
|
||||
if (!employee.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return buildTaskParams(tab, "all", employee.value.id);
|
||||
}
|
||||
|
||||
function docCountParams(doc: DocTabKey): TaskListParams | null {
|
||||
if (!employee.value || mainTab.value === "transfer") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return buildTaskParams(mainTab.value, doc, employee.value.id) as TaskListParams;
|
||||
}
|
||||
|
||||
async function loadCurrentEmployee() {
|
||||
employeeLoading.value = true;
|
||||
employeeError.value = "";
|
||||
@@ -217,10 +268,80 @@ async function reloadList() {
|
||||
await loadTasks(params as TaskListParams);
|
||||
}
|
||||
|
||||
async function reloadForTabChange() {
|
||||
async function countTaskItems(params: TaskListParams | TaskTransferListParams | null) {
|
||||
if (!params) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ("employee_to" in params) {
|
||||
const response = await taskTransferApi.list({ ...params, limit: 1 });
|
||||
return response.count;
|
||||
}
|
||||
|
||||
const response = await taskApi.list({ ...params, limit: 1 });
|
||||
return response.count;
|
||||
}
|
||||
|
||||
async function reloadCounts() {
|
||||
if (!employee.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mainCounts = await Promise.allSettled(
|
||||
mainTabs.map(async (tab) => [tab.key, await countTaskItems(taskCountParams(tab.key))] as const),
|
||||
);
|
||||
mainTabCounts.value = {
|
||||
...mainTabCounts.value,
|
||||
...Object.fromEntries(
|
||||
mainCounts.flatMap((result) =>
|
||||
result.status === "fulfilled" ? [result.value] : [],
|
||||
),
|
||||
),
|
||||
} as Record<MainTabKey, number>;
|
||||
|
||||
if (mainTab.value === "transfer") {
|
||||
docTabCounts.value = {
|
||||
all: 0,
|
||||
simple: 0,
|
||||
memo: 0,
|
||||
bill: 0,
|
||||
contract: 0,
|
||||
contract_application: 0,
|
||||
entry_letter: 0,
|
||||
outgoing_letter: 0,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const docCounts = await Promise.allSettled(
|
||||
docTabs.map(async (tab) => [tab.key, await countTaskItems(docCountParams(tab.key))] as const),
|
||||
);
|
||||
docTabCounts.value = {
|
||||
...docTabCounts.value,
|
||||
...Object.fromEntries(
|
||||
docCounts.flatMap((result) =>
|
||||
result.status === "fulfilled" ? [result.value] : [],
|
||||
),
|
||||
),
|
||||
} as Record<DocTabKey, number>;
|
||||
|
||||
const nextDocTab = visibleDocTabs.value[0]?.key ?? "all";
|
||||
if (docTab.value !== nextDocTab) {
|
||||
suppressDocTabReload = true;
|
||||
docTab.value = nextDocTab;
|
||||
await nextTick();
|
||||
suppressDocTabReload = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function reloadForTabChange(options: { reloadCounts: boolean }) {
|
||||
switchingList.value = true;
|
||||
|
||||
try {
|
||||
if (options.reloadCounts) {
|
||||
await reloadCounts();
|
||||
}
|
||||
|
||||
await reloadList();
|
||||
} finally {
|
||||
switchingList.value = false;
|
||||
@@ -231,6 +352,7 @@ async function onRefresh() {
|
||||
refreshing.value = true;
|
||||
|
||||
try {
|
||||
await reloadCounts();
|
||||
await reloadList();
|
||||
} finally {
|
||||
refreshing.value = false;
|
||||
@@ -246,18 +368,18 @@ watch(mainTab, () => {
|
||||
});
|
||||
}
|
||||
|
||||
void reloadForTabChange();
|
||||
void reloadForTabChange({ reloadCounts: true });
|
||||
});
|
||||
|
||||
watch(docTab, () => {
|
||||
if (showDocTabs.value && !suppressDocTabReload) {
|
||||
void reloadForTabChange();
|
||||
void reloadForTabChange({ reloadCounts: false });
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await loadCurrentEmployee();
|
||||
await reloadList();
|
||||
await reloadForTabChange({ reloadCounts: true });
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -285,22 +407,24 @@ onMounted(async () => {
|
||||
:key="tab.key"
|
||||
:name="tab.key"
|
||||
:icon="tab.icon"
|
||||
:badge="badgeValue(mainTabCounts[tab.key])"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
|
||||
<van-tabs
|
||||
v-if="showDocTabs"
|
||||
v-if="showDocTabs && visibleDocTabs.length > 0"
|
||||
v-model:active="docTab"
|
||||
shrink
|
||||
class="tabs tabs-secondary"
|
||||
>
|
||||
<van-tab
|
||||
v-for="tab in docTabs"
|
||||
v-for="tab in visibleDocTabs"
|
||||
:key="tab.key"
|
||||
:name="tab.key"
|
||||
:title="tab.label"
|
||||
:badge="badgeValue(docTabCounts[tab.key])"
|
||||
/>
|
||||
</van-tabs>
|
||||
|
||||
@@ -311,8 +435,8 @@ onMounted(async () => {
|
||||
@refresh="onRefresh"
|
||||
>
|
||||
<van-list
|
||||
:loading="activeLoading || refreshing"
|
||||
:finished="true"
|
||||
:loading="showLoading"
|
||||
:finished="false"
|
||||
loading-text="Загрузка..."
|
||||
:immediate-check="false"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user