Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
b2c22977
Commit
b2c22977
authored
Sep 30, 2022
by
steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: update memo editor with uploading resources
parent
c0edb72b
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
243 additions
and
235 deletions
+243
-235
Editor.tsx
web/src/components/Editor/Editor.tsx
+5
-47
MemoEditor.tsx
web/src/components/MemoEditor.tsx
+151
-136
api.ts
web/src/helpers/api.ts
+14
-0
editor.less
web/src/less/editor.less
+0
-40
memo-editor.less
web/src/less/memo-editor.less
+72
-12
memoService.ts
web/src/services/memoService.ts
+1
-0
No files found.
web/src/components/Editor/Editor.tsx
View file @
b2c22977
import
{
forwardRef
,
ReactNode
,
useCallback
,
useEffect
,
useImperativeHandle
,
useRef
}
from
"react"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
useRefresh
from
"../../hooks/useRefresh"
;
import
"../../less/editor.less"
;
export
interface
EditorRefActions
{
element
:
HTMLTextAreaElement
;
focus
:
FunctionType
;
insertText
:
(
text
:
string
)
=>
void
;
setContent
:
(
text
:
string
)
=>
void
;
...
...
@@ -12,29 +10,19 @@ export interface EditorRefActions {
getCursorPosition
:
()
=>
number
;
}
interface
Editor
Props
{
interface
Props
{
className
:
string
;
initialContent
:
string
;
placeholder
:
string
;
fullscreen
:
boolean
;
showConfirmBtn
:
boolean
;
tools
?:
ReactNode
;
on
ConfirmBtnClick
:
(
content
:
string
)
=>
void
;
on
Paste
:
(
event
:
React
.
ClipboardEvent
)
=>
void
;
onContentChange
:
(
content
:
string
)
=>
void
;
}
// eslint-disable-next-line react/display-name
const
Editor
=
forwardRef
((
props
:
EditorProps
,
ref
:
React
.
ForwardedRef
<
EditorRefActions
>
)
=>
{
const
{
className
,
initialContent
,
placeholder
,
fullscreen
,
showConfirmBtn
,
onConfirmBtnClick
:
handleConfirmBtnClickCallback
,
onContentChange
:
handleContentChangeCallback
,
}
=
props
;
const
{
t
}
=
useTranslation
();
const
Editor
=
forwardRef
((
props
:
Props
,
ref
:
React
.
ForwardedRef
<
EditorRefActions
>
)
=>
{
const
{
className
,
initialContent
,
placeholder
,
fullscreen
,
onPaste
,
onContentChange
:
handleContentChangeCallback
}
=
props
;
const
editorRef
=
useRef
<
HTMLTextAreaElement
>
(
null
);
const
refresh
=
useRefresh
();
...
...
@@ -54,7 +42,6 @@ const Editor = forwardRef((props: EditorProps, ref: React.ForwardedRef<EditorRef
useImperativeHandle
(
ref
,
()
=>
({
element
:
editorRef
.
current
as
HTMLTextAreaElement
,
focus
:
()
=>
{
editorRef
.
current
?.
focus
();
},
...
...
@@ -94,25 +81,6 @@ const Editor = forwardRef((props: EditorProps, ref: React.ForwardedRef<EditorRef
refresh
();
},
[]);
const
handleEditorKeyDown
=
useCallback
((
event
:
React
.
KeyboardEvent
<
HTMLTextAreaElement
>
)
=>
{
event
.
stopPropagation
();
if
(
event
.
code
===
"Enter"
)
{
if
(
event
.
metaKey
||
event
.
ctrlKey
)
{
handleCommonConfirmBtnClick
();
}
}
},
[]);
const
handleCommonConfirmBtnClick
=
useCallback
(()
=>
{
if
(
!
editorRef
.
current
)
{
return
;
}
handleConfirmBtnClickCallback
(
editorRef
.
current
.
value
);
editorRef
.
current
.
value
=
""
;
},
[]);
return
(
<
div
className=
{
"common-editor-wrapper "
+
className
}
>
<
textarea
...
...
@@ -120,19 +88,9 @@ const Editor = forwardRef((props: EditorProps, ref: React.ForwardedRef<EditorRef
rows=
{
1
}
placeholder=
{
placeholder
}
ref=
{
editorRef
}
onPaste=
{
onPaste
}
onInput=
{
handleEditorInput
}
onKeyDown=
{
handleEditorKeyDown
}
></
textarea
>
<
div
className=
"common-tools-wrapper"
>
<
div
className=
"common-tools-container"
>
{
props
.
tools
!==
undefined
&&
props
.
tools
}
</
div
>
<
div
className=
"btns-container"
>
{
showConfirmBtn
&&
(
<
button
className=
"action-btn confirm-btn"
disabled=
{
editorRef
.
current
?.
value
===
""
}
onClick=
{
handleCommonConfirmBtnClick
}
>
{
t
(
"editor.save"
)
}
<
span
className=
"icon-text"
>
✍️
</
span
>
</
button
>
)
}
</
div
>
</
div
>
</
div
>
);
});
...
...
web/src/components/MemoEditor.tsx
View file @
b2c22977
This diff is collapsed.
Click to expand it.
web/src/helpers/api.ts
View file @
b2c22977
...
...
@@ -133,6 +133,20 @@ export function deleteResourceById(id: ResourceId) {
return
axios
.
delete
(
`/api/resource/
${
id
}
`
);
}
export
function
getMemoResourceList
(
memoId
:
MemoId
)
{
return
axios
.
get
<
ResponseObject
<
Resource
[]
>>
(
`/api/memo/
${
memoId
}
/resource`
);
}
export
function
upsertMemoResource
(
memoId
:
MemoId
,
resourceId
:
ResourceId
)
{
return
axios
.
post
<
ResponseObject
<
Resource
>>
(
`/api/memo/
${
memoId
}
/resource`
,
{
resourceId
,
});
}
export
function
deleteMemoResource
(
memoId
:
MemoId
,
resourceId
:
ResourceId
)
{
return
axios
.
delete
(
`/api/memo/
${
memoId
}
/resource/
${
resourceId
}
`
);
}
export
function
getTagList
(
tagFind
?:
TagFind
)
{
const
queryList
=
[];
if
(
tagFind
?.
creatorId
)
{
...
...
web/src/less/editor.less
View file @
b2c22977
...
...
@@ -25,44 +25,4 @@
}
}
}
> .common-tools-wrapper {
@apply w-full flex flex-row justify-between items-center;
> .common-tools-container {
@apply flex flex-row justify-start items-center;
> .action-btn {
@apply flex flex-row justify-center items-center p-1 w-auto h-auto mr-1 select-none rounded cursor-pointer opacity-60 hover:opacity-90 hover:bg-gray-300 hover:shadow;
> .icon-img {
@apply w-5 h-5 mx-auto flex flex-row justify-center items-center;
}
> .tip-text {
@apply hidden ml-1 text-xs leading-5 text-gray-700 border border-gray-300 rounded-xl px-2;
}
}
}
> .btns-container {
@apply grow-0 shrink-0 flex flex-row justify-end items-center;
> .action-btn {
@apply border-none select-none cursor-pointer py-1 px-3 rounded text-sm hover:opacity-80;
}
> .cancel-btn {
@apply text-gray-500 bg-transparent mr-2;
}
> .confirm-btn {
@apply shadow cursor-pointer px-3 py-0 leading-8 bg-green-600 text-white text-sm hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-60;
> .icon-text {
@apply text-base ml-1;
}
}
}
}
}
web/src/less/memo-editor.less
View file @
b2c22977
...
...
@@ -63,8 +63,18 @@
> .memo-editor {
@apply flex flex-col justify-start items-start relative w-full h-auto bg-white;
}
> .common-tools-wrapper {
@apply w-full flex flex-row justify-between items-center;
> .common-tools-container {
@apply flex flex-row justify-start items-center;
> .action-btn {
@apply flex flex-row justify-center items-center p-1 w-auto h-auto mr-1 select-none rounded cursor-pointer opacity-60 hover:opacity-90 hover:bg-gray-300 hover:shadow;
.tag-action {
&
.tag-action {
@apply relative;
&:hover {
...
...
@@ -85,6 +95,56 @@
}
}
}
> .icon-img {
@apply w-5 h-5 mx-auto flex flex-row justify-center items-center;
}
> .tip-text {
@apply hidden ml-1 text-xs leading-5 text-gray-700 border border-gray-300 rounded-xl px-2;
}
}
}
> .btns-container {
@apply grow-0 shrink-0 flex flex-row justify-end items-center;
> .action-btn {
@apply border-none select-none cursor-pointer py-1 px-3 rounded text-sm hover:opacity-80;
}
> .cancel-btn {
@apply text-gray-500 bg-transparent mr-2;
}
> .confirm-btn {
@apply shadow cursor-pointer px-3 py-0 leading-8 bg-green-600 text-white text-sm hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-60;
> .icon-text {
@apply text-base ml-1;
}
}
}
}
> .resource-list-wrapper {
@apply w-full flex flex-row justify-start flex-wrap;
> .resource-container {
@apply mt-1 mr-1 flex flex-row justify-start items-center flex-nowrap bg-gray-50 px-2 py-1 rounded cursor-pointer hover:bg-gray-100;
> .icon-img {
@apply w-4 h-auto mr-1 text-gray-500;
}
> .name-text {
@apply text-gray-500 text-sm max-w-xs truncate font-mono;
}
> .close-icon {
@apply w-4 h-auto ml-1 text-gray-500 hover:text-gray-800;
}
}
}
.emoji-picker-react {
...
...
web/src/services/memoService.ts
View file @
b2c22977
...
...
@@ -93,6 +93,7 @@ const memoService = {
const
{
data
}
=
(
await
api
.
createMemo
(
memoCreate
)).
data
;
const
memo
=
convertResponseModelMemo
(
data
);
store
.
dispatch
(
createMemo
(
memo
));
return
memo
;
},
patchMemo
:
async
(
memoPatch
:
MemoPatch
):
Promise
<
Memo
>
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment