|
|
|
// Prioritize cards within other cards. Each card has a .priorities array of other taskIds.
|
|
|
|
import inquirer from 'inquirer'
|
|
|
|
import { headerStyle } from './styles.js'
|
|
|
|
import { aoEnv } from './settings.js'
|
|
|
|
import { getCard, prioritizeCard, completeCard, uncheckCard, refocusCard } from './api.js'
|
|
|
|
import { createCardInteractive } from './cards.js'
|
|
|
|
|
|
|
|
// Prints the text (.name) of the first card prioritized in the logged-in users member card
|
|
|
|
export async function getTopPriorityText() {
|
|
|
|
return (await getFirstPriorityCard())?.name
|
|
|
|
}
|
|
|
|
|
|
|
|
// Makes an API request to get the first prioritized card in the member card of the logged-in user
|
|
|
|
async function getFirstPriorityCard() {
|
|
|
|
// Get the first priority of my member card
|
|
|
|
const memberId = aoEnv('AO_CLI_SESSION_MEMBERID')
|
|
|
|
if(!memberId) {
|
|
|
|
return 'Not logged in'
|
|
|
|
}
|
|
|
|
const fetchedCards = await getCard(memberId, 'priority')
|
|
|
|
if(fetchedCards === null) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
if(!fetchedCards || fetchedCards.length < 2) {
|
|
|
|
return 'None'
|
|
|
|
}
|
|
|
|
return fetchedCards[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Displays the priorities of the given taskId in a menu. Selecting a card shows a menu for that card. If taskId is null, member card is used.
|
|
|
|
export async function prioritiesMenu(taskId = null) {
|
|
|
|
console.log(`\n${headerStyle('My Priorities')}`)
|
|
|
|
let prioritiesChoices = []
|
|
|
|
|
|
|
|
const memberId = aoEnv('AO_CLI_SESSION_MEMBERID')
|
|
|
|
if(!memberId) {
|
|
|
|
console.log('Not logged in.')
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if(!taskId) {
|
|
|
|
// Get the priorities of my member card
|
|
|
|
taskId = memberId
|
|
|
|
}
|
|
|
|
const fetchedCards = await getCard(taskId, 'priorities')
|
|
|
|
if(!fetchedCards || fetchedCards.length < 1) {
|
|
|
|
console.log('Failed to fetch member card, this is bad.')
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
const card = fetchedCards[0]
|
|
|
|
let priorityCards = fetchedCards.slice(1) // First card is member card itself
|
|
|
|
let priorities = card.priorities.slice()
|
|
|
|
priorities.reverse()
|
|
|
|
// Fix order - incoming card order is absolute order on server, not order within this card
|
|
|
|
priorityCards = priorities.map((priorityTaskId, i) => {
|
|
|
|
const priorityCard = priorityCards.find(p => p.taskId === priorityTaskId)
|
|
|
|
if(!priorityCard) {
|
|
|
|
return 'Missing card, repair your database'
|
|
|
|
}
|
|
|
|
return priorityCard
|
|
|
|
})
|
|
|
|
console.log('You have', priorityCards.length, 'priorities:')
|
|
|
|
prioritiesChoices = priorities.map((priorityTaskId, i) => {
|
|
|
|
const priorityCard = priorityCards.find(p => p.taskId === priorityTaskId)
|
|
|
|
if(!priorityCard) {
|
|
|
|
return 'Missing card, repair your database'
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
name: priorityCard.name,
|
|
|
|
value: { index: i, card: priorityCard },
|
|
|
|
short: priorityCard.name.substring(0, 70) + priorityCard.name.length >= 70 ? '...' : ''
|
|
|
|
}
|
|
|
|
})
|
|
|
|
let firstIndexEchelonDecreases
|
|
|
|
let firstEchelon = priorityCards.length >= 1 ? priorityCards[0].echelon : null
|
|
|
|
if(firstEchelon) {
|
|
|
|
priorityCards.some((pc, i) => {
|
|
|
|
if(!pc.echelon || pc.echelon !== firstEchelon) {
|
|
|
|
firstIndexEchelonDecreases = i
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
if(!isNaN(firstIndexEchelonDecreases)) {
|
|
|
|
prioritiesChoices.splice(firstIndexEchelonDecreases, 0, new inquirer.Separator('───'))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
prioritiesChoices.push(
|
|
|
|
{ name: 'Create priority', value: 'create_here', short: 'new priority' },
|
|
|
|
{ name: 'Back to Deck', value: false, short: 'back' }
|
|
|
|
)
|
|
|
|
let answer
|
|
|
|
try {
|
|
|
|
answer = await inquirer.prompt({
|
|
|
|
name: 'priorities_menu',
|
|
|
|
type: 'rawlist',
|
|
|
|
message: 'Please choose:',
|
|
|
|
choices: prioritiesChoices,
|
|
|
|
loop: false
|
|
|
|
})
|
|
|
|
} catch(error) {
|
|
|
|
if (error === 'EVENT_INTERRUPTED') {
|
|
|
|
console.log('\nESC')
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch(answer.priorities_menu) {
|
|
|
|
case false:
|
|
|
|
return false
|
|
|
|
case 'create_here':
|
|
|
|
let previousCardCreatedText
|
|
|
|
do {
|
|
|
|
previousCardCreatedText = await createCardInteractive()
|
|
|
|
} while(previousCardCreatedText != '\n')
|
|
|
|
return true
|
|
|
|
case 'Missing card, repair your database':
|
|
|
|
console.log('Database repair yet implemented, sorry.')
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
let chosenTask = answer.priorities_menu.card
|
|
|
|
const chosenTaskId = chosenTask.taskId
|
|
|
|
let previousAnswer
|
|
|
|
do {
|
|
|
|
previousAnswer = await priorityCardMenu(chosenTask, answer.priorities_menu.index, priorityCards)
|
|
|
|
if(previousAnswer) {
|
|
|
|
const fetchedCards = await getCard(chosenTaskId, false)
|
|
|
|
if(!fetchedCards || fetchedCards.length < 1) {
|
|
|
|
console.log('The card has disappeared. Maybe it was deleted, or cards held by no one are automatically cleaned up every five minutes.')
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
chosenTask = fetchedCards[0]
|
|
|
|
}
|
|
|
|
} while(previousAnswer !== false)
|
|
|
|
console.log('Card menu not yet implemented.')
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Short action-oriented menu for cards in the priorities list
|
|
|
|
// Index is the position of the card in the list that it is in, used for fencepost case to display upboat contextually
|
|
|
|
async function priorityCardMenu(card, index, allPriorities) {
|
|
|
|
if(!card) {
|
|
|
|
console.log('priorityCardMenu: card is required.')
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
const taskId = card.taskId
|
|
|
|
const memberId = aoEnv('AO_CLI_SESSION_MEMBERID')
|
|
|
|
if(!memberId) {
|
|
|
|
console.log('Not logged in.')
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
const isChecked = card.claimed.includes(memberId)
|
|
|
|
console.log(`\n${headerStyle('Priority: ' + card.name)}`)
|
|
|
|
let priorityChoices = []
|
|
|
|
if(index != 0) {
|
|
|
|
priorityChoices.push({ name: 'Upboat', value: 'upboat', short: 'upboat' })
|
|
|
|
}
|
|
|
|
priorityChoices.push(
|
|
|
|
{ name: isChecked ? 'Uncheck' : 'Check off', value: 'check', short: 'check!' },
|
|
|
|
{ name: 'Downboat', value: 'downboat', short: 'downboat' },
|
|
|
|
//{ name: 'Browse within', value: 'browse', short: 'browse' }
|
|
|
|
{ name: 'Back to Priorities', value: false, short: 'back' }
|
|
|
|
)
|
|
|
|
let answer
|
|
|
|
try {
|
|
|
|
answer = await inquirer.prompt({
|
|
|
|
name: 'priority_card_menu',
|
|
|
|
type: 'list',
|
|
|
|
message: 'Please choose:',
|
|
|
|
choices: priorityChoices,
|
|
|
|
pageSize: priorityChoices.length,
|
|
|
|
})
|
|
|
|
} catch(error) {
|
|
|
|
if (error === 'EVENT_INTERRUPTED') {
|
|
|
|
console.log('\nESC')
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch(answer.priority_card_menu) {
|
|
|
|
case 'check':
|
|
|
|
if(isChecked) {
|
|
|
|
await uncheckCard(taskId)
|
|
|
|
} else {
|
|
|
|
await completeCard(taskId)
|
|
|
|
}
|
|
|
|
break
|
|
|
|
case 'upboat':
|
|
|
|
console.log('upboat')
|
|
|
|
let firstEchelonScore
|
|
|
|
let newEchelonScore
|
|
|
|
let newPosition = 0
|
|
|
|
console.log('upboat2')
|
|
|
|
console.log('card is', card)
|
|
|
|
//console.log(allPriorities)
|
|
|
|
breakHere:
|
|
|
|
for(let i = 0; i < allPriorities.length; i++) {
|
|
|
|
console.log('upboat3')
|
|
|
|
const priority = allPriorities[i]
|
|
|
|
console.log('priority is', priority)
|
|
|
|
if(i === 0) {
|
|
|
|
console.log('upboat3.1')
|
|
|
|
firstEchelonScore = priority.echelon
|
|
|
|
console.log('upboat3.11115', priority.name, priority.echelon, typeof priority.echelon)
|
|
|
|
if(isNaN(firstEchelonScore)) {
|
|
|
|
console.log('upboat3.2')
|
|
|
|
newEchelonScore = 1
|
|
|
|
break breakHere
|
|
|
|
}
|
|
|
|
if(!card.echelon || card.echelon < priority.echelon) {
|
|
|
|
console.log('upboat3.3')
|
|
|
|
newEchelonScore = priority.echelon
|
|
|
|
} else if(card.echelon && priority.echelon && card.echelon === priority.echelon) {
|
|
|
|
console.log('upboat3.4')
|
|
|
|
newEchelonScore = priority.echelon + 1
|
|
|
|
break breakHere
|
|
|
|
} else if(card.echelon && priority.echelon && card.echelon > priority.echelon) {
|
|
|
|
console.log('upboat3.5')
|
|
|
|
break breakHere
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log('upboat4')
|
|
|
|
if(priority.echelon !== firstEchelonScore) {
|
|
|
|
newPosition = i
|
|
|
|
break breakHere
|
|
|
|
}
|
|
|
|
console.log('upboat5')
|
|
|
|
}
|
|
|
|
console.log('upboat6')
|
|
|
|
console.log('newPosition is', newPosition, 'and newEchelonScore is', newEchelonScore)
|
|
|
|
await prioritizeCard(taskId, memberId, newPosition, newEchelonScore)
|
|
|
|
return false
|
|
|
|
case 'downboat':
|
|
|
|
await refocusCard(taskId, memberId)
|
|
|
|
return false
|
|
|
|
case 'browse':
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|