Fix KOC resource fuzzy filters
This commit is contained in:
@@ -1377,8 +1377,8 @@ function ResourcesPage({
|
|||||||
}) {
|
}) {
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
const [platformFilter, setPlatformFilter] = useState("全部平台");
|
const [platformFilter, setPlatformFilter] = useState("全部平台");
|
||||||
const [ipFilter, setIpFilter] = useState("全部IP地区");
|
const [ipFilter, setIpFilter] = useState("");
|
||||||
const [sourceFilter, setSourceFilter] = useState("全部合作来源");
|
const [sourceFilter, setSourceFilter] = useState("");
|
||||||
const resourceAccounts = useMemo(() => {
|
const resourceAccounts = useMemo(() => {
|
||||||
const deliveriesByAccount = new Map<string, Distribution[]>();
|
const deliveriesByAccount = new Map<string, Distribution[]>();
|
||||||
distributions.forEach((distribution) => {
|
distributions.forEach((distribution) => {
|
||||||
@@ -1430,31 +1430,37 @@ function ResourcesPage({
|
|||||||
);
|
);
|
||||||
const filteredAccounts = useMemo(() => {
|
const filteredAccounts = useMemo(() => {
|
||||||
const keyword = query.trim().toLocaleLowerCase("zh-CN");
|
const keyword = query.trim().toLocaleLowerCase("zh-CN");
|
||||||
|
const ipKeyword = ipFilter.trim().toLocaleLowerCase("zh-CN");
|
||||||
|
const sourceKeyword = sourceFilter.trim().toLocaleLowerCase("zh-CN");
|
||||||
return resourceAccounts.filter(({ account, sources }) => {
|
return resourceAccounts.filter(({ account, sources }) => {
|
||||||
const searchable = `${account.nickname} ${account.public_account_id}`.toLocaleLowerCase(
|
const searchable = `${account.nickname} ${account.public_account_id}`.toLocaleLowerCase(
|
||||||
"zh-CN",
|
"zh-CN",
|
||||||
);
|
);
|
||||||
|
const ipLocation = (account.ip_location || "待识别").toLocaleLowerCase(
|
||||||
|
"zh-CN",
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
(!keyword || searchable.includes(keyword)) &&
|
(!keyword || searchable.includes(keyword)) &&
|
||||||
(platformFilter === "全部平台" ||
|
(platformFilter === "全部平台" ||
|
||||||
account.platform === platformFilter) &&
|
account.platform === platformFilter) &&
|
||||||
(ipFilter === "全部IP地区" ||
|
(!ipKeyword || ipLocation.includes(ipKeyword)) &&
|
||||||
(account.ip_location || "待识别") === ipFilter) &&
|
(!sourceKeyword ||
|
||||||
(sourceFilter === "全部合作来源" ||
|
sources.some((source) =>
|
||||||
sources.includes(sourceFilter))
|
source.toLocaleLowerCase("zh-CN").includes(sourceKeyword),
|
||||||
|
))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}, [ipFilter, platformFilter, query, resourceAccounts, sourceFilter]);
|
}, [ipFilter, platformFilter, query, resourceAccounts, sourceFilter]);
|
||||||
const hasActiveFilters =
|
const hasActiveFilters =
|
||||||
Boolean(query.trim()) ||
|
Boolean(query.trim()) ||
|
||||||
platformFilter !== "全部平台" ||
|
platformFilter !== "全部平台" ||
|
||||||
ipFilter !== "全部IP地区" ||
|
Boolean(ipFilter.trim()) ||
|
||||||
sourceFilter !== "全部合作来源";
|
Boolean(sourceFilter.trim());
|
||||||
const clearFilters = () => {
|
const clearFilters = () => {
|
||||||
setQuery("");
|
setQuery("");
|
||||||
setPlatformFilter("全部平台");
|
setPlatformFilter("全部平台");
|
||||||
setIpFilter("全部IP地区");
|
setIpFilter("");
|
||||||
setSourceFilter("全部合作来源");
|
setSourceFilter("");
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="stack">
|
<div className="stack">
|
||||||
@@ -1494,7 +1500,7 @@ function ResourcesPage({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="resource-toolbar">
|
<div className="resource-toolbar">
|
||||||
<label className="resource-search">
|
<div className="resource-search">
|
||||||
<span aria-hidden="true">⌕</span>
|
<span aria-hidden="true">⌕</span>
|
||||||
<input
|
<input
|
||||||
aria-label="搜索账号名称或账号ID"
|
aria-label="搜索账号名称或账号ID"
|
||||||
@@ -1503,23 +1509,37 @@ function ResourcesPage({
|
|||||||
type="search"
|
type="search"
|
||||||
value={query}
|
value={query}
|
||||||
/>
|
/>
|
||||||
</label>
|
</div>
|
||||||
<select
|
<div className="resource-filter-search">
|
||||||
aria-label="按IP地区筛选"
|
<span aria-hidden="true">⌕</span>
|
||||||
onChange={(event) => setIpFilter(event.target.value)}
|
<input
|
||||||
value={ipFilter}
|
aria-label="模糊搜索IP地区"
|
||||||
>
|
list="resource-ip-options"
|
||||||
<option>全部IP地区</option>
|
onChange={(event) => setIpFilter(event.target.value)}
|
||||||
{ipOptions.map((ip) => <option key={ip}>{ip}</option>)}
|
placeholder="搜索IP地区"
|
||||||
</select>
|
type="search"
|
||||||
<select
|
value={ipFilter}
|
||||||
aria-label="按合作来源筛选"
|
/>
|
||||||
onChange={(event) => setSourceFilter(event.target.value)}
|
<datalist id="resource-ip-options">
|
||||||
value={sourceFilter}
|
{ipOptions.map((ip) => <option key={ip} value={ip} />)}
|
||||||
>
|
</datalist>
|
||||||
<option>全部合作来源</option>
|
</div>
|
||||||
{sourceOptions.map((source) => <option key={source}>{source}</option>)}
|
<div className="resource-filter-search">
|
||||||
</select>
|
<span aria-hidden="true">⌕</span>
|
||||||
|
<input
|
||||||
|
aria-label="模糊搜索合作来源"
|
||||||
|
list="resource-source-options"
|
||||||
|
onChange={(event) => setSourceFilter(event.target.value)}
|
||||||
|
placeholder="搜索合作来源"
|
||||||
|
type="search"
|
||||||
|
value={sourceFilter}
|
||||||
|
/>
|
||||||
|
<datalist id="resource-source-options">
|
||||||
|
{sourceOptions.map((source) => (
|
||||||
|
<option key={source} value={source} />
|
||||||
|
))}
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
className="resource-clear-button"
|
className="resource-clear-button"
|
||||||
disabled={!hasActiveFilters}
|
disabled={!hasActiveFilters}
|
||||||
|
|||||||
@@ -1440,10 +1440,12 @@ a {
|
|||||||
|
|
||||||
.resource-search {
|
.resource-search {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
min-width: 230px;
|
min-width: 230px;
|
||||||
flex: 1 1 280px;
|
flex: 1 1 280px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
margin: 0;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
border: 1px solid #dfe6e2;
|
border: 1px solid #dfe6e2;
|
||||||
@@ -1451,17 +1453,21 @@ a {
|
|||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource-search:focus-within {
|
.resource-search:focus-within,
|
||||||
|
.resource-filter-search:focus-within {
|
||||||
border-color: #74b79f;
|
border-color: #74b79f;
|
||||||
box-shadow: 0 0 0 3px rgb(31 143 107 / 0.08);
|
box-shadow: 0 0 0 3px rgb(31 143 107 / 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource-search > span {
|
.resource-search > span,
|
||||||
|
.resource-filter-search > span {
|
||||||
color: #83918c;
|
color: #83918c;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource-search input {
|
.resource-search input,
|
||||||
|
.resource-filter-search input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -1471,14 +1477,16 @@ a {
|
|||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource-toolbar > select {
|
.resource-filter-search {
|
||||||
width: 160px;
|
display: flex;
|
||||||
|
flex: 0 1 180px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 7px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
padding: 0 31px 0 11px;
|
padding: 0 11px;
|
||||||
border: 1px solid #dfe6e2;
|
border: 1px solid #dfe6e2;
|
||||||
border-radius: 9px;
|
border-radius: 9px;
|
||||||
background-color: white;
|
background: white;
|
||||||
font-size: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource-clear-button {
|
.resource-clear-button {
|
||||||
@@ -2991,7 +2999,7 @@ label small {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.resource-search,
|
.resource-search,
|
||||||
.resource-toolbar > select {
|
.resource-filter-search {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,8 +258,10 @@ test("filters and exports the current KOC resource result set", async () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
assert.match(adminApp, /搜索账号名称 \/ 账号ID/);
|
assert.match(adminApp, /搜索账号名称 \/ 账号ID/);
|
||||||
assert.match(adminApp, /全部IP地区/);
|
assert.match(adminApp, /搜索IP地区/);
|
||||||
assert.match(adminApp, /全部合作来源/);
|
assert.match(adminApp, /搜索合作来源/);
|
||||||
|
assert.match(adminApp, /ipLocation\.includes\(ipKeyword\)/);
|
||||||
|
assert.match(adminApp, /includes\(sourceKeyword\)/);
|
||||||
assert.match(adminApp, /导出筛选结果/);
|
assert.match(adminApp, /导出筛选结果/);
|
||||||
assert.match(adminApp, /filteredAccounts\.map\(\(item\) => item\.account\.id\)/);
|
assert.match(adminApp, /filteredAccounts\.map\(\(item\) => item\.account\.id\)/);
|
||||||
assert.match(exportRoute, /小红书号\/抖音号/);
|
assert.match(exportRoute, /小红书号\/抖音号/);
|
||||||
|
|||||||
Reference in New Issue
Block a user