mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
add FolderSelect
This commit is contained in:
267
browser/main/Detail/FolderSelect.js
Normal file
267
browser/main/Detail/FolderSelect.js
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
import React, { PropTypes } from 'react'
|
||||||
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
|
import styles from './FolderSelect.styl'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
class FolderSelect extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
status: 'IDLE',
|
||||||
|
search: '',
|
||||||
|
optionIndex: -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this.value = this.props.value
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate () {
|
||||||
|
this.value = this.props.value
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick (e) {
|
||||||
|
this.setState({
|
||||||
|
status: 'SEARCH',
|
||||||
|
optionIndex: -1
|
||||||
|
}, () => {
|
||||||
|
this.refs.search.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFocus (e) {
|
||||||
|
if (this.state.status === 'IDLE') {
|
||||||
|
this.setState({
|
||||||
|
status: 'FOCUS'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlur (e) {
|
||||||
|
if (this.state.status === 'FOCUS') {
|
||||||
|
this.setState({
|
||||||
|
status: 'IDLE'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyDown (e) {
|
||||||
|
switch (e.keyCode) {
|
||||||
|
case 13:
|
||||||
|
if (this.state.status === 'FOCUS') {
|
||||||
|
this.setState({
|
||||||
|
status: 'SEARCH',
|
||||||
|
optionIndex: -1
|
||||||
|
}, () => {
|
||||||
|
this.refs.search.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 40:
|
||||||
|
case 38:
|
||||||
|
if (this.state.status === 'FOCUS') {
|
||||||
|
this.setState({
|
||||||
|
status: 'SEARCH',
|
||||||
|
optionIndex: 0
|
||||||
|
}, () => {
|
||||||
|
this.refs.search.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 9:
|
||||||
|
if (e.shiftKey) {
|
||||||
|
e.preventDefault()
|
||||||
|
let tabbable = document.querySelectorAll('a:not([disabled]), button:not([disabled]), input[type=text]:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])')
|
||||||
|
let previousEl = tabbable[Array.prototype.indexOf.call(tabbable, this.refs.root) - 1]
|
||||||
|
if (previousEl != null) previousEl.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearchInputBlur (e) {
|
||||||
|
if (e.relatedTarget !== this.refs.root) {
|
||||||
|
this.setState({
|
||||||
|
status: 'IDLE'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearchInputChange (e) {
|
||||||
|
let { folders } = this.props
|
||||||
|
let search = this.refs.search.value
|
||||||
|
let optionIndex = search.length > 0
|
||||||
|
? _.findIndex(folders, (folder) => {
|
||||||
|
return folder.name.match(new RegExp('^' + _.escapeRegExp(search), 'i'))
|
||||||
|
})
|
||||||
|
: -1
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
search: this.refs.search.value,
|
||||||
|
optionIndex: optionIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearchInputKeyDown (e) {
|
||||||
|
switch (e.keyCode) {
|
||||||
|
case 40:
|
||||||
|
e.stopPropagation()
|
||||||
|
this.nextOption()
|
||||||
|
break
|
||||||
|
case 38:
|
||||||
|
e.stopPropagation()
|
||||||
|
this.previousOption()
|
||||||
|
break
|
||||||
|
case 13:
|
||||||
|
e.stopPropagation()
|
||||||
|
this.selectOption()
|
||||||
|
break
|
||||||
|
case 27:
|
||||||
|
e.stopPropagation()
|
||||||
|
this.setState({
|
||||||
|
status: 'FOCUS'
|
||||||
|
}, () => {
|
||||||
|
this.refs.root.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextOption () {
|
||||||
|
let { folders } = this.props
|
||||||
|
let { optionIndex } = this.state
|
||||||
|
|
||||||
|
optionIndex++
|
||||||
|
if (optionIndex >= folders.length) optionIndex = 0
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
optionIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
previousOption () {
|
||||||
|
let { folders } = this.props
|
||||||
|
let { optionIndex } = this.state
|
||||||
|
|
||||||
|
optionIndex--
|
||||||
|
if (optionIndex < 0) optionIndex = folders.length - 1
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
optionIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
selectOption () {
|
||||||
|
let { folders } = this.props
|
||||||
|
let optionIndex = this.state.optionIndex
|
||||||
|
|
||||||
|
let folder = folders[optionIndex]
|
||||||
|
if (folder != null) {
|
||||||
|
this.setState({
|
||||||
|
status: 'FOCUS'
|
||||||
|
}, () => {
|
||||||
|
this.setValue(folder.key)
|
||||||
|
this.refs.root.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOptionClick (folderKey) {
|
||||||
|
return (e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
this.setState({
|
||||||
|
status: 'FOCUS'
|
||||||
|
}, () => {
|
||||||
|
this.setValue(folderKey)
|
||||||
|
this.refs.root.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue (folderKey) {
|
||||||
|
this.value = folderKey
|
||||||
|
this.props.onChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
let { className, folders, value } = this.props
|
||||||
|
let currentFolder = _.find(folders, {key: value})
|
||||||
|
let optionList = folders.map((folder, index) => {
|
||||||
|
return (
|
||||||
|
<div styleName={index === this.state.optionIndex
|
||||||
|
? 'search-optionList-item--active'
|
||||||
|
: 'search-optionList-item'
|
||||||
|
}
|
||||||
|
key={folder.key}
|
||||||
|
onClick={(e) => this.handleOptionClick(folder.key)(e)}
|
||||||
|
>
|
||||||
|
<i style={{color: folder.color}}
|
||||||
|
className='fa fa-fw fa-cube'
|
||||||
|
/>
|
||||||
|
{folder.name}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={_.isString(className)
|
||||||
|
? 'FolderSelect ' + className
|
||||||
|
: 'FolderSelect'
|
||||||
|
}
|
||||||
|
styleName={this.state.status === 'SEARCH'
|
||||||
|
? 'root--search'
|
||||||
|
: this.state.status === 'FOCUS'
|
||||||
|
? 'root--focus'
|
||||||
|
: 'root'
|
||||||
|
}
|
||||||
|
ref='root'
|
||||||
|
tabIndex='0'
|
||||||
|
onClick={(e) => this.handleClick(e)}
|
||||||
|
onFocus={(e) => this.handleFocus(e)}
|
||||||
|
onBlur={(e) => this.handleBlur(e)}
|
||||||
|
onKeyDown={(e) => this.handleKeyDown(e)}
|
||||||
|
>
|
||||||
|
{this.state.status === 'SEARCH'
|
||||||
|
? <div styleName='search'>
|
||||||
|
<input styleName='search-input'
|
||||||
|
ref='search'
|
||||||
|
value={this.state.search}
|
||||||
|
placeholder='Folder...'
|
||||||
|
onChange={(e) => this.handleSearchInputChange(e)}
|
||||||
|
onBlur={(e) => this.handleSearchInputBlur(e)}
|
||||||
|
onKeyDown={(e) => this.handleSearchInputKeyDown(e)}
|
||||||
|
/>
|
||||||
|
<div styleName='search-optionList'
|
||||||
|
ref='optionList'
|
||||||
|
>
|
||||||
|
{optionList}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
: <div styleName='idle'>
|
||||||
|
<div styleName='idle-label'>
|
||||||
|
<i style={{color: currentFolder.color}}
|
||||||
|
className='fa fa-fw fa-cube'
|
||||||
|
/>
|
||||||
|
{currentFolder.name}
|
||||||
|
</div>
|
||||||
|
<i styleName='idle-caret' className='fa fa-fw fa-caret-down'/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderSelect.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
value: PropTypes.string,
|
||||||
|
folders: PropTypes.arrayOf(PropTypes.shape({
|
||||||
|
key: PropTypes.string,
|
||||||
|
name: PropTypes.string,
|
||||||
|
color: PropTypes.string
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CSSModules(FolderSelect, styles)
|
||||||
74
browser/main/Detail/FolderSelect.styl
Normal file
74
browser/main/Detail/FolderSelect.styl
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
.root
|
||||||
|
position relative
|
||||||
|
border solid 1px transparent
|
||||||
|
line-height 34px
|
||||||
|
vertical-align middle
|
||||||
|
border-radius 5px
|
||||||
|
transition 0.15s
|
||||||
|
user-select none
|
||||||
|
&:hover
|
||||||
|
background-color white
|
||||||
|
border-color $ui-borderColor
|
||||||
|
|
||||||
|
.root--search, .root--focus
|
||||||
|
@extend .root
|
||||||
|
background-color white
|
||||||
|
border-color $ui-input--focus-borderColor
|
||||||
|
&:hover
|
||||||
|
background-color white
|
||||||
|
border-color $ui-input--focus-borderColor
|
||||||
|
|
||||||
|
.idle
|
||||||
|
position relative
|
||||||
|
cursor pointer
|
||||||
|
.idle-label
|
||||||
|
absolute left top
|
||||||
|
padding 0 0 0 5px
|
||||||
|
right 20px
|
||||||
|
overflow ellipsis
|
||||||
|
|
||||||
|
.idle-caret
|
||||||
|
absolute right top
|
||||||
|
height 34px
|
||||||
|
width 20px
|
||||||
|
line-height 34px
|
||||||
|
|
||||||
|
.search
|
||||||
|
absolute top left right bottom
|
||||||
|
line-height 34px
|
||||||
|
|
||||||
|
.search-input
|
||||||
|
vertical-align middle
|
||||||
|
position relative
|
||||||
|
top -2px
|
||||||
|
outline none
|
||||||
|
border none
|
||||||
|
height 20px
|
||||||
|
line-height 20px
|
||||||
|
background-color transparent
|
||||||
|
padding 0 10px
|
||||||
|
|
||||||
|
.search-optionList
|
||||||
|
position fixed
|
||||||
|
border $ui-border
|
||||||
|
z-index 10
|
||||||
|
background-color white
|
||||||
|
border-radius 5px
|
||||||
|
|
||||||
|
.search-optionList-item
|
||||||
|
height 34px
|
||||||
|
width 120px
|
||||||
|
box-sizing border-box
|
||||||
|
padding 0 5px
|
||||||
|
overflow ellipsis
|
||||||
|
cursor pointer
|
||||||
|
&:hover
|
||||||
|
background-color $ui-button--hover-backgroundColor
|
||||||
|
|
||||||
|
.search-optionList-item--active
|
||||||
|
@extend .search-optionList-item
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
|
color $ui-button--active-color
|
||||||
|
&:hover
|
||||||
|
background-color $ui-button--active-backgroundColor
|
||||||
|
color $ui-button--active-color
|
||||||
@@ -5,6 +5,7 @@ import MarkdownEditor from 'browser/components/MarkdownEditor'
|
|||||||
import queue from 'browser/main/lib/queue'
|
import queue from 'browser/main/lib/queue'
|
||||||
import StarButton from './StarButton'
|
import StarButton from './StarButton'
|
||||||
import TagSelect from './TagSelect'
|
import TagSelect from './TagSelect'
|
||||||
|
import FolderSelect from './FolderSelect'
|
||||||
import Repository from 'browser/lib/Repository'
|
import Repository from 'browser/lib/Repository'
|
||||||
|
|
||||||
class NoteDetail extends React.Component {
|
class NoteDetail extends React.Component {
|
||||||
@@ -66,6 +67,7 @@ class NoteDetail extends React.Component {
|
|||||||
|
|
||||||
note.content = this.refs.content.value
|
note.content = this.refs.content.value
|
||||||
note.tags = this.refs.tags.value
|
note.tags = this.refs.tags.value
|
||||||
|
note.folder = this.refs.folder.value
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
note,
|
note,
|
||||||
@@ -111,6 +113,7 @@ class NoteDetail extends React.Component {
|
|||||||
handleStarButtonClick (e) {
|
handleStarButtonClick (e) {
|
||||||
let { note } = this.state
|
let { note } = this.state
|
||||||
let { dispatch } = this.props
|
let { dispatch } = this.props
|
||||||
|
|
||||||
let isStarred = note._repository.starred.some((starredKey) => starredKey === note.key)
|
let isStarred = note._repository.starred.some((starredKey) => starredKey === note.key)
|
||||||
|
|
||||||
if (isStarred) {
|
if (isStarred) {
|
||||||
@@ -143,6 +146,7 @@ class NoteDetail extends React.Component {
|
|||||||
render () {
|
render () {
|
||||||
let { note } = this.state
|
let { note } = this.state
|
||||||
let isStarred = note._repository.starred.some((starredKey) => starredKey === note.key)
|
let isStarred = note._repository.starred.some((starredKey) => starredKey === note.key)
|
||||||
|
let folders = note._repository.folders
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='NoteDetail'
|
<div className='NoteDetail'
|
||||||
@@ -157,7 +161,12 @@ class NoteDetail extends React.Component {
|
|||||||
onClick={(e) => this.handleStarButtonClick(e)}
|
onClick={(e) => this.handleStarButtonClick(e)}
|
||||||
isActive={isStarred}
|
isActive={isStarred}
|
||||||
/>
|
/>
|
||||||
<div styleName='info-left-top-folderSelect'>FolderSelect</div>
|
<FolderSelect styleName='info-left-top-folderSelect'
|
||||||
|
value={this.state.note.folder}
|
||||||
|
ref='folder'
|
||||||
|
folders={folders}
|
||||||
|
onChange={() => this.handleChange()}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='info-left-bottom'>
|
<div styleName='info-left-bottom'>
|
||||||
<TagSelect
|
<TagSelect
|
||||||
@@ -197,6 +206,9 @@ class NoteDetail extends React.Component {
|
|||||||
NoteDetail.propTypes = {
|
NoteDetail.propTypes = {
|
||||||
dispatch: PropTypes.func,
|
dispatch: PropTypes.func,
|
||||||
repositories: PropTypes.array,
|
repositories: PropTypes.array,
|
||||||
|
note: PropTypes.shape({
|
||||||
|
|
||||||
|
}),
|
||||||
style: PropTypes.shape({
|
style: PropTypes.shape({
|
||||||
left: PropTypes.number
|
left: PropTypes.number
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
$info-height = 80px
|
$info-height = 75px
|
||||||
|
|
||||||
.root
|
.root
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
@@ -17,6 +17,7 @@ $info-height = 80px
|
|||||||
|
|
||||||
.info-left-top
|
.info-left-top
|
||||||
height 40px
|
height 40px
|
||||||
|
line-height 40px
|
||||||
|
|
||||||
.info-left-top-starButton
|
.info-left-top-starButton
|
||||||
display inline-block
|
display inline-block
|
||||||
@@ -27,15 +28,16 @@ $info-height = 80px
|
|||||||
|
|
||||||
.info-left-top-folderSelect
|
.info-left-top-folderSelect
|
||||||
display inline-block
|
display inline-block
|
||||||
height 40px
|
height 34px
|
||||||
width 100px
|
width 120px
|
||||||
vertical-align top
|
vertical-align middle
|
||||||
|
|
||||||
.info-left-bottom
|
.info-left-bottom
|
||||||
height 40px
|
height 30px
|
||||||
|
|
||||||
.info-left-bottom-tagSelect
|
.info-left-bottom-tagSelect
|
||||||
height 40px
|
height 30px
|
||||||
|
line-height 30px
|
||||||
|
|
||||||
.info-right
|
.info-right
|
||||||
float right
|
float right
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ class NoteList extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto scroll
|
// Auto scroll
|
||||||
|
let splitted = location.query.key.split('-')
|
||||||
|
let repoKey = splitted[0]
|
||||||
|
let noteKey = splitted[1]
|
||||||
let targetIndex = _.findIndex(this.notes, (note) => {
|
let targetIndex = _.findIndex(this.notes, (note) => {
|
||||||
let splitted = location.query.key.split('-')
|
|
||||||
let repoKey = splitted[0]
|
|
||||||
let noteKey = splitted[1]
|
|
||||||
return repoKey === note._repository.key && noteKey === note.key
|
return repoKey === note._repository.key && noteKey === note.key
|
||||||
})
|
})
|
||||||
if (targetIndex > -1) {
|
if (targetIndex > -1) {
|
||||||
@@ -133,11 +133,7 @@ class NoteList extends React.Component {
|
|||||||
if (location.pathname.match(/\/home/)) {
|
if (location.pathname.match(/\/home/)) {
|
||||||
return repositories
|
return repositories
|
||||||
.reduce((sum, repository) => {
|
.reduce((sum, repository) => {
|
||||||
return sum.concat(repository.notes
|
return sum.concat(repository.notes)
|
||||||
.map((note) => {
|
|
||||||
note._repository = repository
|
|
||||||
return note
|
|
||||||
}))
|
|
||||||
}, [])
|
}, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,11 +144,7 @@ class NoteList extends React.Component {
|
|||||||
.map((starredKey) => {
|
.map((starredKey) => {
|
||||||
return _.find(repository.notes, {key: starredKey})
|
return _.find(repository.notes, {key: starredKey})
|
||||||
})
|
})
|
||||||
.filter((note) => _.isObject(note))
|
.filter((note) => _.isObject(note)))
|
||||||
.map((note) => {
|
|
||||||
note._repository = repository
|
|
||||||
return note
|
|
||||||
}))
|
|
||||||
}, [])
|
}, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,18 +154,10 @@ class NoteList extends React.Component {
|
|||||||
let folder = _.find(repository.folders, {key: folderKey})
|
let folder = _.find(repository.folders, {key: folderKey})
|
||||||
if (folder == null) {
|
if (folder == null) {
|
||||||
return repository.notes
|
return repository.notes
|
||||||
.map((note) => {
|
|
||||||
note._repository = repository
|
|
||||||
return note
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return repository.notes
|
return repository.notes
|
||||||
.filter((note) => note.folder === folderKey)
|
.filter((note) => note.folder === folderKey)
|
||||||
.map((note) => {
|
|
||||||
note._repository = repository
|
|
||||||
return note
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNoteClick (key) {
|
handleNoteClick (key) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import _ from 'lodash'
|
|||||||
let tasks = []
|
let tasks = []
|
||||||
|
|
||||||
function _save (task, repoKey, note) {
|
function _save (task, repoKey, note) {
|
||||||
|
note = Object.assign({}, note)
|
||||||
delete note._repository
|
delete note._repository
|
||||||
|
|
||||||
task.status = 'process'
|
task.status = 'process'
|
||||||
@@ -15,7 +16,6 @@ function _save (task, repoKey, note) {
|
|||||||
})
|
})
|
||||||
.then((note) => {
|
.then((note) => {
|
||||||
tasks.splice(tasks.indexOf(task), 1)
|
tasks.splice(tasks.indexOf(task), 1)
|
||||||
console.log(tasks)
|
|
||||||
console.info('Note saved', note)
|
console.info('Note saved', note)
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ function repositories (state = initialRepositories, action) {
|
|||||||
console.info('REDUX >> ', action)
|
console.info('REDUX >> ', action)
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'INIT_ALL':
|
case 'INIT_ALL':
|
||||||
|
action.data.forEach((repo) => {
|
||||||
|
repo.notes.forEach((note) => {
|
||||||
|
note._repository = repo
|
||||||
|
})
|
||||||
|
})
|
||||||
return action.data.slice()
|
return action.data.slice()
|
||||||
case 'ADD_REPOSITORY':
|
case 'ADD_REPOSITORY':
|
||||||
{
|
{
|
||||||
@@ -113,6 +118,7 @@ function repositories (state = initialRepositories, action) {
|
|||||||
let targetRepo = _.find(repos, {key: action.repository})
|
let targetRepo = _.find(repos, {key: action.repository})
|
||||||
|
|
||||||
if (targetRepo == null) return state
|
if (targetRepo == null) return state
|
||||||
|
action.note._repository = targetRepo
|
||||||
targetRepo.notes.push(action.note)
|
targetRepo.notes.push(action.note)
|
||||||
|
|
||||||
return repos
|
return repos
|
||||||
@@ -126,6 +132,8 @@ function repositories (state = initialRepositories, action) {
|
|||||||
|
|
||||||
let targetNoteIndex = _.findIndex(targetRepo.notes, {key: action.note.key})
|
let targetNoteIndex = _.findIndex(targetRepo.notes, {key: action.note.key})
|
||||||
action.note.updatedAt = Date.now()
|
action.note.updatedAt = Date.now()
|
||||||
|
action.note._repository = targetRepo
|
||||||
|
|
||||||
if (targetNoteIndex > -1) {
|
if (targetNoteIndex > -1) {
|
||||||
targetRepo.notes.splice(targetNoteIndex, 1, action.note)
|
targetRepo.notes.splice(targetNoteIndex, 1, action.note)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user