Animate appearance of pinned documents

This commit is contained in:
Tom Moor
2023-05-17 20:13:09 -04:00
parent aff9413b0f
commit 9b257e9593
3 changed files with 184 additions and 150 deletions

View File

@@ -23,6 +23,7 @@ import breakpoint from "styled-components-breakpoint";
import Pin from "~/models/Pin";
import DocumentCard from "~/components/DocumentCard";
import useStores from "~/hooks/useStores";
import { ResizingHeightContainer } from "./ResizingHeightContainer";
type Props = {
/** Pins to display */
@@ -98,27 +99,36 @@ function PinnedDocuments({ limit, pins, canUpdate, ...rest }: Props) {
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
<SortableContext items={items} strategy={rectSortingStrategy}>
<List>
<AnimatePresence initial={false}>
{items.map((documentId) => {
const document = documents.get(documentId);
const pin = pins.find((pin) => pin.documentId === documentId);
<ResizingHeightContainer
config={{
transition: {
duration: 0.2,
ease: "easeInOut",
},
}}
>
<SortableContext items={items} strategy={rectSortingStrategy}>
<List>
<AnimatePresence initial={false}>
{items.map((documentId) => {
const document = documents.get(documentId);
const pin = pins.find((pin) => pin.documentId === documentId);
return document ? (
<DocumentCard
key={documentId}
document={document}
canUpdatePin={canUpdate}
isDraggable={items.length > 1}
pin={pin}
{...rest}
/>
) : null;
})}
</AnimatePresence>
</List>
</SortableContext>
return document ? (
<DocumentCard
key={documentId}
document={document}
canUpdatePin={canUpdate}
isDraggable={items.length > 1}
pin={pin}
{...rest}
/>
) : null;
})}
</AnimatePresence>
</List>
</SortableContext>
</ResizingHeightContainer>
</DndContext>
);
}

View File

@@ -12,6 +12,7 @@ import {
} from "react-router-dom";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { s } from "@shared/styles";
import Collection from "~/models/Collection";
import Search from "~/scenes/Search";
import Badge from "~/components/Badge";
@@ -178,90 +179,97 @@ function CollectionScene() {
canUpdate={can.update}
/>
<Tabs>
<Tab to={collectionPath(collection.url)} exact>
{t("Documents")}
</Tab>
<Tab to={collectionPath(collection.url, "updated")} exact>
{t("Recently updated")}
</Tab>
<Tab to={collectionPath(collection.url, "published")} exact>
{t("Recently published")}
</Tab>
<Tab to={collectionPath(collection.url, "old")} exact>
{t("Least recently updated")}
</Tab>
<Tab to={collectionPath(collection.url, "alphabetical")} exact>
{t("AZ")}
</Tab>
</Tabs>
<Switch>
<Route path={collectionPath(collection.url, "alphabetical")}>
<PaginatedDocumentList
key="alphabetical"
documents={documents.alphabeticalInCollection(
collection.id
)}
fetch={documents.fetchAlphabetical}
options={{
collectionId: collection.id,
}}
/>
</Route>
<Route path={collectionPath(collection.url, "old")}>
<PaginatedDocumentList
key="old"
documents={documents.leastRecentlyUpdatedInCollection(
collection.id
)}
fetch={documents.fetchLeastRecentlyUpdated}
options={{
collectionId: collection.id,
}}
/>
</Route>
<Route path={collectionPath(collection.url, "recent")}>
<Redirect to={collectionPath(collection.url, "published")} />
</Route>
<Route path={collectionPath(collection.url, "published")}>
<PaginatedDocumentList
key="published"
documents={documents.recentlyPublishedInCollection(
collection.id
)}
fetch={documents.fetchRecentlyPublished}
options={{
collectionId: collection.id,
}}
showPublished
/>
</Route>
<Route path={collectionPath(collection.url, "updated")}>
<PaginatedDocumentList
key="updated"
documents={documents.recentlyUpdatedInCollection(
collection.id
)}
fetch={documents.fetchRecentlyUpdated}
options={{
collectionId: collection.id,
}}
/>
</Route>
<Route path={collectionPath(collection.url)} exact>
<PaginatedDocumentList
documents={documents.rootInCollection(collection.id)}
fetch={documents.fetchPage}
options={{
collectionId: collection.id,
parentDocumentId: null,
sort: collection.sort.field,
direction: collection.sort.direction,
}}
showParentDocuments
/>
</Route>
</Switch>
<Documents>
<Tabs>
<Tab to={collectionPath(collection.url)} exact>
{t("Documents")}
</Tab>
<Tab to={collectionPath(collection.url, "updated")} exact>
{t("Recently updated")}
</Tab>
<Tab to={collectionPath(collection.url, "published")} exact>
{t("Recently published")}
</Tab>
<Tab to={collectionPath(collection.url, "old")} exact>
{t("Least recently updated")}
</Tab>
<Tab
to={collectionPath(collection.url, "alphabetical")}
exact
>
{t("AZ")}
</Tab>
</Tabs>
<Switch>
<Route path={collectionPath(collection.url, "alphabetical")}>
<PaginatedDocumentList
key="alphabetical"
documents={documents.alphabeticalInCollection(
collection.id
)}
fetch={documents.fetchAlphabetical}
options={{
collectionId: collection.id,
}}
/>
</Route>
<Route path={collectionPath(collection.url, "old")}>
<PaginatedDocumentList
key="old"
documents={documents.leastRecentlyUpdatedInCollection(
collection.id
)}
fetch={documents.fetchLeastRecentlyUpdated}
options={{
collectionId: collection.id,
}}
/>
</Route>
<Route path={collectionPath(collection.url, "recent")}>
<Redirect
to={collectionPath(collection.url, "published")}
/>
</Route>
<Route path={collectionPath(collection.url, "published")}>
<PaginatedDocumentList
key="published"
documents={documents.recentlyPublishedInCollection(
collection.id
)}
fetch={documents.fetchRecentlyPublished}
options={{
collectionId: collection.id,
}}
showPublished
/>
</Route>
<Route path={collectionPath(collection.url, "updated")}>
<PaginatedDocumentList
key="updated"
documents={documents.recentlyUpdatedInCollection(
collection.id
)}
fetch={documents.fetchRecentlyUpdated}
options={{
collectionId: collection.id,
}}
/>
</Route>
<Route path={collectionPath(collection.url)} exact>
<PaginatedDocumentList
documents={documents.rootInCollection(collection.id)}
fetch={documents.fetchPage}
options={{
collectionId: collection.id,
parentDocumentId: null,
sort: collection.sort.field,
direction: collection.sort.direction,
}}
showParentDocuments
/>
</Route>
</Switch>
</Documents>
</>
)}
</CenteredContent>
@@ -290,6 +298,11 @@ const StarButton = styled(Star)`
}
`;
const Documents = styled.div`
position: relative;
background: ${s("background")};
`;
const HeadingWithIcon = styled(Heading)<{ $isStarred: boolean }>`
display: flex;
align-items: center;

View File

@@ -3,6 +3,8 @@ import { HomeIcon } from "outline-icons";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { Switch, Route } from "react-router-dom";
import styled from "styled-components";
import { s } from "@shared/styles";
import { Action } from "~/components/Actions";
import Empty from "~/components/Empty";
import Heading from "~/components/Heading";
@@ -48,54 +50,63 @@ function Home() {
{!ui.languagePromptDismissed && <LanguagePrompt />}
<Heading>{t("Home")}</Heading>
<PinnedDocuments pins={pins.home} canUpdate={canManageTeam} />
<Tabs>
<Tab to="/home" exact>
{t("Recently viewed")}
</Tab>
<Tab to="/home/recent" exact>
{t("Recently updated")}
</Tab>
<Tab to="/home/created">{t("Created by me")}</Tab>
</Tabs>
<Switch>
<Route path="/home/recent">
<PaginatedDocumentList
documents={documents.recentlyUpdated}
fetch={documents.fetchRecentlyUpdated}
empty={<Empty>{t("Weird, this shouldnt ever be empty")}</Empty>}
showCollection
/>
</Route>
<Route path="/home/created">
<PaginatedDocumentList
key="created"
documents={documents.createdByUser(userId)}
fetch={documents.fetchOwned}
options={{
user: userId,
}}
empty={<Empty>{t("You havent created any documents yet")}</Empty>}
showCollection
/>
</Route>
<Route path="/home">
<PaginatedDocumentList
key="recent"
documents={documents.recentlyViewed}
fetch={documents.fetchRecentlyViewed}
empty={
<Empty>
{t(
"Documents youve recently viewed will be here for easy access"
)}
</Empty>
}
showCollection
/>
</Route>
</Switch>
<Documents>
<Tabs>
<Tab to="/home" exact>
{t("Recently viewed")}
</Tab>
<Tab to="/home/recent" exact>
{t("Recently updated")}
</Tab>
<Tab to="/home/created">{t("Created by me")}</Tab>
</Tabs>
<Switch>
<Route path="/home/recent">
<PaginatedDocumentList
documents={documents.recentlyUpdated}
fetch={documents.fetchRecentlyUpdated}
empty={<Empty>{t("Weird, this shouldnt ever be empty")}</Empty>}
showCollection
/>
</Route>
<Route path="/home/created">
<PaginatedDocumentList
key="created"
documents={documents.createdByUser(userId)}
fetch={documents.fetchOwned}
options={{
user: userId,
}}
empty={
<Empty>{t("You havent created any documents yet")}</Empty>
}
showCollection
/>
</Route>
<Route path="/home">
<PaginatedDocumentList
key="recent"
documents={documents.recentlyViewed}
fetch={documents.fetchRecentlyViewed}
empty={
<Empty>
{t(
"Documents youve recently viewed will be here for easy access"
)}
</Empty>
}
showCollection
/>
</Route>
</Switch>
</Documents>
</Scene>
);
}
const Documents = styled.div`
position: relative;
background: ${s("background")};
`;
export default observer(Home);