mirror of
https://github.com/XFox111/TabsAsideExtension.git
synced 2026-04-22 07:58:01 +03:00
58d8e864e0
* feat: add ability to hide collections #211 (#213) * feat: add ability to hide collections #211 * fix: hide/unhide collection label is swapped * fix: missing useCallback dependency * fix: add selected tabs to existing collection adds all tabs in current window #215 (#216) * fix: add selected tabs to existing collection adds all tabs in current window #215 * fix: force selected tabs only for adding tabs to groups * feat: compact collection view (#214) * feat: compact collection view #201 * loc: compact view localization * fix(loc): missing "color" translation in edit dialog * feat: add ability to edit saved tabs (#218) * feat: adds option to edit saved tabs #217 * loc: translations for #217 * build(deps): Bump the react group with 2 updates (#221) Bumps the react group with 2 updates: [react](https://github.com/facebook/react/tree/HEAD/packages/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom). Updates `react` from 19.2.1 to 19.2.3 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react) Updates `react-dom` from 19.2.1 to 19.2.3 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.2.3/packages/react-dom) --- updated-dependencies: - dependency-name: react dependency-version: 19.2.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: react - dependency-name: react-dom dependency-version: 19.2.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: react ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): Bump the deps group with 4 updates (#220) Bumps the deps group with 4 updates: [@fluentui/react-components](https://github.com/microsoft/fluentui), [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js), [eslint](https://github.com/eslint/eslint) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint). Updates `@fluentui/react-components` from 9.72.8 to 9.72.9 - [Release notes](https://github.com/microsoft/fluentui/releases) - [Commits](https://github.com/microsoft/fluentui/compare/@fluentui/react-components_v9.72.8...@fluentui/react-components_v9.72.9) Updates `@eslint/js` from 9.39.1 to 9.39.2 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/commits/v9.39.2/packages/js) Updates `eslint` from 9.39.1 to 9.39.2 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v9.39.1...v9.39.2) Updates `typescript-eslint` from 8.49.0 to 8.51.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.51.0/packages/typescript-eslint) --- updated-dependencies: - dependency-name: "@fluentui/react-components" dependency-version: 9.72.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: deps - dependency-name: "@eslint/js" dependency-version: 9.39.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: deps - dependency-name: eslint dependency-version: 9.39.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: deps - dependency-name: typescript-eslint dependency-version: 8.51.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: deps ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump version from 3.2.3 to 3.3.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
163 lines
6.0 KiB
TypeScript
163 lines
6.0 KiB
TypeScript
import CollectionView from "@/entrypoints/sidepanel/components/CollectionView";
|
|
import GroupView from "@/entrypoints/sidepanel/components/GroupView";
|
|
import { DndItem } from "@/entrypoints/sidepanel/hooks/useDndItem";
|
|
import CloudIssueMessages from "@/entrypoints/sidepanel/layouts/collections/messages/CloudIssueMessages";
|
|
import CtaMessage from "@/entrypoints/sidepanel/layouts/collections/messages/CtaMessage";
|
|
import filterCollections, { CollectionFilterType } from "@/entrypoints/sidepanel/utils/filterCollections";
|
|
import sortCollections from "@/entrypoints/sidepanel/utils/sortCollections";
|
|
import { track } from "@/features/analytics";
|
|
import useSettings from "@/hooks/useSettings";
|
|
import { CollectionItem } from "@/models/CollectionModels";
|
|
import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, MouseSensor, TouchSensor, useSensor, useSensors } from "@dnd-kit/core";
|
|
import { rectSortingStrategy, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
import { Body1, Button, Caption1, mergeClasses, Subtitle2 } from "@fluentui/react-components";
|
|
import { ArrowUndo20Regular, SearchInfo24Regular, Sparkle48Regular } from "@fluentui/react-icons";
|
|
import { ReactElement } from "react";
|
|
import TabView from "../../components/TabView";
|
|
import CollectionContext from "../../contexts/CollectionContext";
|
|
import { useCollections } from "../../contexts/CollectionsProvider";
|
|
import applyReorder from "../../utils/dnd/applyReorder";
|
|
import { collisionDetector } from "../../utils/dnd/collisionDetector";
|
|
import { snapHandleToCursor } from "../../utils/dnd/snapHandleToCursor";
|
|
import { useStyles_CollectionListView } from "./CollectionListView.styles";
|
|
import SearchBar from "./SearchBar";
|
|
import StorageCapacityIssueMessage from "./messages/StorageCapacityIssueMessage";
|
|
|
|
export default function CollectionListView(): ReactElement
|
|
{
|
|
const { tilesView, updateCollections, collections } = useCollections();
|
|
|
|
const [sortMode, setSortMode] = useSettings("sortMode");
|
|
const [query, setQuery] = useState<string>("");
|
|
const [colors, setColors] = useState<CollectionFilterType["colors"]>([]);
|
|
const [showHidden, setShowHidden] = useState<boolean>(false);
|
|
const [compactView] = useSettings("compactView");
|
|
|
|
const [active, setActive] = useState<DndItem | null>(null);
|
|
|
|
const sensors = useSensors(
|
|
useSensor(MouseSensor, { activationConstraint: { delay: 150, tolerance: 20 } }),
|
|
useSensor(TouchSensor, { activationConstraint: { delay: 300, tolerance: 20 } })
|
|
);
|
|
|
|
const resultList = useMemo(
|
|
() => sortCollections(filterCollections(collections, { query, colors, showHidden }), sortMode),
|
|
[query, colors, sortMode, collections, showHidden]
|
|
);
|
|
|
|
const cls = useStyles_CollectionListView();
|
|
|
|
const resetFilter = useCallback(() =>
|
|
{
|
|
setQuery("");
|
|
setColors([]);
|
|
setShowHidden(false);
|
|
}, []);
|
|
|
|
const updateFilter = useCallback((newColors: CollectionFilterType["colors"], newShowHidden: boolean) =>
|
|
{
|
|
setColors(newColors);
|
|
setShowHidden(newShowHidden);
|
|
}, []);
|
|
|
|
const handleDragStart = (event: DragStartEvent): void =>
|
|
{
|
|
setActive(event.active.data.current as DndItem);
|
|
};
|
|
|
|
const handleDragEnd = (args: DragEndEvent): void =>
|
|
{
|
|
setActive(null);
|
|
const result: CollectionItem[] | null = applyReorder(resultList, args);
|
|
|
|
if (result !== null)
|
|
{
|
|
updateCollections(result);
|
|
if (sortMode !== "custom")
|
|
setSortMode("custom");
|
|
|
|
track("used_drag_and_drop");
|
|
}
|
|
};
|
|
|
|
if (sortMode === null || collections === null)
|
|
return <></>;
|
|
|
|
if (collections.length < 1)
|
|
return (
|
|
<article className={ cls.empty }>
|
|
<Sparkle48Regular />
|
|
<Subtitle2 align="center">{ i18n.t("main.list.empty.title") }</Subtitle2>
|
|
<Caption1 align="center">{ i18n.t("main.list.empty.message") }</Caption1>
|
|
</article>
|
|
);
|
|
|
|
return (
|
|
<article className={ cls.root }>
|
|
<SearchBar
|
|
query={ query } onQueryChange={ setQuery }
|
|
filter={ colors } onFilterChange={ updateFilter }
|
|
sort={ sortMode } onSortChange={ setSortMode }
|
|
showHidden={ showHidden }
|
|
onReset={ resetFilter } />
|
|
|
|
<CtaMessage className={ cls.msgBar } />
|
|
<StorageCapacityIssueMessage className={ cls.msgBar } />
|
|
<CloudIssueMessages className={ cls.msgBar } />
|
|
|
|
{ resultList.length < 1 ?
|
|
<div className={ cls.emptySearch }>
|
|
<SearchInfo24Regular />
|
|
<Subtitle2>{ i18n.t("main.list.empty_search.title") }</Subtitle2>
|
|
<Body1>{ i18n.t("main.list.empty_search.message") }</Body1>
|
|
<Button appearance="subtle" icon={ <ArrowUndo20Regular /> } onClick={ resetFilter }>
|
|
{ i18n.t("common.actions.reset_filters") }
|
|
</Button>
|
|
</div>
|
|
:
|
|
<section className={ mergeClasses(cls.collectionList, !tilesView && cls.listView, !!(!tilesView && compactView) && cls.compactList) }>
|
|
<DndContext
|
|
sensors={ sensors }
|
|
collisionDetection={ collisionDetector(!tilesView) }
|
|
onDragStart={ handleDragStart }
|
|
onDragEnd={ handleDragEnd }
|
|
modifiers={ [snapHandleToCursor] }
|
|
>
|
|
<SortableContext
|
|
items={ resultList.map((_, index) => index.toString()) }
|
|
strategy={ tilesView ? verticalListSortingStrategy : rectSortingStrategy }
|
|
>
|
|
{ resultList.map((collection, index) =>
|
|
<CollectionView key={ index } collection={ collection } index={ index } compact={ compactView } />
|
|
) }
|
|
</SortableContext>
|
|
|
|
<DragOverlay dropAnimation={ null }>
|
|
{ active !== null ?
|
|
active.item.type === "collection" ?
|
|
<CollectionView collection={ active.item } index={ -1 } dragOverlay />
|
|
:
|
|
<CollectionContext.Provider
|
|
value={ {
|
|
tabCount: 0,
|
|
collection: resultList[active.indices[0]],
|
|
hasPinnedGroup: true
|
|
} }
|
|
>
|
|
{ active.item.type === "group" ?
|
|
<GroupView group={ active.item } indices={ [-1] } collectionId={ -1 } dragOverlay />
|
|
:
|
|
<TabView tab={ active.item } indices={ [-1] } collectionId={ -1 } dragOverlay />
|
|
}
|
|
</CollectionContext.Provider>
|
|
:
|
|
<></>
|
|
}
|
|
</DragOverlay>
|
|
</DndContext>
|
|
</section>
|
|
}
|
|
</article>
|
|
);
|
|
}
|