@fortawesome/free-solid-svg-icons#faSort TypeScript Examples
The following examples show how to use
@fortawesome/free-solid-svg-icons#faSort.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ScriptsPage.tsx From apps with MIT License | 4 votes |
ScriptsPage = ({ region, path }: { region: Region; path: string }) => {
const history = useHistory(),
location = useLocation(),
searchParams = new URLSearchParams(location.search),
thisStateCache = stateCache.get(region),
[query, setQuery] = useState(searchParams.get("query") ?? thisStateCache?.query ?? undefined),
[scriptFileName, setScriptFileName] = useState(
searchParams.get("scriptFileName") ?? thisStateCache?.scriptFileName ?? undefined
),
[scripts, setScripts] = useState<Script.ScriptSearchResult[]>(thisStateCache?.scripts ?? []),
[error, setError] = useState<AxiosError | undefined>(undefined),
[searching, setSearching] = useState(false),
[searched, setSearched] = useState(thisStateCache?.searched ?? false),
[resultSort, setResultSort] = useState<ScriptResultSort>("Score");
const search = (query: string, scriptFileName?: string) => {
setSearching(true);
Api.searchScript(query, scriptFileName)
.then((r) => {
setSearched(true);
setScripts(r);
setSearching(false);
})
.catch((e) => setError(e));
};
const searchButton = (query?: string, scriptFileName?: string) => {
if (query === undefined || query.trim() === "") {
alert("Please enter a query");
} else {
search(query, scriptFileName);
history.replace(`/${region}/${path}?${getQueryString(query, scriptFileName)}`);
}
};
useEffect(() => {
// when switching between regions using the navbar
Manager.setRegion(region);
if (stateCache.has(region)) {
const queryString = getQueryString(stateCache.get(region)?.query);
history.replace(`/${region}/${path}?${queryString}`);
}
}, [region, path, history]);
useEffect(() => {
if (!stateCache.has(region) && query !== undefined && query !== "") {
// for first run if URL query string is not empty
search(query, scriptFileName);
}
}, [region, query, scriptFileName]);
useEffect(() => {
stateCache.set(region, { query, scriptFileName, scripts, searched });
}, [region, query, scriptFileName, scripts, searched]);
document.title = `[${region}] Scripts - Atlas Academy DB`;
if (error !== undefined) {
history.replace(`/${region}/${path}`);
return (
<div style={{ textAlign: "center" }}>
<ErrorStatus error={error} />
<Button
variant={"primary"}
onClick={() => {
setError(undefined);
setSearching(false);
}}
>
Redo the Search
</Button>
</div>
);
}
return (
<>
{searching ? <Loading /> : null}
<h1>Scripts Search</h1>
<div className="my-3">
Supports
<ul>
<li>
<code>this OR that</code>
</li>
<li>
<code>this -but -not -that</code>
</li>
<li>
<code>"this exact phrase"</code>
</li>
<li>
<code>prefix*</code>
</li>
</ul>
<a
href="https://groonga.org/docs/reference/grn_expr/query_syntax.html"
target="_blank"
rel="noreferrer"
>
Syntax Reference
</a>{" "}
(Queries starting with <code>column:</code> are not supported).
</div>
<form
onSubmit={(ev: React.FormEvent) => {
ev.preventDefault();
searchButton(query);
}}
>
<Form.Group>
<Form.Label>Search Query</Form.Label>
<Form.Control
value={query ?? ""}
onChange={(ev) => {
setQuery(ev.target.value !== "" ? ev.target.value : undefined);
}}
/>
</Form.Group>
<Form.Group>
<Form.Label>Script File Name</Form.Label>
<Form.Control
value={scriptFileName ?? ""}
onChange={(ev) => {
setScriptFileName(ev.target.value !== "" ? ev.target.value : undefined);
}}
/>
<Form.Text className="text-muted">
The script ID should contain this string. For example 30001 for LB1, 94036 for Ooku.
</Form.Text>
</Form.Group>
<Button variant={"primary"} onClick={() => searchButton(query, scriptFileName)}>
Search <FontAwesomeIcon icon={faSearch} />
</Button>{" "}
</form>
<hr />
{searched ? (
<h5>
Found{" "}
<b>
{scripts.length}
{scripts.length === 50 ? "+" : ""}
</b>{" "}
result
{scripts.length > 1 ? "s" : ""}
</h5>
) : null}
{scripts.length > 0 ? (
<>
<Table responsive>
<thead>
<tr>
<th className="text-nowrap align-bottom">
<Button
variant=""
className="py-0 border-0 align-bottom"
onClick={() => {
switch (resultSort) {
case "Score":
setResultSort("ScriptIdAscending");
break;
case "ScriptIdAscending":
setResultSort("ScriptIdDescending");
break;
case "ScriptIdDescending":
setResultSort("Score");
break;
}
}}
>
{resultSort === "Score" ? (
<FontAwesomeIcon
icon={faSort}
title="Sorted by how many keywords are included"
/>
) : resultSort === "ScriptIdAscending" ? (
<FontAwesomeIcon icon={faSortUp} title="Sorted by Script ID (Ascending)" />
) : (
<FontAwesomeIcon
icon={faSortDown}
title="Sorted by Script ID (Descending)"
/>
)}
</Button>
Script ID
</th>
<th>Snippet</th>
</tr>
</thead>
<tbody>
{scripts
.sort((a, b) => {
switch (resultSort) {
case "Score":
return b.score - a.score || a.scriptId.localeCompare(b.scriptId, "en");
case "ScriptIdAscending":
return a.scriptId.localeCompare(b.scriptId, "en");
case "ScriptIdDescending":
return b.scriptId.localeCompare(a.scriptId, "en");
default:
return 0;
}
})
.map((script) => (
<tr key={script.scriptId}>
<td>
<ScriptDescriptor
region={region}
scriptId={script.scriptId}
scriptType=""
/>
</td>
<td
dangerouslySetInnerHTML={{
__html: script.snippets[0],
}}
></td>
</tr>
))}
</tbody>
</Table>
</>
) : null}
</>
);
}
Example #2
Source File: ProblemPage.tsx From cftracker with MIT License | 4 votes |
ProblemPage = () => {
const state: RootStateType = useSelector((state) => state) as RootStateType;
const history = useHistory();
const SORT_BY_RATING = 1,
SORT_BY_SOLVE = 2,
ASCENDING = 0,
DESCENDING = 1;
enum ProblemSave {
PROBLEM_SOLVE_STATUS = "PROBLEM_SOLVE_STATUS",
PROBLEM_TAGS = "PROBLEM_TAGS",
PROBLEM_FILTER = "PROBLEM_FILTER",
}
const query = parseQuery(history.location.search.trim());
interface filt {
perPage: number;
minRating: number;
maxRating: number;
showUnrated: boolean;
minContestId: number;
maxContestId: number;
search: string;
}
const defaultFilt: filt = {
perPage: 100,
minRating: state.appState.minRating,
maxRating: state.appState.maxRating,
showUnrated: true,
minContestId: state.appState.minContestId,
maxContestId: state.appState.maxContestId,
search: SEARCH in query ? query[SEARCH] : "",
};
const [filter, setFilter] = useState<filt>(
getObj(ProblemSave.PROBLEM_FILTER, defaultFilt)
);
const SOLVEBUTTONS = [Verdict.SOLVED, Verdict.ATTEMPTED, Verdict.UNSOLVED];
const initFilterState = {
tags: getSet(ProblemSave.PROBLEM_TAGS, []),
sortBy: SORT_BY_SOLVE,
order: DESCENDING,
};
const [solveStatus, setSolveStatus] = useState(
getSet(ProblemSave.PROBLEM_SOLVE_STATUS, SOLVEBUTTONS)
);
const [problemList, setProblemList] = useState({ problems: [], error: "" });
const [tagList, setTagList] = useState({ tags: [] });
const [randomProblem, setRandomProblem] = useState(-1);
const [selected, setSelected] = useState(0);
const [filterState, setFilterState] = useState(initFilterState);
const [solved, setSolved] = useState(new Set<string>());
const [attempted, setAttempted] = useState(new Set<string>());
const filterProblem = (problem: Problem) => {
let containTags = false;
if (filterState.tags.size === 0) containTags = true;
else
for (let tag of problem.tags)
if (filterState.tags.has(tag)) {
containTags = true;
break;
}
let ratingInside =
problem.rating <= filter.maxRating && problem.rating >= filter.minRating;
let contestIdInside =
problem.contestId <= filter.maxContestId &&
problem.contestId >= filter.minContestId;
let status = solveStatus.has(getState(problem));
let searchIncluded = true;
let text = filter.search.toLowerCase().trim();
if (text.length)
searchIncluded =
problem.name.toLowerCase().includes(text) ||
problem.id.toLowerCase().includes(text);
return (
status && ratingInside && containTags && searchIncluded && contestIdInside
);
};
const getState = (problem: Problem) => {
if (solved.has(problem.getId())) return Verdict.SOLVED;
if (attempted.has(problem.getId())) return Verdict.ATTEMPTED;
return Verdict.UNSOLVED;
};
useEffect(() => {
saveObj(ProblemSave.PROBLEM_FILTER, filter);
if (filter.search.trim().length)
history.push({
pathname: Path.PROBLEMS,
search: "?" + SEARCH + "=" + filter.search.trim(),
});
else
history.push({
pathname: Path.PROBLEMS,
});
if (state.problemList.problems !== undefined) {
let newState = { problems: [] };
newState.problems = state.problemList.problems;
let used = new Set<string>();
newState.problems = newState.problems.filter((problem: Problem) => {
if (used.has(problem.getId())) return false;
return filterProblem(problem);
});
if (filterState.sortBy === SORT_BY_RATING)
newState.problems.sort(sortByRating);
else newState.problems.sort(sortBySolveCount);
if (filterState.order === DESCENDING) newState.problems.reverse();
let tags = [];
for (let tag of state.problemList.tags) tags.push(tag);
setTagList({ tags });
setProblemList({ ...problemList, problems: newState.problems });
}
setRandomProblem(-1);
setSelected(0);
}, [state, filterState, filter, filter.search, solveStatus]);
useEffect(() => {
let solv = new Set<string>();
let att = new Set<string>();
for (let submission of state.userSubmissions.submissions) {
if (submission.verdict === Verdict.OK)
solv.add(submission.contestId.toString() + submission.index);
else att.add(submission.contestId.toString() + submission.index);
}
setSolved(solv);
setAttempted(att);
}, [state.userSubmissions.submissions]);
const sortList = (sortBy) => {
if (filterState.sortBy === sortBy)
setFilterState({ ...filterState, order: filterState.order ^ 1 });
else
setFilterState({
...filterState,
...{
order: sortBy === SORT_BY_RATING ? ASCENDING : DESCENDING,
sortBy: sortBy,
},
});
};
const paginate = () => {
let lo = selected * filter.perPage;
let high = Math.min(problemList.problems.length, lo + filter.perPage);
if (lo > high) return [];
return problemList.problems.slice(lo, high);
};
const nuetral = () => {
return <FontAwesomeIcon icon={faSort} />;
};
const less = () => {
return <FontAwesomeIcon icon={faSortUp} />;
};
const greater = () => {
return <FontAwesomeIcon icon={faSortDown} />;
};
return (
<>
<div>
<Filter
search={filter.search}
searchName="problemSearch"
searchPlaceHolder="Problem Name or Id"
name="Problem"
onSearch={(e) => {
setFilter({ ...filter, search: e });
}}
length={problemList.problems.length}
perPage={filter.perPage}
selected={selected}
setRandom={(num) => {
setRandomProblem(num);
}}
theme={state.appState.theme}>
<CustomModal title="Filter" theme={state.appState.theme}>
<CheckList
items={SOLVEBUTTONS}
active={solveStatus}
name={"Solve Status"}
onClickSet={(newSet) => {
setSolveStatus(newSet);
saveSet(ProblemSave.PROBLEM_SOLVE_STATUS, newSet);
}}
theme={state.appState.theme}
/>
<InputRange
min={state.appState.minRating}
max={state.appState.maxRating}
minValue={filter.minRating}
maxValue={filter.maxRating}
theme={state.appState.theme}
name="Rating"
step={100}
minTitle="Set 0 to show Unrated Problems"
className="p-2 pb-0"
onMinChange={(num: number) => {
setFilter({ ...filter, minRating: num });
}}
onMaxChange={(num: number) => {
setFilter({ ...filter, maxRating: num });
}}
/>
<InputRange
min={state.appState.minContestId}
max={state.appState.maxContestId}
minValue={filter.minContestId}
maxValue={filter.maxContestId}
theme={state.appState.theme}
name="ContestId"
step={1}
className="p-2"
onMinChange={(num: number) => {
setFilter({ ...filter, minContestId: num });
}}
onMaxChange={(num: number) => {
setFilter({ ...filter, maxContestId: num });
}}
/>
<CheckList
items={tagList.tags}
active={filterState.tags}
name={"Tags"}
onClickSet={(newSet) => {
let myFilterState = { ...filterState };
myFilterState.tags = newSet;
setFilterState(myFilterState);
saveSet(ProblemSave.PROBLEM_TAGS, newSet);
}}
/>
</CustomModal>
</Filter>
<div className={"container p-0 pt-3 pb-3 " + state.appState.theme.bg}>
<div className={"h-100 text-center pb-3 " + state.appState.theme.bg}>
<table
className={
"table table-bordered m-0 " + state.appState.theme.table
}>
<thead className={state.appState.theme.thead}>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th
scope="col"
role="button"
onClick={() => sortList(SORT_BY_RATING)}>
<div className="d-flex justify-content-between">
<div>Rating</div>
<div>
{filterState.sortBy === SORT_BY_RATING
? filterState.order === ASCENDING
? less()
: greater()
: nuetral()}
</div>
</div>
</th>
<th
scope="col"
role="button"
onClick={() => sortList(SORT_BY_SOLVE)}>
<div className="d-flex justify-content-between">
<div>Solve Count</div>
<div>
{filterState.sortBy === SORT_BY_SOLVE
? filterState.order === ASCENDING
? less()
: greater()
: nuetral()}
</div>
</div>
</th>
</tr>
</thead>
<tbody className={state.appState.theme.bg}>
<ProblemList
problems={
randomProblem === -1
? paginate()
: [problemList.problems[randomProblem]]
}
solved={solved}
attempted={attempted}
perPage={filter.perPage}
pageSelected={selected}
theme={state.appState.theme}
/>
</tbody>
</table>
</div>
</div>
</div>
<footer className={"pt-2 " + state.appState.theme.bg}>
<Pagination
totalCount={problemList.problems.length}
perPage={filter.perPage}
selected={selected}
theme={state.appState.theme}
pageSelected={(e) => setSelected(e)}
pageSize={(num) => {
setFilter({ ...filter, perPage: num });
}}
/>
</footer>
</>
);
}