Move item in checklist

This commit is contained in:
Magnus Åhall 2024-01-13 10:01:10 +01:00
parent d0f410323e
commit 44f5d92815
3 changed files with 125 additions and 16 deletions

24
main.go
View File

@ -111,6 +111,7 @@ func main() { // {{{
service.Register("/node/checklist_item/state", true, true, nodeChecklistItemState)
service.Register("/node/checklist_item/label", true, true, nodeChecklistItemLabel)
service.Register("/node/checklist_item/delete", true, true, nodeChecklistItemDelete)
service.Register("/node/checklist_item/move", true, true, nodeChecklistItemMove)
service.Register("/key/retrieve", true, true, keyRetrieve)
service.Register("/key/create", true, true, keyCreate)
service.Register("/key/counter", true, true, keyCounter)
@ -645,6 +646,29 @@ func nodeChecklistItemDelete(w http.ResponseWriter, r *http.Request, sess *sessi
"OK": true,
})
} // }}}
func nodeChecklistItemMove(w http.ResponseWriter, r *http.Request, sess *session.T) { // {{{
var err error
req := struct {
ChecklistItemID int
AfterItemID int
}{}
if err = parseRequest(r, &req); err != nil {
responseError(w, err)
return
}
err = ChecklistItemMove(sess.UserID, req.ChecklistItemID, req.AfterItemID)
if err != nil {
logger.Error("checklist", "error", err)
responseError(w, err)
return
}
responseData(w, map[string]interface{}{
"OK": true,
})
} // }}}
func keyRetrieve(w http.ResponseWriter, r *http.Request, sess *session.T) { // {{{
logger.Info("webserver", "request", "/key/retrieve")

44
node.go
View File

@ -600,6 +600,50 @@ func ChecklistItemDelete(userID, checklistItemID int) (err error) { // {{{
)
return
} // }}}
func ChecklistItemMove(userID, checklistItemID, afterItemID int) (err error) { // {{{
_, err = service.Db.Conn.Exec(
`
WITH
"to" AS (
SELECT
i.checklist_group_id AS group_id,
i."order"
FROM checklist_item i
INNER JOIN checklist_group g ON i.checklist_group_id = g.id
INNER JOIN node n ON g.node_id = n.id
WHERE
n.user_id = $1 AND
i.id = $3
),
update_order AS (
UPDATE checklist_item
SET
"order" =
CASE
WHEN checklist_item."order" <= "to"."order" THEN checklist_item."order" - 1
WHEN checklist_item."order" > "to"."order" THEN checklist_item."order" + 1
END
FROM "to"
WHERE
checklist_item.id != $2 AND
checklist_item.checklist_group_id = "to".group_id
)
UPDATE checklist_item
SET
checklist_group_id = "to".group_id,
"order" = "to"."order"
FROM "to"
WHERE
checklist_item.id = $2
`,
userID,
checklistItemID,
afterItemID,
)
return
} // }}}
func (node *Node) retrieveChecklist() (err error) { // {{{
var rows *sqlx.Rows

View File

@ -16,8 +16,7 @@ export class ChecklistGroup {
let item = new ChecklistItem(itemData)
item.checklistGroup = this
return item
}
).sort(ChecklistItem.sort)
})
else
this[key] = data[key]
})
@ -92,6 +91,14 @@ export class ChecklistItem {
})
.catch(errCallback)
}//}}}
move(to, okCallback) {//{{{
window._app.current.request('/node/checklist_item/move', {
ChecklistItemID: this.ID,
AfterItemID: to.ID,
})
.then(okCallback)
.catch(_app.current.responseError)
}//}}}
}
export class Checklist extends Component {
@ -100,11 +107,14 @@ export class Checklist extends Component {
this.edit = signal(true)
this.dragItemSource = null
this.dragItemTarget = null
this.groupElements = {}
this.state = {
confirmDeletion: true,
}
window._checklist = this
}//}}}
render({ groups }, { confirmDeletion }) {//{{{
this.groupElements = {}
if (groups.length == 0)
return
@ -112,7 +122,10 @@ export class Checklist extends Component {
groups = []
groups.sort(ChecklistGroup.sort)
let groupElements = groups.map(group => html`<${ChecklistGroupElement} key="group-${group.ID}" ui=${this} group=${group} />`)
let groupElements = groups.map(group => {
this.groupElements[group.ID] = createRef()
return html`<${ChecklistGroupElement} ref=${this.groupElements[group.ID]} key="group-${group.ID}" ui=${this} group=${group} />`
})
let edit = 'edit-list-gray.svg'
let confirmDeletionEl = ''
@ -126,9 +139,9 @@ export class Checklist extends Component {
`
}
let addGroup = ()=>{
let addGroup = () => {
if (this.edit.value)
return html`<img src="/images/${_VERSION}/add-gray.svg" onclick=${()=>this.addGroup()} />`
return html`<img src="/images/${_VERSION}/add-gray.svg" onclick=${() => this.addGroup()} />`
}
return html`
@ -188,9 +201,11 @@ class ChecklistGroupElement extends Component {
}//}}}
render({ ui, group }) {//{{{
let items = ({ ui, group }) =>
group.items.map(item => html`<${ChecklistItemElement} key="item-${item.ID}" ui=${ui} group=${this} item=${item} />`)
group.items
.sort(ChecklistItem.sort)
.map(item => html`<${ChecklistItemElement} key="item-${item.ID}" ui=${ui} group=${this} item=${item} />`)
let label = ()=>html`<div class="label" style="cursor: pointer" ref=${this.label} onclick=${()=>this.editLabel()}>${group.Label}</div>`
let label = () => html`<div class="label" style="cursor: pointer" ref=${this.label} onclick=${() => this.editLabel()}>${group.Label}</div>`
return html`
<div class="checklist-group-container">
@ -266,7 +281,7 @@ class ChecklistItemElement extends Component {
this.label = createRef()
}//}}}
render({ ui, item }, { checked, dragTarget }) {//{{{
let checkbox = ()=>{
let checkbox = () => {
if (ui.edit.value)
return html`<label ref=${this.label} onclick=${() => this.editLabel()} style="cursor: pointer">${item.Label}</label>`
else
@ -284,9 +299,9 @@ class ChecklistItemElement extends Component {
`
}//}}}
componentDidMount() {//{{{
this.base.addEventListener('dragstart', ()=>this.dragStart())
this.base.addEventListener('dragend', ()=>this.dragEnd())
this.base.addEventListener('dragenter', evt=>this.dragEnter(evt))
this.base.addEventListener('dragstart', () => this.dragStart())
this.base.addEventListener('dragend', () => this.dragEnd())
this.base.addEventListener('dragenter', evt => this.dragEnter(evt))
}//}}}
update(checked) {//{{{
@ -348,11 +363,37 @@ class ChecklistItemElement extends Component {
this.props.ui.dragTarget(this)
}//}}}
dragEnd() {//{{{
console.log(
this.props.ui.dragItemSource.props.item.Label,
this.props.ui.dragItemTarget.props.item.Label,
)
let groups = this.props.ui.props.groups
let from = this.props.ui.dragItemSource.props.item
let to = this.props.ui.dragItemTarget.props.item
this.props.ui.dragReset()
if (from.ID == to.ID)
return
let fromGroup = groups.find(g => g.ID == from.GroupID)
let toGroup = groups.find(g => g.ID == to.GroupID)
from.Order = to.Order
from.GroupID = toGroup.ID
toGroup.items.forEach(i => {
if (i.ID == from.ID)
return
if (i.Order <= to.Order)
i.Order--
})
if (fromGroup.ID != toGroup.ID) {
fromGroup.items = fromGroup.items.filter(i => i.ID != from.ID)
toGroup.items.push(from)
}
this.props.ui.groupElements[fromGroup.ID].current.forceUpdate()
this.props.ui.groupElements[toGroup.ID].current.forceUpdate()
from.move(to, ()=>console.log('ok'))
}//}}}
}