From 74712b3bc665528a35a43f68dba23b52efe561e6 Mon Sep 17 00:00:00 2001 From: Dinesh Singh Date: Sat, 12 Nov 2022 18:34:47 +0530 Subject: [PATCH 1/3] Public note copy url fix --- apps/webapp/src/Components/EditorInfobar/Metadata.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/webapp/src/Components/EditorInfobar/Metadata.tsx b/apps/webapp/src/Components/EditorInfobar/Metadata.tsx index 65303470f..9518024d3 100644 --- a/apps/webapp/src/Components/EditorInfobar/Metadata.tsx +++ b/apps/webapp/src/Components/EditorInfobar/Metadata.tsx @@ -82,6 +82,10 @@ const Metadata = ({ return usersWithStatus }, [location, activeUsers, mentionable, namespaceId, nodeId]) + const onNoteShareClick = (event: React.MouseEvent) => { + openShareModal('permission', 'note', nodeId) + } + if (!publicMetadata && (content === undefined || content.metadata === undefined || metadata === undefined || isEmpty)) return null @@ -111,11 +115,14 @@ const Metadata = ({ {!publicMetadata && !hideShareDetails && ( - }> + } + > openShareModal('permission', 'note', nodeId)} + onClick={onNoteShareClick} label="Share" /> From 99d15221ddd376b8a4574167623cdf06a169067d Mon Sep 17 00:00:00 2001 From: Dinesh Singh Date: Sat, 12 Nov 2022 18:47:47 +0530 Subject: [PATCH 2/3] Table elements rendering fix in Preview Components --- .../Components/EditorPreviewComponents.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/webapp/src/Editor/Components/EditorPreviewComponents.tsx b/apps/webapp/src/Editor/Components/EditorPreviewComponents.tsx index 40e735a6c..857eded87 100644 --- a/apps/webapp/src/Editor/Components/EditorPreviewComponents.tsx +++ b/apps/webapp/src/Editor/Components/EditorPreviewComponents.tsx @@ -1,13 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ - import { createPlateUI, withProps } from '@udecode/plate' import { StyledElement } from '@udecode/plate-styled-components' -import Todo from '../../Components/Todo' -import { QuickLinkElement } from './QuickLink/QuickLinkElement' -import { LinkElement, MediaEmbedElement, TableWrapper } from '@mexit/shared' -import InlineBlock from './InlineBlock' -import TagWrapper from '../../Components/Editor/TagWrapper' import { ELEMENT_ILINK, ELEMENT_INLINE_BLOCK, @@ -20,10 +14,16 @@ import { ELEMENT_TASK_VIEW_LINK, ELEMENT_TODO_LI } from '@mexit/core' +import { LinkElement, MediaEmbedElement, TableWrapper } from '@mexit/shared' + +import TagWrapper from '../../Components/Editor/TagWrapper' +import Todo from '../../Components/Todo' +import InlineBlock from './InlineBlock' import { MentionElement } from './Mentions/MentionElement' +import { QuickLinkElement } from './QuickLink/QuickLinkElement' import TaskViewLink from './TaskViewLink' -export const editorPreviewComponents = { +export const editorPreviewComponents = createPlateUI({ [ELEMENT_LINK]: withProps(LinkElement, { as: 'a' }), @@ -41,7 +41,7 @@ export const editorPreviewComponents = { [ELEMENT_TABLE]: TableWrapper, [ELEMENT_MENTION]: MentionElement as any, [ELEMENT_TASK_VIEW_LINK]: TaskViewLink as any -} +}) const components = createPlateUI({ ...editorPreviewComponents, From af511387c2421322561245bf7af0262f00415f84 Mon Sep 17 00:00:00 2001 From: Dinesh Singh Date: Sat, 12 Nov 2022 20:57:06 +0530 Subject: [PATCH 3/3] ILinks undefined in Highlights, todos in local storage --- apps/webapp/src/Editor/Plugins/todoUtils.ts | 22 +- apps/webapp/src/Hooks/useUpdater.ts | 6 +- apps/webapp/src/Stores/useTodoStore.ts | 269 +++++++++--------- .../src/Stores/highlightStoreConstructor.ts | 11 +- 4 files changed, 167 insertions(+), 141 deletions(-) diff --git a/apps/webapp/src/Editor/Plugins/todoUtils.ts b/apps/webapp/src/Editor/Plugins/todoUtils.ts index 93ad0dd51..1b4ff7d2f 100644 --- a/apps/webapp/src/Editor/Plugins/todoUtils.ts +++ b/apps/webapp/src/Editor/Plugins/todoUtils.ts @@ -1,5 +1,6 @@ -import { getMentionsFromContent, getTagsFromContent, NodeEditorContent, TodoType } from "@mexit/core" -import { createTodo } from "../../Stores/useTodoStore" +import { ELEMENT_TODO_LI, getMentionsFromContent, getTagsFromContent, NodeEditorContent, TodoType } from '@mexit/core' + +import { createTodo } from '../../Stores/useTodoStore' export const createDefaultTodo = (nodeid: string, content?: NodeEditorContent): TodoType => { const block = content?.[0] @@ -8,5 +9,20 @@ export const createDefaultTodo = (nodeid: string, content?: NodeEditorContent): const todo = createTodo(nodeid, block.id, content, tags, mentions) - return todo; + return todo +} + +export const getTodoMetadata = (content: NodeEditorContent) => { + if (!content) return + + const block = content[0] + + if (block && block.type === ELEMENT_TODO_LI) { + const { priority, status, ...rest } = block + + return { + priority, + status + } + } } diff --git a/apps/webapp/src/Hooks/useUpdater.ts b/apps/webapp/src/Hooks/useUpdater.ts index 9f99e728a..7e7c7c3d2 100644 --- a/apps/webapp/src/Hooks/useUpdater.ts +++ b/apps/webapp/src/Hooks/useUpdater.ts @@ -1,4 +1,4 @@ -import { getTodosFromContent, NodeEditorContent } from '@mexit/core' +import { getTodosFromContent, mog, NodeEditorContent } from '@mexit/core' import { useSlashCommands } from '@mexit/shared' import { useContentStore } from '../Stores/useContentStore' @@ -31,7 +31,9 @@ export const useUpdater = () => { if (metadata) setMetadata(noteId, metadata) updateLinksFromContent(noteId, content) updateTagsFromContent(noteId, content) - updateNodeTodos(noteId, getTodosFromContent(content)) + const todos = getTodosFromContent(content) + mog('CONTENT FOR TODOS', { todos }) + updateNodeTodos(noteId, todos) updateDocument('node', noteId, content) } diff --git a/apps/webapp/src/Stores/useTodoStore.ts b/apps/webapp/src/Stores/useTodoStore.ts index 67fd78123..b0af3dfd0 100644 --- a/apps/webapp/src/Stores/useTodoStore.ts +++ b/apps/webapp/src/Stores/useTodoStore.ts @@ -1,5 +1,5 @@ import create from 'zustand' -import { persist } from 'zustand/middleware' +import { devtools, persist } from 'zustand/middleware' import { NodeEditorContent, @@ -9,11 +9,12 @@ import { TodosType, TodoType, convertContentToRawText, - IDBStorage, getTagsFromContent, - getMentionsFromContent + getMentionsFromContent, + mog } from '@mexit/core' +import { getTodoMetadata } from '../Editor/Plugins/todoUtils' import { useReminderStore } from './useReminderStore' export const createTodo = ( @@ -23,14 +24,15 @@ export const createTodo = ( mentions: string[] = [], tags: string[] = [] ) => { - // mog('createTodo', { nodeid, todoId, content }) + const metaData = getTodoMetadata(content) + mog('CONTENT OF CREATE', { content }) return { id: todoId, nodeid, content, metadata: { - status: TodoStatus.todo, - priority: PriorityType.noPriority + status: metaData?.status ?? TodoStatus.todo, + priority: metaData?.priority ?? PriorityType.noPriority }, mentions, tags, @@ -44,7 +46,6 @@ type TodoStoreType = { todos: TodosType clearTodos: () => void initTodos: (todos: TodosType) => void - // * Update specific node todos setNodeTodos: (nodeid: string, todos: Array) => void addTodoInNode: (nodeid: string, todo: TodoType) => void @@ -60,135 +61,141 @@ type TodoStoreType = { const useTodoStore = create( persist( - (set, get) => ({ - todos: {}, - initTodos: (todos) => { - if (todos) { - set({ todos }) - } - }, - clearTodos: () => set({ todos: {} }), + devtools( + (set, get) => ({ + todos: {}, + initTodos: (todos) => { + if (todos) { + set({ todos }) + } + }, + clearTodos: () => set({ todos: {} }), + + addTodoInNode: (nodeid, todo) => { + if (!nodeid) { + return + } + const todos = get().todos ?? {} + + const nodeTodos = todos?.[nodeid] ?? [] + set({ todos: { ...todos, [nodeid]: [todo, ...nodeTodos] } }) + }, + getTodoOfNodeWithoutCreating: (nodeid, todoId) => { + const todo = get().todos?.[nodeid]?.find((todo) => todo.id === todoId && nodeid === todo.nodeid) + return todo + }, - addTodoInNode: (nodeid, todo) => { - if (!nodeid) { - return - } - const todos = get().todos ?? {} - - const nodeTodos = todos?.[nodeid] ?? [] - set({ todos: { ...todos, [nodeid]: [todo, ...nodeTodos] } }) - }, - getTodoOfNodeWithoutCreating: (nodeid, todoId) => { - const todo = get().todos?.[nodeid]?.find((todo) => todo.id === todoId && nodeid === todo.nodeid) - return todo - }, - - getTodoOfNode: (nodeid, todoId) => { - const todo = get().todos?.[nodeid]?.find((todo) => todo.id === todoId && nodeid === todo.nodeid) - // mog('getTodoOfNode', { nodeid, todoId, todo }) - if (!todo) { - const newTodo = createTodo(nodeid, todoId) - if (!nodeid) return newTodo - get().addTodoInNode(nodeid, newTodo) - - return newTodo - } + getTodoOfNode: (nodeid, todoId) => { + const todo = get().todos?.[nodeid]?.find((todo) => todo.id === todoId && nodeid === todo.nodeid) + mog('getTodoOfNode', { nodeid, todoId, todo, todos: get().todos }) + if (!todo) { + const newTodo = createTodo(nodeid, todoId) + if (!nodeid) return newTodo + get().addTodoInNode(nodeid, newTodo) - return todo - }, - - getAllTodos: () => { - const allTodos = Object.entries(get().todos).reduce((acc, [nodeid, todos]) => { - const newTodos = todos.filter((todo) => { - // TODO: Find a faster way to check for empty content - const text = convertContentToRawText(todo.content).trim() - // mog('empty todo check', { text, nodeid, todo }) - if (text === '') { - return false - } - if (todo.content === defaultContent.content) return false - return true + return newTodo + } + + return todo + }, + + getAllTodos: () => { + const allTodos = Object.entries(get().todos).reduce((acc, [nodeid, todos]) => { + const newTodos = todos.filter((todo) => { + // TODO: Find a faster way to check for empty content + const text = convertContentToRawText(todo.content).trim() + // mog('empty todo check', { text, nodeid, todo }) + if (text === '') { + return false + } + if (todo.content === defaultContent.content) return false + return true + }) + + return { ...acc, [nodeid]: newTodos } + }, {}) + return allTodos + }, + + setNodeTodos: (nodeid, todos) => { + // mog('setNodeTodos', { nodeid, todos }) + if (!nodeid) return + const currentTodos = get().todos ?? {} + const newTodos = { ...currentTodos, [nodeid]: todos } + set({ todos: newTodos }) + }, + updateTodoOfNode: (nodeid, todo) => { + // mog('updateNodeTodos', { nodeid, todo }) + if (!nodeid) return + const currentTodos = get().todos ?? {} + + const todos = currentTodos?.[nodeid] ?? [] + const newTodos = todos.map((t) => + t.id === todo.id && todo.nodeid === nodeid ? { ...todo, updatedAt: Date.now() } : t + ) + // mog('TODO UPDATE', { newTodos, nodeid, todos }) + set({ todos: { ...currentTodos, [nodeid]: newTodos } }) + }, + replaceContentOfTodos: (nodeid, todosContent) => { + // mog('replaceContentOfTodos', { nodeid, todosContent }) + if (!nodeid) return + const todos = get().todos ?? {} + + if (todosContent.length === 0) { + if (!todos[nodeid]) return + + delete todos[nodeid] + set({ todos }) + + return + } + + const nTodo = todos[nodeid] ?? [] + const nodeTodos = todosContent.map((content) => { + const todo = nTodo.find((todo) => todo.id === content.id && nodeid === todo.nodeid) + const tags = getTagsFromContent([content]) + const mentions = getMentionsFromContent([content]) + // mog('replaceContent', { nodeid, tags, mentions, todosContent, nodeTodos, todo, content }) + return todo + ? { ...todo, mentions, tags, content: [content] } + : createTodo(nodeid, content.id, [content], mentions, tags) }) - return { ...acc, [nodeid]: newTodos } - }, {}) - return allTodos - }, - - setNodeTodos: (nodeid, todos) => { - // mog('setNodeTodos', { nodeid, todos }) - if (!nodeid) return - const currentTodos = get().todos ?? {} - const newTodos = { ...currentTodos, [nodeid]: todos } - set({ todos: newTodos }) - }, - updateTodoOfNode: (nodeid, todo) => { - // mog('updateNodeTodos', { nodeid, todo }) - if (!nodeid) return - const currentTodos = get().todos ?? {} - - const todos = currentTodos?.[nodeid] ?? [] - const newTodos = todos.map((t) => - t.id === todo.id && todo.nodeid === nodeid ? { ...todo, updatedAt: Date.now() } : t - ) - // mog('currentTodos', { newTodos, nodeid, todos }) - set({ todos: { ...currentTodos, [nodeid]: newTodos } }) - }, - replaceContentOfTodos: (nodeid, todosContent) => { - // mog('replaceContentOfTodos', { nodeid, todosContent }) - if (!nodeid) return - const todos = get().todos ?? {} - - if (todosContent.length === 0) { - if (!todos[nodeid]) return - - delete todos[nodeid] - set({ todos }) - - return + const leftOutTodos = nTodo.filter((todo) => !nodeTodos.find((t) => t.id === todo.id && nodeid === t.nodeid)) + + const reminders = useReminderStore.getState().reminders + const setReminders = useReminderStore.getState().setReminders + const newReminders = reminders.filter((reminder) => !leftOutTodos.find((todo) => todo.id === reminder.todoid)) + + setReminders(newReminders) + const newtodos = { ...todos, [nodeid]: nodeTodos } + mog('NEW TODO', { newtodos }) + set({ todos: newtodos }) + }, + updatePriorityOfTodo: (nodeid, todoId, priority) => { + // mog('updatePro', { nodeid, todoId, priority }) + if (!nodeid) return + const todo = get().getTodoOfNodeWithoutCreating(nodeid, todoId) + if (!todo) return + + const newTodo = { ...todo, metadata: { ...todo.metadata, priority } } + get().updateTodoOfNode(nodeid, newTodo) + }, + updateStatusOfTodo: (nodeid, todoId, status) => { + // mog('updateSta', { nodeid, todoId, status }) + if (!nodeid) return + const todo = get().getTodoOfNodeWithoutCreating(nodeid, todoId) + if (!todo) return + + const newTodo = { ...todo, metadata: { ...todo.metadata, status } } + get().updateTodoOfNode(nodeid, newTodo) } - - const nTodo = todos[nodeid] ?? [] - const nodeTodos = todosContent.map((content) => { - const todo = nTodo.find((todo) => todo.id === content.id && nodeid === todo.nodeid) - const tags = getTagsFromContent([content]) - const mentions = getMentionsFromContent([content]) - // mog('replaceContent', { nodeid, tags, mentions, todosContent, nodeTodos, todo, content }) - return todo - ? { ...todo, mentions, tags, content: [content] } - : createTodo(nodeid, content.id, [content], mentions, tags) - }) - - const leftOutTodos = nTodo.filter((todo) => !nodeTodos.find((t) => t.id === todo.id && nodeid === t.nodeid)) - - const reminders = useReminderStore.getState().reminders - const setReminders = useReminderStore.getState().setReminders - const newReminders = reminders.filter((reminder) => !leftOutTodos.find((todo) => todo.id === reminder.todoid)) - - setReminders(newReminders) - const newtodos = { ...todos, [nodeid]: nodeTodos } - set({ todos: newtodos }) - }, - updatePriorityOfTodo: (nodeid, todoId, priority) => { - // mog('updatePro', { nodeid, todoId, priority }) - if (!nodeid) return - const todo = get().getTodoOfNodeWithoutCreating(nodeid, todoId) - if (!todo) return - - const newTodo = { ...todo, metadata: { ...todo.metadata, priority } } - get().updateTodoOfNode(nodeid, newTodo) - }, - updateStatusOfTodo: (nodeid, todoId, status) => { - // mog('updateSta', { nodeid, todoId, status }) - if (!nodeid) return - const todo = get().getTodoOfNodeWithoutCreating(nodeid, todoId) - if (!todo) return - - const newTodo = { ...todo, metadata: { ...todo.metadata, status } } - get().updateTodoOfNode(nodeid, newTodo) - } - }), - { name: 'mexit-todo-store', getStorage: () => IDBStorage } + }), + { name: 'Todo Store Web' } + ), + { + name: 'mexit-todo-store' + } ) ) diff --git a/libs/core/src/Stores/highlightStoreConstructor.ts b/libs/core/src/Stores/highlightStoreConstructor.ts index e97b1179a..cb6c1e6c7 100644 --- a/libs/core/src/Stores/highlightStoreConstructor.ts +++ b/libs/core/src/Stores/highlightStoreConstructor.ts @@ -32,13 +32,14 @@ export const highlightStoreConstructor = (set, get) => ({ initHighlights: (ilinks, contents) => { const highlighted = {} - ilinks.forEach((ilink) => { + ilinks?.forEach((ilink) => { contents[ilink.nodeid]?.content?.forEach(function (block) { - if (block?.metadata?.elementMetadata && this) { - highlighted[block.metadata.elementMetadata.sourceUrl] = { - ...highlighted[block.metadata.elementMetadata.sourceUrl], + const elementMetadata = block?.metadata?.elementMetadata + if (elementMetadata?.sourceURL && this) { + highlighted[elementMetadata.sourceUrl] = { + ...highlighted[elementMetadata.sourceUrl], [block.id]: { - elementMetadata: block.metadata.elementMetadata, + elementMetadata, nodeId: this.nodeid, shared: !!this?.owner }