Skip to content

Commit

Permalink
[Filters] revamp style
Browse files Browse the repository at this point in the history
- remove toggle filter state
- delete buttons more visible
- simplified dom structure + spacing review
- decrease code preview size
relates #164
  • Loading branch information
paulgirard committed Jun 14, 2024
1 parent e3fb0a0 commit c211f00
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 80 deletions.
18 changes: 18 additions & 0 deletions src/components/GraphFilters/FilteredGraphSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { FC } from "react";
import { useTranslation } from "react-i18next";

import { filteredGraphsAtom } from "../../core/graph";
import { useReadAtom } from "../../core/utils/atoms";

export const FilteredGraphSummary: FC<{ filterIndex: number }> = ({ filterIndex }) => {
const { t } = useTranslation();
const filteredGraphs = useReadAtom(filteredGraphsAtom);
const relatedGraph = filteredGraphs[filterIndex]?.graph;

return (
<div className="small text-muted">
{relatedGraph.order} {t("graph.model.nodes", { count: relatedGraph.order })}, {relatedGraph.size}{" "}
{t("graph.model.edges", { count: relatedGraph.size })}
</div>
);
};
20 changes: 11 additions & 9 deletions src/components/GraphFilters/RangeFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { RangeFilterType } from "../../core/filters/types";
import { inRangeIncluded } from "../../core/filters/utils";
import { graphDatasetAtom, parentFilteredGraphAtom } from "../../core/graph";
import { useReadAtom } from "../../core/utils/atoms";
import { FilteredGraphSummary } from "./FilteredGraphSummary";
import { findRanges, shortenNumber } from "./utils";

interface RangeValue {
Expand Down Expand Up @@ -205,7 +206,7 @@ export const RangeFilterEditor: FC<{ filter: RangeFilterType }> = ({ filter }) =
replaceCurrentFilter({ ...filter, keepMissingValues: e.target.checked });
}}
/>
<label className="from-check-label" htmlFor="keepMissingValues">
<label className="from-check-label small" htmlFor="keepMissingValues">
{t("filters.keepMissingValues")}
</label>
</div>
Expand All @@ -215,25 +216,26 @@ export const RangeFilterEditor: FC<{ filter: RangeFilterType }> = ({ filter }) =

export const RangeFilter: FC<{
filter: RangeFilterType;
filterIndex: number;
active?: boolean;
editMode?: boolean;
}> = ({ filter, editMode }) => {
}> = ({ filter, editMode, filterIndex, active }) => {
const { t } = useTranslation();

return (
<div>
<>
<div className="fs-5">
{filter.field} ({t(`graph.model.${filter.itemType}`)})
</div>
{editMode ? (
<RangeFilterEditor filter={filter} />
) : (
<div>
<span className="fs-5">
{!editMode && (
<div className="flex-grow-1">
<span className="fs-6">
{filter.min ? `${filter.min}` : "∞"} - {filter.max ? `${filter.max}` : "∞"}
</span>{" "}
</div>
)}
</div>
{active && <FilteredGraphSummary filterIndex={filterIndex} />}
{editMode && <RangeFilterEditor filter={filter} />}
</>
);
};
6 changes: 5 additions & 1 deletion src/components/GraphFilters/ScriptFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useModal } from "../../core/modals";
import { useReadAtom } from "../../core/utils/atoms";
import { FunctionEditorModal } from "../../views/graphPage/modals/FunctionEditorModal";
import { CodeEditorIcon } from "../common-icons";
import { FilteredGraphSummary } from "./FilteredGraphSummary";

// eslint-disable-next-line no-new-func
const nodeFilterCustomFn = new Function(`return (
Expand All @@ -38,9 +39,10 @@ const SCRIPT_JS_DOC = `/**

export const ScriptFilter: FC<{
filter: ScriptFilterType;
filterIndex: number;
active?: boolean;
editMode?: boolean;
}> = ({ filter, editMode }) => {
}> = ({ filter, editMode, active, filterIndex }) => {
const { t } = useTranslation();
const { openModal } = useModal();
const { replaceCurrentFilter } = useFiltersActions();
Expand All @@ -51,6 +53,7 @@ export const ScriptFilter: FC<{
<div className="fs-5">
{t("filters.script")} ({t(`graph.model.${filter.itemType}`)})
</div>
{active && <FilteredGraphSummary filterIndex={filterIndex} />}
<div className="position-relative">
{filter.script && (
<>
Expand All @@ -60,6 +63,7 @@ export const ScriptFilter: FC<{
<div className="filler-fade-out position-absolute bottom-0"></div>
</>
)}

{editMode && (
<div className={cx(filter.script && "bottom-0 position-absolute w-100")}>
<button
Expand Down
21 changes: 12 additions & 9 deletions src/components/GraphFilters/TermsFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { graphDatasetAtom, parentFilteredGraphAtom } from "../../core/graph";
import { useReadAtom } from "../../core/utils/atoms";
import { toString } from "../../core/utils/casting";
import { DEFAULT_SELECT_PROPS } from "../consts";
import { FilteredGraphSummary } from "./FilteredGraphSummary";

const TermsFilterEditor: FC<{ filter: TermsFilterType }> = ({ filter }) => {
const parentGraph = useReadAtom(parentFilteredGraphAtom);
Expand All @@ -29,7 +30,7 @@ const TermsFilterEditor: FC<{ filter: TermsFilterType }> = ({ filter }) => {
}, [filter, parentGraph]);

return (
<>
<div className="my-3 w-100">
<Select
{...DEFAULT_SELECT_PROPS}
value={filter.terms ? Array.from(filter.terms).map((t) => ({ label: t, value: t })) : []}
Expand All @@ -53,36 +54,38 @@ const TermsFilterEditor: FC<{ filter: TermsFilterType }> = ({ filter }) => {
replaceCurrentFilter({ ...filter, keepMissingValues: e.target.checked });
}}
/>
<label className="from-check-label" htmlFor="keepMissingValues">
<label className="from-check-label small" htmlFor="keepMissingValues">
{t("filters.keepMissingValues")}
</label>
</div>
</>
</div>
);
};

export const TermsFilter: FC<{
filter: TermsFilterType;
filterIndex: number;
active?: boolean;
editMode?: boolean;
}> = ({ filter, editMode }) => {
}> = ({ filter, editMode, filterIndex, active }) => {
const { t, i18n } = useTranslation();

//TODO: adapt language
const listFormatter = new Intl.ListFormat(i18n.language, { style: "long", type: "conjunction" });

return (
<div>
<>
<div className="fs-5">
{filter.field} ({t(`graph.model.${filter.itemType}`)})
</div>
{editMode ? (
<TermsFilterEditor filter={filter} />
) : (

{active && <FilteredGraphSummary filterIndex={filterIndex} />}
{!editMode && (
<div>
<span className="fs-5">{filter.terms ? listFormatter.format(filter.terms) : t("common.all")}</span>
</div>
)}
</div>
{editMode && <TermsFilterEditor filter={filter} />}
</>
);
};
91 changes: 33 additions & 58 deletions src/components/GraphFilters/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import cx from "classnames";
import { FC, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { BsCheckSquare } from "react-icons/bs";
import { CgRemoveR } from "react-icons/cg";
import { FiEdit } from "react-icons/fi";
import { RiFilterLine, RiFilterOffLine } from "react-icons/ri";

import { useFilters, useFiltersActions, useGraphDataset } from "../../core/context/dataContexts";
import { FilterType } from "../../core/filters/types";
import { filteredGraphsAtom } from "../../core/graph";
import { useReadAtom } from "../../core/utils/atoms";
import { GraphIcon } from "../common-icons";
import { FilterCreator } from "./FilterCreator";
import { RangeFilter } from "./RangeFilter";
import { ScriptFilter } from "./ScriptFilter";
Expand All @@ -24,8 +18,6 @@ const FilterInStack: FC<{
const filters = useFilters();
const { openPastFilter, deleteFutureFilter, deletePastFilter, openFutureFilter } = useFiltersActions();
const { t } = useTranslation();
const filteredGraphs = useReadAtom(filteredGraphsAtom);
const relatedGraph = filteredGraphs[filterIndex]?.graph;

const editMode = !!active && filterIndex === filters.past.length - 1;
// internalEditMode is an internal state which is used to mimic edit/confirm state for the last filter
Expand All @@ -48,60 +40,42 @@ const FilterInStack: FC<{
} else openFutureFilter(filterIndex);
}}
>
<div className="d-flex justify-content-between align-items-start">
<div className=" button-container">
{/* filter downstream ongoing edition => disabled */}
{!active && <RiFilterOffLine title={t("filters.desactivated").toString()} className="icon" />}
{active && filterIndex !== filters.past.length - 1 && (
<RiFilterLine title={t("filters.activated").toString()} className="icon" />
)}
{/* upstream filters => can be edited only if no other edit ongoing*/}
{active && filterIndex === filters.past.length - 1 && (
<div
title={filterIndex === filters.past.length - 1 ? undefined : t("filters.no_concurrent_edit").toString()}
>
<button
className="btn btn-icon"
onClick={(e) => {
e.stopPropagation();
setInternalEditMode(!internalEditMode);
}}
title={t("common.edit").toString()}
disabled={filterIndex !== filters.past.length - 1}
>
{internalEditMode ? <BsCheckSquare /> : <FiEdit />}
</button>
</div>
)}
</div>
<div className="flex-grow-1">
{filter.type === "range" && (
<RangeFilter filter={filter} editMode={editMode && internalEditMode} active={active} />
)}
{filter.type === "terms" && (
<TermsFilter filter={filter} editMode={editMode && internalEditMode} active={active} />
)}
{filter.type === "script" && (
<ScriptFilter filter={filter} editMode={editMode && internalEditMode} active={active} />
)}
{active && relatedGraph && (
<div className="small text-muted">
{relatedGraph.order} {t("graph.model.nodes", { count: relatedGraph.order })}, {relatedGraph.size}{" "}
{t("graph.model.edges", { count: relatedGraph.size })}
</div>
)}
</div>
<div className=" button-container">
<div className="d-flex flex-column justify-content-between align-items-start">
{filter.type === "range" && (
<RangeFilter
filter={filter}
filterIndex={filterIndex}
editMode={editMode && internalEditMode}
active={active}
/>
)}
{filter.type === "terms" && (
<TermsFilter
filter={filter}
filterIndex={filterIndex}
editMode={editMode && internalEditMode}
active={active}
/>
)}
{filter.type === "script" && (
<ScriptFilter
filter={filter}
filterIndex={filterIndex}
editMode={editMode && internalEditMode}
active={active}
/>
)}
<div className="w-100 d-flex justify-content-center align-items-center">
<button
className="btn btn-icon"
className="btn btn-outline-dark border-0"
onClick={(e) => {
e.stopPropagation();
if (active) deletePastFilter(filterIndex);
else deleteFutureFilter(filterIndex);
}}
title={t("common.remove").toString()}
>
<CgRemoveR />
<CgRemoveR /> {t("common.remove").toString()}
</button>
</div>
</div>
Expand Down Expand Up @@ -129,14 +103,15 @@ const GraphFilters: FC = () => {
return (
<div className="panel-block-grow">
<div
className={cx("filter-item d-flex align-items-center", filters.past.length !== 0 && "cursor-pointer")}
className={cx(
"filter-item d-flex align-items-center",
filters.past.length !== 0 && "cursor-pointer",
filters.past.length === 0 && "edited",
)}
onClick={() => {
if (filters.past.length !== 0) closeAllPastFilters();
}}
>
<div className="button-container">
<GraphIcon className="icon" />
</div>
<div>
<div className="fs-5">{t("filters.full_graph")}</div>
<div className="small text-muted">
Expand Down
2 changes: 1 addition & 1 deletion src/styles/_filters.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
position: relative;

@extend .mt-2;
@extend .px-1;
@extend .px-2;
@extend .py-2;
&.inactive {
@extend .text-muted;
Expand Down
5 changes: 3 additions & 2 deletions src/styles/_highlightjs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

div.code-thumb {
font-size: 10px;
min-height: 100px;
max-height: 150px;
min-height: 80px;
max-height: 120px;
overflow: hidden;
pre {
margin-bottom: 0;
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
Expand Down

0 comments on commit c211f00

Please sign in to comment.