mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-23 19:49:56 +01:00
editor: add button to sort task list
This commit is contained in:
committed by
Abdullah Atta
parent
ca2f924417
commit
912e97dc3c
@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { Box, Flex, Input, Text } from "@theme-ui/components";
|
||||
import { findChildren, getNodeType } from "@tiptap/core";
|
||||
import TaskItem from "@tiptap/extension-task-item";
|
||||
import { Node } from "prosemirror-model";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { ToolButton } from "../../toolbar/components/tool-button";
|
||||
@@ -27,7 +26,7 @@ import { findParentNodeOfTypeClosestToPos } from "../../utils/prosemirror";
|
||||
import { ReactNodeViewProps } from "../react";
|
||||
import { TaskItemNode } from "../task-item";
|
||||
import { TaskListAttributes } from "./task-list";
|
||||
import { countCheckedItems, deleteCheckedItems } from "./utils";
|
||||
import { countCheckedItems, deleteCheckedItems, sortList } from "./utils";
|
||||
|
||||
export function TaskListComponent(
|
||||
props: ReactNodeViewProps<TaskListAttributes>
|
||||
@@ -120,6 +119,26 @@ export function TaskListComponent(
|
||||
}}
|
||||
/>
|
||||
{editor.isEditable && (
|
||||
<>
|
||||
<ToolButton
|
||||
toggled={false}
|
||||
title="Move all checked tasks to bottom"
|
||||
icon="sortTaskList"
|
||||
variant="small"
|
||||
sx={{
|
||||
zIndex: 1
|
||||
}}
|
||||
onClick={() => {
|
||||
const pos = getPos();
|
||||
editor.current
|
||||
?.chain()
|
||||
.focus()
|
||||
.command(({ tr }) => {
|
||||
return !!sortList(tr, pos);
|
||||
})
|
||||
.run();
|
||||
}}
|
||||
/>
|
||||
<ToolButton
|
||||
toggled={false}
|
||||
title="Clear completed tasks"
|
||||
@@ -140,6 +159,7 @@ export function TaskListComponent(
|
||||
.run();
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Text
|
||||
variant={"body"}
|
||||
|
||||
@@ -69,3 +69,44 @@ export function deleteCheckedItems(tr: Transaction, pos: number) {
|
||||
return tr;
|
||||
}
|
||||
|
||||
export function sortList(tr: Transaction, pos: number) {
|
||||
const node = tr.doc.nodeAt(pos);
|
||||
|
||||
const parent = node ? { node, pos } : null;
|
||||
if (!parent || parent.node.type.name !== TaskList.name) return;
|
||||
|
||||
const sublists: NodeWithPos[] = [];
|
||||
parent.node.descendants((node, nodePos) => {
|
||||
if (node.type.name === TaskList.name)
|
||||
sublists.push({ node, pos: pos + nodePos + 1 });
|
||||
});
|
||||
if (sublists.length > 1) sublists.reverse();
|
||||
sublists.push(parent);
|
||||
|
||||
for (const list of sublists) {
|
||||
const children: {
|
||||
checked: number;
|
||||
index: number;
|
||||
}[] = [];
|
||||
|
||||
list.node.forEach((node, _, index) => {
|
||||
children.push({
|
||||
index,
|
||||
checked: node.attrs.checked ? 1 : 0
|
||||
});
|
||||
});
|
||||
|
||||
tr.replaceWith(
|
||||
tr.mapping.map(list.pos),
|
||||
tr.mapping.map(list.pos + list.node.nodeSize),
|
||||
Fragment.from(
|
||||
children
|
||||
.sort((a, b) => a.checked - b.checked)
|
||||
.map((c) => list.node.child(c.index))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!tr.steps.length) return null;
|
||||
return tr;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,8 @@ import {
|
||||
mdiNewspaper,
|
||||
mdiFullscreen,
|
||||
mdiWeb,
|
||||
mdiPageNextOutline
|
||||
mdiPageNextOutline,
|
||||
mdiSortBoolAscendingVariant
|
||||
} from "@mdi/js";
|
||||
|
||||
export const Icons = {
|
||||
@@ -190,6 +191,7 @@ export const Icons = {
|
||||
borderColor:
|
||||
"M4 24q-.825 0-1.412-.587Q2 22.825 2 22q0-.825.588-1.413Q3.175 20 4 20h16q.825 0 1.413.587Q22 21.175 22 22q0 .825-.587 1.413Q20.825 24 20 24Zm1-6q-.425 0-.713-.288Q4 17.425 4 17v-2.325q0-.2.075-.388q.075-.187.225-.337l8.75-8.75l3.75 3.75l-8.75 8.75q-.15.15-.337.225q-.188.075-.388.075Zm1-2h.9L14 8.95L13.05 8L6 15.1Zm11.925-8.15l-3.75-3.75l1.8-1.8q.275-.3.7-.288q.425.013.7.288l2.35 2.35q.275.275.275.688q0 .412-.275.712ZM6 16Z",
|
||||
sortDesc: mdiSortDescending,
|
||||
sortTaskList: mdiSortBoolAscendingVariant,
|
||||
deleteTable: mdiTableOff,
|
||||
mergeCells: mdiTableMergeCells,
|
||||
splitCells: mdiTableSplitCell,
|
||||
|
||||
Reference in New Issue
Block a user