@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 vote down vote up
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 vote down vote up
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>
    </>
  );
}