Quellcode durchsuchen

update back form page

production
CANCERYS\kw093 vor 1 Woche
Ursprung
Commit
0fc9f78a21
3 geänderte Dateien mit 101 neuen und 49 gelöschten Zeilen
  1. +80
    -43
      src/components/StockTakeManagement/PickerCardList.tsx
  2. +14
    -0
      src/components/StockTakeManagement/StockTakeTab.tsx
  3. +7
    -6
      src/i18n/zh/inventory.json

+ 80
- 43
src/components/StockTakeManagement/PickerCardList.tsx Datei anzeigen

@@ -47,14 +47,30 @@ interface PickerCardListProps {
onListPageChange: (page: number) => void; onListPageChange: (page: number) => void;
onCardClick: (session: AllPickedStockTakeListReponse) => void; onCardClick: (session: AllPickedStockTakeListReponse) => void;
onReStockTakeClick: (session: AllPickedStockTakeListReponse) => void; onReStockTakeClick: (session: AllPickedStockTakeListReponse) => void;
searchFilters: PickerCardListFilters;
appliedFilters: PickerCardListFilters;
onSearchFiltersChange: (next: PickerCardListFilters) => void;
onAppliedFiltersChange: (next: PickerCardListFilters) => void;
} }


export type PickerCardListFilters = {
sectionDescription: string;
stockTakeSession: string;
status: string;
area: string;
storeId: string;
};

const PickerCardList: React.FC<PickerCardListProps> = ({ const PickerCardList: React.FC<PickerCardListProps> = ({
page, page,
pageSize, pageSize,
onListPageChange, onListPageChange,
onCardClick, onCardClick,
onReStockTakeClick, onReStockTakeClick,
searchFilters,
appliedFilters,
onSearchFiltersChange,
onAppliedFiltersChange,
}) => { }) => {
const { t } = useTranslation(["inventory", "common"]); const { t } = useTranslation(["inventory", "common"]);
dayjs.extend(duration); dayjs.extend(duration);
@@ -72,40 +88,30 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
const [sectionDescriptionOptions, setSectionDescriptionOptions] = useState<string[]>([]); const [sectionDescriptionOptions, setSectionDescriptionOptions] = useState<string[]>([]);
const [stockTakeSectionOptions, setStockTakeSectionOptions] = useState<string[]>([]); const [stockTakeSectionOptions, setStockTakeSectionOptions] = useState<string[]>([]);
const [storeIdOptions, setStoreIdOptions] = useState<string[]>(["2F", "4F"]); const [storeIdOptions, setStoreIdOptions] = useState<string[]>(["2F", "4F"]);
const [searchSectionDescription, setSearchSectionDescription] = useState<string>("All");
const [searchStockTakeSession, setSearchStockTakeSession] = useState<string>("");
const [searchStatus, setSearchStatus] = useState<string>("All");
const [searchArea, setSearchArea] = useState<string>("");
const [searchStoreId, setSearchStoreId] = useState<string>("All");

const [filterSectionDescription, setFilterSectionDescription] = useState<string>("All");
const [filterStockTakeSession, setFilterStockTakeSession] = useState<string>("");
const [filterStatus, setFilterStatus] = useState<string>("All");
const [filterArea, setFilterArea] = useState<string>("");
const [filterStoreId, setFilterStoreId] = useState<string>("All");


const statusOptions = ["pending", "stockTaking", "approving", "completed"]; const statusOptions = ["pending", "stockTaking", "approving", "completed"];


const handleSearch = () => { const handleSearch = () => {
setFilterSectionDescription(searchSectionDescription || "All");
setFilterStockTakeSession(searchStockTakeSession || "");
setFilterStatus(searchStatus || "All");
setFilterArea(searchArea || "");
setFilterStoreId(searchStoreId || "All");
onAppliedFiltersChange({
sectionDescription: searchFilters.sectionDescription || "All",
stockTakeSession: searchFilters.stockTakeSession || "",
status: searchFilters.status || "All",
area: searchFilters.area || "",
storeId: searchFilters.storeId || "All",
});
onListPageChange(0); onListPageChange(0);
}; };


const handleResetSearch = () => { const handleResetSearch = () => {
setSearchSectionDescription("All");
setSearchStockTakeSession("");
setSearchStatus("All");
setSearchArea("");
setSearchStoreId("All");
setFilterSectionDescription("All");
setFilterStockTakeSession("");
setFilterStatus("All");
setFilterArea("");
setFilterStoreId("All");
const resetFilters: PickerCardListFilters = {
sectionDescription: "All",
stockTakeSession: "",
status: "All",
area: "",
storeId: "All",
};
onSearchFiltersChange(resetFilters);
onAppliedFiltersChange(resetFilters);
onListPageChange(0); onListPageChange(0);
}; };


@@ -113,11 +119,11 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
let cancelled = false; let cancelled = false;
setLoading(true); setLoading(true);
getStockTakeRecordsPaged(page, pageSize, { getStockTakeRecordsPaged(page, pageSize, {
sectionDescription: filterSectionDescription,
stockTakeSections: filterStockTakeSession,
status: filterStatus,
area: filterArea,
storeId: filterStoreId,
sectionDescription: appliedFilters.sectionDescription,
stockTakeSections: appliedFilters.stockTakeSession,
status: appliedFilters.status,
area: appliedFilters.area,
storeId: appliedFilters.storeId,
}) })
.then((res) => { .then((res) => {
if (cancelled) return; if (cancelled) return;
@@ -137,7 +143,7 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [page, pageSize, filterSectionDescription, filterStockTakeSession, filterStatus, filterArea, filterStoreId, listRefreshNonce]);
}, [page, pageSize, appliedFilters, listRefreshNonce]);


//const startIdx = page * PER_PAGE; //const startIdx = page * PER_PAGE;
//const paged = stockTakeSessions.slice(startIdx, startIdx + PER_PAGE); //const paged = stockTakeSessions.slice(startIdx, startIdx + PER_PAGE);
@@ -298,9 +304,14 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel>{t("Stock Take Section")}</InputLabel> <InputLabel>{t("Stock Take Section")}</InputLabel>
<Select <Select
value={searchSectionDescription}
value={searchFilters.sectionDescription}
label={t("Stock Take Section")} label={t("Stock Take Section")}
onChange={(e) => setSearchSectionDescription(e.target.value)}
onChange={(e) =>
onSearchFiltersChange({
...searchFilters,
sectionDescription: e.target.value,
})
}
> >
<MenuItem value="All">{t("All")}</MenuItem> <MenuItem value="All">{t("All")}</MenuItem>
{sectionDescriptionOptions.map((desc) => ( {sectionDescriptionOptions.map((desc) => (
@@ -315,8 +326,19 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
<Autocomplete <Autocomplete
freeSolo freeSolo
options={stockTakeSectionOptions} options={stockTakeSectionOptions}
value={searchStockTakeSession}
onInputChange={(_, newValue) => setSearchStockTakeSession(newValue)}
value={searchFilters.stockTakeSession}
onChange={(_, newValue) =>
onSearchFiltersChange({
...searchFilters,
stockTakeSession: newValue || "",
})
}
onInputChange={(_, newValue) =>
onSearchFiltersChange({
...searchFilters,
stockTakeSession: newValue,
})
}
renderInput={(params) => ( renderInput={(params) => (
<TextField <TextField
{...params} {...params}
@@ -330,9 +352,14 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel>{t("Status")}</InputLabel> <InputLabel>{t("Status")}</InputLabel>
<Select <Select
value={searchStatus}
value={searchFilters.status}
label={t("Status")} label={t("Status")}
onChange={(e) => setSearchStatus(e.target.value)}
onChange={(e) =>
onSearchFiltersChange({
...searchFilters,
status: e.target.value,
})
}
> >
<MenuItem value="All">{t("All")}</MenuItem> <MenuItem value="All">{t("All")}</MenuItem>
{statusOptions.map((status) => ( {statusOptions.map((status) => (
@@ -347,17 +374,27 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
<TextField <TextField
fullWidth fullWidth
label={t("Area")} label={t("Area")}
value={searchArea}
onChange={(e) => setSearchArea(e.target.value)}
value={searchFilters.area}
onChange={(e) =>
onSearchFiltersChange({
...searchFilters,
area: e.target.value,
})
}
/> />
</Grid> </Grid>
<Grid item xs={12} md={6}> <Grid item xs={12} md={6}>
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel>{t("Store ID")}</InputLabel> <InputLabel>{t("Store ID")}</InputLabel>
<Select <Select
value={searchStoreId}
value={searchFilters.storeId}
label={t("Store ID")} label={t("Store ID")}
onChange={(e) => setSearchStoreId(e.target.value)}
onChange={(e) =>
onSearchFiltersChange({
...searchFilters,
storeId: e.target.value,
})
}
> >
<MenuItem value="All">{t("All")}</MenuItem> <MenuItem value="All">{t("All")}</MenuItem>
{storeIdOptions.map((storeId) => ( {storeIdOptions.map((storeId) => (
@@ -449,7 +486,7 @@ const PickerCardList: React.FC<PickerCardListProps> = ({
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}> <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
{t("Control Time")}: <TimeDisplay startTime={session.startTime} endTime={session.endTime} /> {t("Control Time")}: <TimeDisplay startTime={session.startTime} endTime={session.endTime} />
</Typography> </Typography>
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>{t("Total Item Number")}: {session.totalItemNumber}</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>{t("Total Item Kind Number")}: {session.totalItemNumber}</Typography>
</CardContent> </CardContent>




+ 14
- 0
src/components/StockTakeManagement/StockTakeTab.tsx Datei anzeigen

@@ -5,11 +5,19 @@ import { useState, useCallback, useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { AllPickedStockTakeListReponse, getLatestApproverStockTakeHeader } from "@/app/api/stockTake/actions"; import { AllPickedStockTakeListReponse, getLatestApproverStockTakeHeader } from "@/app/api/stockTake/actions";
import PickerCardList from "./PickerCardList"; import PickerCardList from "./PickerCardList";
import type { PickerCardListFilters } from "./PickerCardList";
import PickerStockTake from "./PickerStockTake"; import PickerStockTake from "./PickerStockTake";
import PickerReStockTake from "./PickerReStockTake"; import PickerReStockTake from "./PickerReStockTake";
import ApproverStockTakeAll from "./ApproverStockTakeAll"; import ApproverStockTakeAll from "./ApproverStockTakeAll";


type ViewScope = "picker" | "approver-all"; type ViewScope = "picker" | "approver-all";
const DEFAULT_PICKER_CARD_LIST_FILTERS: PickerCardListFilters = {
sectionDescription: "All",
stockTakeSession: "",
status: "All",
area: "",
storeId: "All",
};


const StockTakeTab: React.FC = () => { const StockTakeTab: React.FC = () => {
const { t } = useTranslation(["inventory", "common"]); const { t } = useTranslation(["inventory", "common"]);
@@ -22,6 +30,8 @@ const StockTakeTab: React.FC = () => {
/** 從卡片列表進入明細後返回時保留分頁 */ /** 從卡片列表進入明細後返回時保留分頁 */
const [pickerListPage, setPickerListPage] = useState(0); const [pickerListPage, setPickerListPage] = useState(0);
const [pickerListPageSize] = useState(6); const [pickerListPageSize] = useState(6);
const [pickerSearchFilters, setPickerSearchFilters] = useState<PickerCardListFilters>(DEFAULT_PICKER_CARD_LIST_FILTERS);
const [pickerAppliedFilters, setPickerAppliedFilters] = useState<PickerCardListFilters>(DEFAULT_PICKER_CARD_LIST_FILTERS);
const [snackbar, setSnackbar] = useState<{ const [snackbar, setSnackbar] = useState<{
open: boolean; open: boolean;
message: string; message: string;
@@ -127,6 +137,10 @@ const StockTakeTab: React.FC = () => {
page={pickerListPage} page={pickerListPage}
pageSize={pickerListPageSize} pageSize={pickerListPageSize}
onListPageChange={setPickerListPage} onListPageChange={setPickerListPage}
searchFilters={pickerSearchFilters}
appliedFilters={pickerAppliedFilters}
onSearchFiltersChange={setPickerSearchFilters}
onAppliedFiltersChange={setPickerAppliedFilters}
onCardClick={(session) => { onCardClick={(session) => {
setViewScope("picker"); setViewScope("picker");
handleCardClick(session); handleCardClick(session);


+ 7
- 6
src/i18n/zh/inventory.json Datei anzeigen

@@ -26,7 +26,7 @@
"Back to List": "返回列表", "Back to List": "返回列表",
"Start Stock Take Date": "盤點日期", "Start Stock Take Date": "盤點日期",
"Record Status": "記錄狀態", "Record Status": "記錄狀態",
"Stock take record status updated to not match": "盤點記錄狀態更新為數值不符",
"Stock take record status updated to not match": "盤點記錄狀態更新為要求重點",
"available": "可用", "available": "可用",
"Issue Qty": "問題數量", "Issue Qty": "問題數量",
"tke": "盤點", "tke": "盤點",
@@ -48,8 +48,8 @@
"Batch Save All": "批量保存所有", "Batch Save All": "批量保存所有",
"Batch Submit All": "批量提交所有", "Batch Submit All": "批量提交所有",
"Batch Save All": "批量保存所有", "Batch Save All": "批量保存所有",
"not match": "數值不符",
"Not Match": "數值不符",
"not match": "要求重點",
"Not Match": "要求重點",
"Pass": "已盤點", "Pass": "已盤點",
"Area": "區域", "Area": "區域",
@@ -68,6 +68,7 @@
"ReStockTake": "重新盤點", "ReStockTake": "重新盤點",
"Stock Taker": "盤點員", "Stock Taker": "盤點員",
"Total Item Number": "貨品數量", "Total Item Number": "貨品數量",
"Total Item Kind Number": "貨品種類數量",
"Please enter QTY and Bad QTY": "請輸入盤點數量和不良數量", "Please enter QTY and Bad QTY": "請輸入盤點數量和不良數量",
"Available QTY cannot be negative": "可用數量不能為負數", "Available QTY cannot be negative": "可用數量不能為負數",
"Start Time": "開始時間", "Start Time": "開始時間",
@@ -99,7 +100,7 @@
"book qty": "帳面庫存", "book qty": "帳面庫存",
"start time": "開始時間", "start time": "開始時間",
"end time": "結束時間", "end time": "結束時間",
"notmatch": "數值不符",
"notmatch": "要求重點",
"Only Variance": "僅差異", "Only Variance": "僅差異",
"Control Time": "操作時間", "Control Time": "操作時間",
"Batch approver save completed: {{success}} success, {{errors}} errors": "批次審核儲存完成:成功 {{success}} 筆,錯誤 {{errors}} 筆", "Batch approver save completed: {{success}} success, {{errors}} errors": "批次審核儲存完成:成功 {{success}} 筆,錯誤 {{errors}} 筆",
@@ -110,8 +111,8 @@
"pending": "待處理", "pending": "待處理",
"Last Stock Take Date": "上次盤點日期", "Last Stock Take Date": "上次盤點日期",
"Remark": "備註", "Remark": "備註",
"notMatch": "數值不符",
"notMatch": "數值不符",
"notMatch": "要求重點",
"notMatch": "要求重點",
"Stock take record saved successfully": "盤點記錄保存成功", "Stock take record saved successfully": "盤點記錄保存成功",
"View Details": "查看詳細", "View Details": "查看詳細",
"Input": "輸入", "Input": "輸入",


Laden…
Abbrechen
Speichern