feat: impl tag create & edit

This commit is contained in:
thecodrr
2021-07-20 12:47:11 +05:00
parent 6302bc6d79
commit 2bbfc52e56
9 changed files with 118 additions and 49 deletions

View File

@@ -166,7 +166,7 @@ test("edit topics individually", async () => {
await page.click(Menu.new("menuitem").item("edit").build()); await page.click(Menu.new("menuitem").item("edit").build());
const editedTopicTitle = "Topic " + index + " edit 1"; const editedTopicTitle = "Topic " + index + " edit 1";
await page.fill(getTestId("dialog-edit-topic"), editedTopicTitle); await page.fill(getTestId("item-dialog-title"), editedTopicTitle);
await page.click(getTestId("dialog-yes")); await page.click(getTestId("dialog-yes"));

View File

@@ -4,6 +4,7 @@ import { hashNavigate } from "../navigation";
import ThemeProvider from "../components/theme-provider"; import ThemeProvider from "../components/theme-provider";
import { qclone } from "qclone"; import { qclone } from "qclone";
import { store as notebookStore } from "../stores/notebook-store"; import { store as notebookStore } from "../stores/notebook-store";
import { store as tagStore } from "../stores/tag-store";
import { store as appStore } from "../stores/app-store"; import { store as appStore } from "../stores/app-store";
import { db } from "./db"; import { db } from "./db";
import { showToast } from "../utils/toast"; import { showToast } from "../utils/toast";
@@ -491,9 +492,8 @@ export function showSignUpDialog() {
export function showTopicDialog() { export function showTopicDialog() {
return showDialog((Dialogs, perform) => ( return showDialog((Dialogs, perform) => (
<Dialogs.TopicDialog <Dialogs.TopicDialog
title={"Create a Topic"} title={"Create topic"}
subtitle={"You can create as many topics as you want."} subtitle={"You can create as many topics as you want."}
icon={Icon.Topic}
onClose={() => { onClose={() => {
perform(false); perform(false);
}} }}
@@ -502,6 +502,7 @@ export function showTopicDialog() {
const notebookId = notebookStore.get().selectedNotebookId; const notebookId = notebookStore.get().selectedNotebookId;
await db.notebooks.notebook(notebookId).topics.add(topic); await db.notebooks.notebook(notebookId).topics.add(topic);
notebookStore.setSelectedNotebook(notebookId); notebookStore.setSelectedNotebook(notebookId);
showToast("success", "Topic created!");
perform(true); perform(true);
}} }}
/> />
@@ -515,17 +516,56 @@ export function showEditTopicDialog(notebookId, topicId) {
if (!topic) return; if (!topic) return;
return showDialog((Dialogs, perform) => ( return showDialog((Dialogs, perform) => (
<Dialogs.TopicDialog <Dialogs.TopicDialog
title={"Edit Topic"} title={"Edit topic"}
subtitle={`You are editing "${topic.title}" topic.`} subtitle={`You are editing "${topic.title}" topic.`}
icon={Icon.Topic} icon={Icon.Topic}
topic={topic} item={topic}
onClose={() => perform(false)} onClose={() => perform(false)}
onAction={async (t) => { onAction={async (t) => {
await db.notebooks await db.notebooks
.notebook(topic.notebookId) .notebook(topic.notebookId)
.topics.add({ ...topic, title: t }); .topics.add({ ...topic, title: t });
notebookStore.setSelectedNotebook(topic.notebookId); notebookStore.setSelectedNotebook(topic.notebookId);
showToast("success", "Topic edited successfully!"); showToast("success", "Topic edited!");
perform(true);
}}
/>
));
}
export function showCreateTagDialog() {
return showDialog((Dialogs, perform) => (
<Dialogs.ItemDialog
title={"Create tag"}
subtitle={"You can create multiple tags."}
onClose={() => {
perform(false);
}}
onAction={async (title) => {
if (!title) return;
await db.tags.add(title);
showToast("success", "Tag created!");
tagStore.refresh();
perform(true);
}}
/>
));
}
export function showEditTagDialog(tagId) {
const tag = db.tags.tag(tagId);
if (!tag) return;
return showDialog((Dialogs, perform) => (
<Dialogs.ItemDialog
title={"Edit tag"}
subtitle={`You are editing #${tag.alias || tag.title}.`}
item={tag}
onClose={() => perform(false)}
onAction={async (title) => {
if (!title) return;
await db.tags.rename(tagId, title);
showToast("success", "Tag edited!");
tagStore.refresh();
perform(true); perform(true);
}} }}
/> />

View File

@@ -52,9 +52,13 @@ export const CREATE_BUTTON_MAP = {
onClick: () => hashNavigate("/notebooks/create"), onClick: () => hashNavigate("/notebooks/create"),
}, },
topics: { topics: {
title: "Add a topic", title: "Create a topic",
onClick: () => hashNavigate(`/topics/create`), onClick: () => hashNavigate(`/topics/create`),
}, },
tags: {
title: "Create a tag",
onClick: () => hashNavigate(`/tags/create`),
},
}; };
export async function introduceFeatures() { export async function introduceFeatures() {

View File

@@ -10,7 +10,7 @@ import MoveDialog from "./movenotedialog";
import PasswordDialog from "./passworddialog"; import PasswordDialog from "./passworddialog";
import RecoveryKeyDialog from "./recoverykeydialog"; import RecoveryKeyDialog from "./recoverykeydialog";
import SignUpDialog from "./signupdialog"; import SignUpDialog from "./signupdialog";
import TopicDialog from "./topicdialog"; import ItemDialog from "./itemdialog";
import SessionExpiredDialog from "./sessionexpireddialog"; import SessionExpiredDialog from "./sessionexpireddialog";
import FeatureDialog from "./feature-dialog"; import FeatureDialog from "./feature-dialog";
@@ -27,7 +27,7 @@ const Dialogs = {
PasswordDialog, PasswordDialog,
RecoveryKeyDialog, RecoveryKeyDialog,
SignUpDialog, SignUpDialog,
TopicDialog, ItemDialog,
SessionExpiredDialog, SessionExpiredDialog,
FeatureDialog, FeatureDialog,
}; };

View File

@@ -0,0 +1,46 @@
import React, { useRef } from "react";
import { Box } from "rebass";
import { Input } from "@rebass/forms";
import Dialog from "./dialog";
import Field from "../field";
function ItemDialog(props) {
return (
<Dialog
isOpen={true}
title={props.title}
description={props.subtitle}
positiveButton={{
props: {
form: "itemForm",
type: "submit",
},
text: props.title,
}}
onClose={props.onClose}
negativeButton={{ text: "Cancel", onClick: props.onClose }}
>
<Box
as="form"
id="itemForm"
onSubmit={(e) => {
e.preventDefault();
const title = e.target.title.value;
props.onAction(title);
}}
>
<Field
required
label="Title"
id="title"
name="title"
autoFocus
data-test-id="item-dialog-title"
defaultValue={props.item?.alias || props.item?.title}
/>
</Box>
</Dialog>
);
}
export default ItemDialog;

View File

@@ -1,36 +0,0 @@
import React, { useRef } from "react";
import { Box } from "rebass";
import { Input } from "@rebass/forms";
import Dialog from "./dialog";
function TopicDialog(props) {
const ref = useRef();
return (
<Dialog
isOpen={true}
title={props.title}
description={props.subtitle}
icon={props.icon}
positiveButton={{
text: "Create topic",
onClick: () => {
props.onAction(ref.current.value);
},
}}
onClose={props.onClose}
negativeButton={{ text: "Cancel", onClick: props.onClose }}
>
<Box my={1}>
<Input
data-test-id="dialog-edit-topic"
autoFocus
ref={ref}
placeholder="Topic title"
defaultValue={props.topic && props.topic.title}
></Input>
</Box>
</Dialog>
);
}
export default TopicDialog;

View File

@@ -148,7 +148,7 @@ function NavigationMenu(props) {
{pins.map((pin) => ( {pins.map((pin) => (
<NavigationItem <NavigationItem
key={pin.id} key={pin.id}
title={pin.title} title={pin.alias || pin.title}
menu={{ menu={{
items: [ items: [
{ {

View File

@@ -1,12 +1,19 @@
import React from "react"; import React from "react";
import ListItem from "../list-item"; import ListItem from "../list-item";
import { navigate } from "../../navigation"; import { hashNavigate, navigate } from "../../navigation";
import { Text } from "rebass"; import { Text } from "rebass";
import { store as appStore } from "../../stores/app-store"; import { store as appStore } from "../../stores/app-store";
import { db } from "../../common/db"; import { db } from "../../common/db";
import * as Icon from "../icons"; import * as Icon from "../icons";
const menuItems = [ const menuItems = [
{
title: () => "Edit",
icon: Icon.Edit,
onClick: ({ tag }) => {
hashNavigate(`/tags/${tag.id}/edit`);
},
},
{ {
title: ({ tag }) => title: ({ tag }) =>
db.settings.isPinned(tag.id) ? "Remove shortcut" : "Create shortcut", db.settings.isPinned(tag.id) ? "Remove shortcut" : "Create shortcut",
@@ -16,13 +23,13 @@ const menuItems = [
]; ];
function Tag({ item, index }) { function Tag({ item, index }) {
const { id, title, noteIds } = item; const { id, title, alias, noteIds } = item;
return ( return (
<ListItem <ListItem
item={item} item={item}
selectable={false} selectable={false}
index={index} index={index}
title={<TagNode title={title} />} title={<TagNode title={alias || title} />}
footer={ footer={
<Text mt={1} variant="subBody"> <Text mt={1} variant="subBody">
{noteIds.length} notes {noteIds.length} notes

View File

@@ -2,6 +2,8 @@ import React from "react";
import Vault from "../common/vault"; import Vault from "../common/vault";
import { import {
showBuyDialog, showBuyDialog,
showCreateTagDialog,
showEditTagDialog,
showEmailVerificationDialog, showEmailVerificationDialog,
} from "../common/dialog-controller"; } from "../common/dialog-controller";
import { import {
@@ -47,6 +49,12 @@ const hashroutes = {
"/notebooks/:notebookId/topics/:topicId/edit": ({ notebookId, topicId }) => { "/notebooks/:notebookId/topics/:topicId/edit": ({ notebookId, topicId }) => {
showEditTopicDialog(notebookId, topicId); showEditTopicDialog(notebookId, topicId);
}, },
"/tags/create": () => {
showCreateTagDialog();
},
"/tags/:tagId/edit": ({ tagId }) => {
showEditTagDialog(tagId);
},
"/notes/create": () => { "/notes/create": () => {
closeOpenedDialog(); closeOpenedDialog();
hashNavigate("/notes/create", { addNonce: true, replace: true }); hashNavigate("/notes/create", { addNonce: true, replace: true });