snapshot of https://github.com/makeplane/plane.git @ d868349a55de79979eb8b98701bf1702c67ad634 (2026-09-15)
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function CycleModuleBoardLayoutLoader() {
|
||||
return (
|
||||
<div className="h-full w-full animate-pulse">
|
||||
<div className="flex h-full w-full justify-between">
|
||||
<div className="3xl:grid-cols-4 grid h-full w-full auto-rows-max grid-cols-1 gap-6 overflow-y-auto p-8 transition-all lg:grid-cols-2 xl:grid-cols-3">
|
||||
{range(5).map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex h-44 w-full flex-col justify-between rounded-sm border border-subtle bg-surface-1 p-4 text-13"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="h-6 w-24 rounded-sm bg-layer-1" />
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-6 w-20 rounded-sm bg-layer-1" />
|
||||
<span className="h-6 w-6 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-20 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<span className="h-5 w-5 rounded-full bg-layer-1" />
|
||||
</div>
|
||||
<span className="h-1.5 rounded-sm bg-layer-1" />
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<span className="h-4 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-4 w-4 rounded-sm bg-layer-1" />
|
||||
<span className="h-4 w-4 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function CycleModuleListLayoutLoader() {
|
||||
return (
|
||||
<div className="h-full animate-pulse overflow-y-auto">
|
||||
<div className="flex h-full w-full justify-between">
|
||||
<div className="flex h-full w-full flex-col overflow-y-auto">
|
||||
{range(5).map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex w-full flex-col items-center justify-between gap-5 border-b border-subtle px-5 py-6 sm:flex-row"
|
||||
>
|
||||
<div className="relative flex w-full items-center justify-between gap-3 overflow-hidden">
|
||||
<div className="relative flex w-full items-center gap-3 overflow-hidden">
|
||||
<div className="flex items-center gap-4 truncate">
|
||||
<span className="h-10 w-10 rounded-full bg-layer-1" />
|
||||
<span className="h-5 w-20 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
<span className="h-6 w-20 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between gap-2.5 overflow-hidden sm:w-auto sm:flex-shrink-0 sm:justify-end">
|
||||
<div className="relative flex flex-shrink-0 items-center gap-3">
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
import { getRandomInt } from "../utils";
|
||||
|
||||
function CalendarDay() {
|
||||
const dataCount = getRandomInt(0, 1);
|
||||
const dataBlocks = range(dataCount).map((index) => (
|
||||
<span key={index} className="mb-2 h-8 w-full rounded-sm bg-layer-1" />
|
||||
));
|
||||
|
||||
return (
|
||||
<div className="flex min-h-[9rem] w-full flex-col">
|
||||
<div className="flex w-full items-center justify-end p-2">
|
||||
<span className="h-6 w-6 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-2.5 p-2">{dataBlocks}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function CalendarLayoutLoader() {
|
||||
return (
|
||||
<div className="h-full w-full animate-pulse overflow-y-auto bg-surface-1">
|
||||
<span className="relative grid grid-cols-5 divide-x-[0.5px] divide-subtle-1 text-13 font-medium">
|
||||
{range(5).map((index) => (
|
||||
<span key={index} className="h-11 w-full bg-layer-1" />
|
||||
))}
|
||||
</span>
|
||||
<div className="h-full w-full overflow-y-auto">
|
||||
<div className="grid h-full w-full grid-cols-1 divide-y-[0.5px] divide-subtle-1 overflow-y-auto">
|
||||
{range(6).map((index) => (
|
||||
<div key={index} className="grid grid-cols-5 divide-x-[0.5px] divide-subtle-1">
|
||||
{range(5).map((index) => (
|
||||
<CalendarDay key={index} />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
import { Row } from "@plane/ui";
|
||||
import { BLOCK_HEIGHT } from "@/components/gantt-chart/constants";
|
||||
import { getRandomLength } from "../utils";
|
||||
|
||||
export function GanttLayoutListItemLoader() {
|
||||
return (
|
||||
<div className="flex w-full items-center gap-4 px-6" style={{ height: `${BLOCK_HEIGHT}px` }}>
|
||||
<div className="h-6 w-8 rounded-sm bg-layer-1 px-3" />
|
||||
<div className={`h-6 px-3 w-${getRandomLength(["32", "52", "72"])} rounded-sm bg-layer-1`} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function GanttLayoutLoader() {
|
||||
return (
|
||||
<div className="flex h-full animate-pulse flex-col overflow-x-auto">
|
||||
<div className="min-h-10 w-full border-b border-subtle">
|
||||
<span className="h-6 w-12 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex h-full">
|
||||
<div className="h-full w-[25.5rem] border-r border-subtle">
|
||||
<Row className="flex h-header items-end border-b border-subtle py-2">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<span className="h-5 w-14 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</Row>
|
||||
<Row className="flex h-11 w-full flex-col gap-3 py-4">
|
||||
{range(6).map((index) => (
|
||||
<div key={index} className="flex h-11 w-full items-center gap-3">
|
||||
<span className="h-6 w-6 rounded-sm bg-layer-1" />
|
||||
<span className={`h-6 w-${getRandomLength(["32", "52", "72"])} rounded-sm bg-layer-1`} />
|
||||
</div>
|
||||
))}
|
||||
</Row>
|
||||
</div>
|
||||
<div className="h-full w-full border-r border-subtle">
|
||||
<div className="flex h-header flex-col justify-between gap-2 border-b border-subtle px-4 py-1.5">
|
||||
<div className="flex items-center justify-start">
|
||||
<span className="h-5 w-20 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex w-full items-center justify-between gap-3">
|
||||
{range(15).map((index) => (
|
||||
<span key={index} className="h-5 w-10 rounded-sm bg-layer-1" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-11 w-full flex-col gap-3 p-4">
|
||||
{range(6).map((index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`flex h-11 w-full items-center gap-3`}
|
||||
style={{ paddingLeft: getRandomLength(["115px", "208px", "260px"]) }}
|
||||
>
|
||||
<span className={`h-6 w-40 w-${getRandomLength(["32", "52", "72"])} rounded-sm bg-layer-1`} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { forwardRef } from "react";
|
||||
import { range } from "lodash-es";
|
||||
// plane ui
|
||||
import { ContentWrapper } from "@plane/ui";
|
||||
// plane utils
|
||||
import { cn } from "@plane/utils";
|
||||
|
||||
export const KanbanIssueBlockLoader = forwardRef(function KanbanIssueBlockLoader(
|
||||
{ cardHeight = 100, shouldAnimate = true }: { cardHeight?: number; shouldAnimate?: boolean },
|
||||
ref: React.ForwardedRef<HTMLSpanElement>
|
||||
) {
|
||||
return (
|
||||
<span
|
||||
ref={ref}
|
||||
className={cn(`block rounded-sm bg-[var(--illustration-fill-secondary)]`, { "animate-pulse": shouldAnimate })}
|
||||
style={{ height: `${cardHeight}px` }}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export function KanbanColumnLoader({
|
||||
cardsInColumn = 3,
|
||||
ignoreHeader = false,
|
||||
cardHeight = 100,
|
||||
shouldAnimate = true,
|
||||
}: {
|
||||
cardsInColumn?: number;
|
||||
ignoreHeader?: boolean;
|
||||
cardHeight?: number;
|
||||
shouldAnimate?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
{!ignoreHeader && (
|
||||
<div className="flex h-9 w-80 items-center justify-between">
|
||||
<div className="item-center flex gap-3">
|
||||
<span className={cn("h-6 w-6 rounded-sm bg-layer-1", { "animate-pulse": shouldAnimate })} />
|
||||
<span className={cn("h-6 w-24 rounded-sm bg-layer-1", { "animate-pulse": shouldAnimate })} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{range(cardsInColumn).map((cardIndex) => (
|
||||
<KanbanIssueBlockLoader key={cardIndex} cardHeight={cardHeight} shouldAnimate={shouldAnimate} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
KanbanIssueBlockLoader.displayName = "KanbanIssueBlockLoader";
|
||||
|
||||
export function KanbanLayoutLoader({ cardsInEachColumn = [2, 3, 2, 4, 3] }: { cardsInEachColumn?: number[] }) {
|
||||
return (
|
||||
<ContentWrapper className="flex-row gap-5 overflow-x-auto py-1.5">
|
||||
{cardsInEachColumn.map((cardsInColumn, columnIndex) => (
|
||||
<KanbanColumnLoader key={columnIndex} cardsInColumn={cardsInColumn} />
|
||||
))}
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { Fragment, forwardRef } from "react";
|
||||
import { range } from "lodash-es";
|
||||
// plane ui
|
||||
import { Row } from "@plane/ui";
|
||||
// plane utils
|
||||
import { cn } from "@plane/utils";
|
||||
import { getRandomInt, getRandomLength } from "../utils";
|
||||
|
||||
export const ListLoaderItemRow = forwardRef(function ListLoaderItemRow(
|
||||
{
|
||||
shouldAnimate = true,
|
||||
renderForPlaceHolder = false,
|
||||
defaultPropertyCount = 6,
|
||||
}: { shouldAnimate?: boolean; renderForPlaceHolder?: boolean; defaultPropertyCount?: number },
|
||||
ref: React.ForwardedRef<HTMLDivElement>
|
||||
) {
|
||||
return (
|
||||
<Row
|
||||
ref={ref}
|
||||
className={cn("flex h-11 items-center justify-between py-3", {
|
||||
"bg-surface-1": renderForPlaceHolder,
|
||||
"border-t border-subtle": !renderForPlaceHolder,
|
||||
})}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<span
|
||||
className={cn("h-5 w-10 rounded-sm bg-[var(--illustration-fill-tertiary)]", {
|
||||
"animate-pulse": shouldAnimate,
|
||||
"bg-surface-2": renderForPlaceHolder,
|
||||
})}
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
`h-5 w-${getRandomLength(["32", "52", "72"])} rounded-sm bg-[var(--illustration-fill-tertiary)]`,
|
||||
{
|
||||
"animate-pulse": shouldAnimate,
|
||||
"bg-surface-2": renderForPlaceHolder,
|
||||
}
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{range(defaultPropertyCount).map((index) => (
|
||||
<Fragment key={index}>
|
||||
{getRandomInt(1, 2) % 2 === 0 ? (
|
||||
<span
|
||||
key={index}
|
||||
className={cn("h-5 w-5 rounded-sm bg-[var(--illustration-fill-tertiary)]", {
|
||||
"animate-pulse": shouldAnimate,
|
||||
"bg-surface-2": renderForPlaceHolder,
|
||||
})}
|
||||
/>
|
||||
) : (
|
||||
<span
|
||||
className={cn("h-5 w-16 rounded-sm bg-[var(--illustration-fill-tertiary)]", {
|
||||
"animate-pulse": shouldAnimate,
|
||||
"bg-surface-2": renderForPlaceHolder,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
</Row>
|
||||
);
|
||||
});
|
||||
|
||||
ListLoaderItemRow.displayName = "ListLoaderItemRow";
|
||||
|
||||
function ListSection({ itemCount }: { itemCount: number }) {
|
||||
return (
|
||||
<div className="flex flex-shrink-0 flex-col">
|
||||
<Row className="sticky top-0 z-[2] w-full flex-shrink-0 border-b border-subtle bg-surface-2 py-1">
|
||||
<div className="flex w-full items-center gap-2 py-1.5">
|
||||
<span className="h-6 w-6 animate-pulse rounded-sm bg-layer-1" />
|
||||
<span className="h-6 w-24 animate-pulse rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</Row>
|
||||
<div className="relative h-full w-full">
|
||||
{range(itemCount).map((index) => (
|
||||
<ListLoaderItemRow key={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ListLayoutLoader() {
|
||||
return (
|
||||
<div className="flex flex-shrink-0 flex-col">
|
||||
{[6, 5, 2].map((itemCount, index) => (
|
||||
<ListSection key={index} itemCount={itemCount} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
export function MembersLayoutLoader() {
|
||||
return (
|
||||
<div className="flex gap-5 overflow-x-auto py-1.5">
|
||||
{range(5).map((columnIndex) => (
|
||||
<div key={columnIndex} className="flex flex-col gap-3">
|
||||
<div className={`flex h-9 items-center justify-between ${columnIndex === 0 ? "w-80" : "w-36"}`}>
|
||||
<span className="h-6 w-24 animate-pulse rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
{range(2).map((cardIndex) => (
|
||||
<span className="h-8 w-full animate-pulse rounded-sm bg-layer-1" key={cardIndex} />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
// ui
|
||||
import { Loader } from "@plane/ui";
|
||||
import { InboxSidebarLoader } from "./inbox-sidebar-loader";
|
||||
|
||||
export function InboxLayoutLoader() {
|
||||
return (
|
||||
<div className="relative flex h-full w-full overflow-hidden">
|
||||
<div className="h-full w-2/6 flex-shrink-0 border-r border-strong">
|
||||
<InboxSidebarLoader />
|
||||
</div>
|
||||
<div className="w-4/6">
|
||||
<Loader className="flex h-full flex-col gap-5 p-5">
|
||||
<div className="space-y-2">
|
||||
<Loader.Item height="30px" width="40%" />
|
||||
<Loader.Item height="15px" width="60%" />
|
||||
<Loader.Item height="15px" width="60%" />
|
||||
<Loader.Item height="15px" width="40%" />
|
||||
</div>
|
||||
<Loader.Item height="150px" />
|
||||
</Loader>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function InboxSidebarLoader() {
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
{range(6).map((index) => (
|
||||
<div key={index} className="flex h-[105px] flex-col gap-2.5 space-y-3 border-b border-subtle p-4">
|
||||
<div className="flex flex-col gap-2">
|
||||
<span className="h-5 w-16 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-36 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-4 w-20 rounded-sm bg-layer-1" />
|
||||
<span className="h-2 w-2 rounded-full bg-layer-1" />
|
||||
<span className="h-4 w-16 rounded-sm bg-layer-1" />
|
||||
<span className="h-4 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
import { Row } from "@plane/ui";
|
||||
import { getRandomLength } from "../utils";
|
||||
|
||||
export function SpreadsheetIssueRowLoader(props: { columnCount: number }) {
|
||||
return (
|
||||
<tr className="border-b border-subtle bg-surface-1">
|
||||
<td className="sticky left-0 z-[10] flex h-11 min-w-[28rem] items-center border-r-[0.5px] border-subtle bg-surface-1">
|
||||
<Row className="flex items-center gap-3">
|
||||
<span className="h-5 w-10 animate-pulse rounded-sm bg-layer-1" />
|
||||
<span className={`h-5 w-${getRandomLength(["32", "52", "72"])} animate-pulse rounded-sm bg-layer-1`} />
|
||||
</Row>
|
||||
</td>
|
||||
{range(props.columnCount).map((colIndex) => (
|
||||
<td key={colIndex} className="h-11 w-full min-w-[8rem] border-r border-subtle">
|
||||
<div className="flex items-center justify-center gap-3 px-3">
|
||||
<span className="h-5 w-20 animate-pulse rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
export function SpreadsheetLayoutLoader() {
|
||||
return (
|
||||
<div className="horizontal-scroll-enable h-full w-full overflow-y-auto">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="h-11 min-w-[28rem] animate-pulse border-r border-subtle bg-surface-2" />
|
||||
{range(10).map((index) => (
|
||||
<th key={index} className="h-11 w-full min-w-[8rem] animate-pulse border-r border-subtle bg-surface-2" />
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{range(16).map((rowIndex) => (
|
||||
<SpreadsheetIssueRowLoader key={rowIndex} columnCount={10} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
26
apps/web/core/components/ui/loader/notification-loader.tsx
Normal file
26
apps/web/core/components/ui/loader/notification-loader.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function NotificationsLoader() {
|
||||
return (
|
||||
<div className="animate-pulse divide-y divide-subtle overflow-hidden">
|
||||
{range(3).map((i) => (
|
||||
<div key={i} className="flex w-full items-center gap-4 p-3">
|
||||
<span className="min-h-12 min-w-12 rounded-full bg-layer-1" />
|
||||
<div className="flex w-full flex-col gap-2.5">
|
||||
<span className="h-5 w-36 rounded-sm bg-layer-1" />
|
||||
<div className="flex w-full items-center justify-between gap-2">
|
||||
<span className="h-5 w-28 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
38
apps/web/core/components/ui/loader/pages-loader.tsx
Normal file
38
apps/web/core/components/ui/loader/pages-loader.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function PagesLoader() {
|
||||
return (
|
||||
<div className="flex h-full flex-col space-y-5 overflow-hidden p-6">
|
||||
<div className="flex justify-between gap-4">
|
||||
<h3 className="text-20 font-semibold text-primary">Pages</h3>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
{range(5).map((i) => (
|
||||
<span key={i} className="h-8 w-20 rounded-full bg-layer-1" />
|
||||
))}
|
||||
</div>
|
||||
<div className="divide-y divide-subtle-1">
|
||||
{range(5).map((i) => (
|
||||
<div key={i} className="flex h-12 w-full items-center justify-between px-3">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-20 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="h-5 w-16 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
44
apps/web/core/components/ui/loader/projects-loader.tsx
Normal file
44
apps/web/core/components/ui/loader/projects-loader.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function ProjectsLoader() {
|
||||
return (
|
||||
<div className="h-full w-full animate-pulse overflow-y-auto p-8">
|
||||
<div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
||||
{range(3).map((i) => (
|
||||
<div key={i} className="flex cursor-pointer flex-col rounded-sm border border-subtle bg-surface-1">
|
||||
<div className="relative min-h-[118px] w-full rounded-t border-b border-subtle">
|
||||
<div className="absolute inset-0 z-[1] bg-gradient-to-t from-black/20 to-transparent">
|
||||
<div className="absolute bottom-4 z-10 flex h-10 w-full items-center justify-between gap-3 px-4">
|
||||
<div className="flex flex-grow items-center gap-2.5 truncate">
|
||||
<span className="min-h-9 min-w-9 rounded-sm bg-layer-1" />
|
||||
<div className="flex w-full flex-col justify-between gap-0.5 truncate">
|
||||
<span className="h-4 w-28 rounded-sm bg-layer-1" />
|
||||
<span className="h-4 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-full flex-shrink-0 items-center gap-2">
|
||||
<span className="h-6 w-6 rounded-sm bg-layer-1" />
|
||||
<span className="h-6 w-6 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-[104px] w-full flex-col justify-between rounded-b-sm p-4">
|
||||
<span className="h-4 w-36 rounded-sm bg-layer-1" />
|
||||
<div className="item-center flex justify-between">
|
||||
<span className="h-5 w-20 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
21
apps/web/core/components/ui/loader/settings/activity.tsx
Normal file
21
apps/web/core/components/ui/loader/settings/activity.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
import { getRandomLength } from "../utils";
|
||||
|
||||
export function ActivitySettingsLoader() {
|
||||
return (
|
||||
<div className="flex animate-pulse flex-col gap-3">
|
||||
{range(10).map((i) => (
|
||||
<div key={i} className="relative flex h-12 items-center gap-2 border-b border-subtle">
|
||||
<span className="h-6 w-6 rounded-sm bg-layer-1" />
|
||||
<span className={`h-6 w-${getRandomLength(["52", "72", "96"])} rounded-sm bg-layer-1`} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
30
apps/web/core/components/ui/loader/settings/api-token.tsx
Normal file
30
apps/web/core/components/ui/loader/settings/api-token.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
export function APITokenSettingsLoader() {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<section className="w-full overflow-y-auto">
|
||||
<div className="mb-2 flex items-center justify-between border-b border-subtle pb-3.5">
|
||||
<h3 className="text-18 font-medium">{t("workspace_settings.settings.api_tokens.title")}</h3>
|
||||
<span className="h-8 w-28 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="divide-y-[0.5px] divide-subtle-1">
|
||||
{range(2).map((i) => (
|
||||
<div key={i} className="flex flex-col gap-2 py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-5 w-28 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<span className="h-5 w-36 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
37
apps/web/core/components/ui/loader/settings/email.tsx
Normal file
37
apps/web/core/components/ui/loader/settings/email.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function EmailSettingsLoader() {
|
||||
return (
|
||||
<div className="pb- mx-auto mt-8 h-full w-full animate-pulse overflow-y-auto px-6 lg:px-20">
|
||||
<div className="mb-2 flex flex-col gap-2 border-b border-subtle pt-6 pb-6">
|
||||
<span className="h-7 w-40 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-96 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-center py-3">
|
||||
<span className="h-7 w-32 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
{range(4).map((i) => (
|
||||
<div key={i} className="flex items-center justify-between">
|
||||
<div className="flex flex-col gap-2 py-3">
|
||||
<span className="h-6 w-28 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-96 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="flex items-center py-12">
|
||||
<span className="h-8 w-32 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function ImportExportSettingsLoader() {
|
||||
return (
|
||||
<div className="animate-pulse divide-y-[0.5px] divide-subtle-1">
|
||||
{range(2).map((i) => (
|
||||
<div key={i} className="flex items-center justify-between gap-2 px-4 py-3">
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-5 w-16 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-4 w-28 rounded-sm bg-layer-1" />
|
||||
<span className="h-4 w-28 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
26
apps/web/core/components/ui/loader/settings/integration.tsx
Normal file
26
apps/web/core/components/ui/loader/settings/integration.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function IntegrationsSettingsLoader() {
|
||||
return (
|
||||
<div className="animate-pulse divide-y-[0.5px] divide-subtle">
|
||||
{range(2).map((i) => (
|
||||
<div key={i} className="flex items-center justify-between gap-2 border-b border-subtle bg-surface-1 px-4 py-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<span className="h-10 w-10 rounded-full bg-layer-1" />
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="h-5 w-20 rounded-sm bg-layer-1" />
|
||||
<span className="h-4 w-60 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
<span className="h-8 w-16 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
25
apps/web/core/components/ui/loader/settings/members.tsx
Normal file
25
apps/web/core/components/ui/loader/settings/members.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function MembersSettingsLoader() {
|
||||
return (
|
||||
<div className="divide-y-[0.5px] divide-subtle">
|
||||
{range(3).map((i) => (
|
||||
<div key={i} className="group grid grid-cols-5 items-center justify-evenly px-3 py-4">
|
||||
<div className="col-span-2 flex items-center gap-x-2.5">
|
||||
<span className="size-6 rounded-full bg-layer-1" />
|
||||
<span className="h-5 w-24 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<span className="h-5 w-24 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-20 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-28 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
28
apps/web/core/components/ui/loader/settings/web-hook.tsx
Normal file
28
apps/web/core/components/ui/loader/settings/web-hook.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export function WebhookSettingsLoader() {
|
||||
return (
|
||||
<div className="h-full w-full overflow-hidden py-8 pr-9">
|
||||
<div className="flex h-full w-full flex-col">
|
||||
<div className="flex items-center justify-between gap-4 border-b border-subtle pb-3.5">
|
||||
<div className="text-18 font-medium">Webhooks</div>
|
||||
<span className="h-8 w-28 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="h-full w-full overflow-y-auto">
|
||||
<div className="border-b border-subtle">
|
||||
<div>
|
||||
<span className="flex items-center justify-between gap-4 px-3.5 py-[18px]">
|
||||
<span className="h-5 w-36 rounded-sm bg-layer-1" />
|
||||
<span className="h-6 w-12 rounded-sm bg-layer-1" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
12
apps/web/core/components/ui/loader/utils.tsx
Normal file
12
apps/web/core/components/ui/loader/utils.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export const getRandomInt = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
|
||||
export const getRandomLength = (lengthArray: string[]) => {
|
||||
const randomIndex = Math.floor(Math.random() * lengthArray.length);
|
||||
return `${lengthArray[randomIndex]}`;
|
||||
};
|
||||
28
apps/web/core/components/ui/loader/view-list-loader.tsx
Normal file
28
apps/web/core/components/ui/loader/view-list-loader.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { range } from "lodash-es";
|
||||
|
||||
export function ViewListLoader() {
|
||||
return (
|
||||
<div className="flex h-full w-full animate-pulse flex-col">
|
||||
{range(8).map((i) => (
|
||||
<div key={i} className="group border-b border-subtle">
|
||||
<div className="relative flex w-full items-center justify-between rounded-sm p-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="min-h-10 min-w-10 rounded-sm bg-layer-1" />
|
||||
<span className="h-6 w-28 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
<span className="h-5 w-5 rounded-sm bg-layer-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user