2025-02-20 10:54:43 +01:00
< script setup >
2025-02-20 16:12:36 +01:00
import { onMounted , ref , useTemplateRef } from 'vue' ;
import { Button } from 'pankow' ;
import { prettyDate } from 'pankow/utils' ;
import { marked } from 'marked' ;
import AppsModel from '../../models/AppsModel.js' ;
const appsModel = AppsModel . create ( ) ;
2025-02-20 10:54:43 +01:00
const props = defineProps ( [ 'app' ] ) ;
2025-02-20 16:12:36 +01:00
const emit = defineEmits ( [ 'changed' ] ) ;
const id = ref ( '' ) ;
const notesTextarea = useTemplateRef ( 'notesTextarea' ) ;
const showDoneChecklist = ref ( false ) ;
const hasOldChecklist = ref ( false ) ;
const checklist = ref ( [ ] ) ;
const manifest = ref ( { } ) ;
const editing = ref ( false ) ;
const busy = ref ( false ) ;
const placeholder = 'Add admin notes here...' ;
const noteContent = ref ( '' ) ;
async function onAckChecklistItem ( item , key ) {
// TODO
}
async function onSubmit ( ) {
busy . value = true ;
// skip saving if unchanged from postInstall
if ( noteContent . value === props . app . manifest . postInstallMessage ) {
busy . value = false ;
editing . value = false ;
return ;
}
const [ error ] = await appsModel . configure ( id . value , 'notes' , { notes : noteContent . value } ) ;
if ( error ) {
busy . value = false ;
return console . error ( error ) ;
}
// let main view know about this
emit ( 'changed' ) ;
editing . value = false ;
busy . value = false ;
}
function onEdit ( ) {
editing . value = true ;
setTimeout ( ( ) => notesTextarea . value . focus ( ) , 200 ) ;
}
function onDismiss ( ) {
editing . value = false ;
noteContent . value = props . app . notes === null ? props . app . manifest . postInstallMessage : props . app . notes ;
}
2025-02-20 10:54:43 +01:00
onMounted ( ( ) => {
2025-02-20 16:12:36 +01:00
const app = props . app ;
manifest . value = app . manifest || { } ;
id . value = app . id ;
checklist . value = app . checklist ;
hasOldChecklist . value = ! ! Object . keys ( app . checklist ) . find ( ( k ) => { return app . checklist [ k ] . acknowledged ; } ) ;
noteContent . value = app . notes === null ? app . manifest . postInstallMessage : app . notes ;
editing . value = false ;
busy . value = false ;
2025-02-20 10:54:43 +01:00
} ) ;
< / script >
< template >
< div >
2025-02-20 16:12:36 +01:00
< div class = "actionable" @click ="info.showDoneChecklist = true" v-show = "hasOldChecklist && !showDoneChecklist" > Show Checklist < / div >
< div class = "actionable" @click ="info.showDoneChecklist = false" v-show = "showDoneChecklist" > Hide Checklist < / div >
< div v-for = "(item, key) in checklist" :key="key" >
< div class = "checklist-item" v-if = "!item.acknowledged" >
< span v-html = "marked.parse(item.message)" > < / span >
< button class = "btn btn-xs btn-default" style = "margin-left: 10px;" @click ="onAckChecklistItem(item, key)" > Done < / button >
< / div >
< / div >
< div v-for = "(item, key) in checklist" :key="key" v-show="showDoneChecklist" >
< div class = "checklist-item checklist-item-acknowledged" v-if = "item.acknowledged" >
< span v-html = "marked.parse(item.message)" > < / span >
< span class = "text-muted text-small" > { { item . changedBy } } { { prettyDate ( item . changedAt ) } } < / span >
< / div >
< / div >
< div style = "margin-top: 10px" > < / div >
< div class = "info-row" >
< div class = "info-label" > { { $t ( 'app.updates.info.description' ) } } < / div >
< div class = "info-value" v-if = "app.appStoreId" > {{ manifest.title }} {{ app.upstreamVersion }} < / div >
< div class = "info-value" v-else > {{ manifest.dockerImage }} < / div >
< / div >
< div class = "info-row" >
< div class = "info-label" > { { $t ( 'app.updates.info.appId' ) } } < / div >
< div class = "info-value" > { { app . id } } < / div >
< / div >
< div class = "info-row" >
< div class = "info-label" > { { $t ( 'app.updates.info.packageVersion' ) } } < / div >
< div class = "info-value" v-if = "app.appStoreId"><a :href="`/#/appstore/${manifest.id}?version=${manifest.version}`" > {{ manifest.id }} @ {{ manifest.version }} < / a > < / div >
< div class = "info-value" v-else > {{ manifest.version }} < / div >
< / div >
< div class = "info-row" >
< div class = "info-label" > { { $t ( 'app.updates.info.installedAt' ) } } < / div >
< div class = "info-value" > { { prettyDate ( app . creationTime ) } } < / div >
< / div >
< div class = "info-row" >
< div class = "info-label" > { { $t ( 'app.updates.info.lastUpdated' ) } } < / div >
< div class = "info-value" > { { prettyDate ( app . updateTime ) } } < / div >
< / div >
< br / >
< p >
< label class = "control-label" > { { $t ( 'app.info.notes.title' ) } } < / label > < i v-show = "!editing" class="info-edit-indicator fa fa-pencil-alt" @click="onEdit()" > < / i >
< / p >
< div >
< div v-show = "!editing" >
< div v-if = "noteContent" v-html="marked.parse(noteContent)" > < / div >
< div v-else class = "text-muted hand" @click ="onEdit()" > {{ placeholder }} < / div >
< / div >
< div v-show = "editing" >
< textarea ref = "notesTextarea" style = "white-space: pre-wrap; margin-bottom: 5px; width: 100%" v-model = "noteContent" rows="10" > < / textarea >
< div style = "display: flex; gap: 5px" >
< Button secondary @click ="onDismiss()" v-show = "!busy" > {{ $ t ( ' main.dialog.cancel ' ) }} < / Button >
< Button @click ="onSubmit()" :disabled = "busy" :loading = "busy" > { { $t ( 'app.display.saveAction' ) } } < / Button >
< / div >
< / div >
< / div >
2025-02-20 10:54:43 +01:00
< / div >
< / template >