json-object-editor
Version:
JOE the Json Object Editor | Platform Edition
136 lines (130 loc) • 7.25 kB
JavaScript
var schema = {
title : '${name}',
info:"In your group working towards realizing a specific outcome? Track it with goals.",
default_schema:true,
// Curated summary for agents
summary:{
description:'Outcome to achieve; referenced by projects and aligned planning.',
purpose:'Goals define measurable outcomes and can be aligned to projects or groups. Use goal to plan and report on strategic objectives; projects may list aligned goals.',
labelField:'name',
defaultSort:{ field:'joeUpdated', dir:'desc' },
searchableFields:['name','info','code','_id'],
allowedSorts:['joeUpdated','created','name','priority','group'],
relationships:{
outbound:[
{ field:'group', targetSchema:'group', cardinality:'one' },
{ field:'tags', targetSchema:'tag', cardinality:'many' }
],
inbound:{ graphRef:'server/relationships.graph.json' }
},
joeManagedFields:['created','joeUpdated'],
fields:[
{ name:'_id', type:'string', required:true },
{ name:'itemtype', type:'string', required:true, const:'goal' },
{ name:'name', type:'string', required:true },
{ name:'code', type:'string' },
{ name:'info', type:'string' },
{ name:'description', type:'string' },
{ name:'group', type:'string', isReference:true, targetSchema:'group' },
{ name:'milestones', type:'objectList' },
{ name:'tags', type:'string', isArray:true, isReference:true, targetSchema:'tag' },
{ name:'joeUpdated', type:'string', format:'date-time', required:true },
{ name:'created', type:'string', format:'date-time', required:true }
]
},
menuicon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="-120 -120 720 720"><path d="M476.6 83.8c-0.7-2.7-2.9-4.6-6-5.4l-34.3-8.7c-0.9-0.2-2.2-1.6-2.5-2.5L425.2 33c-1-3.8-3.8-6.2-7.3-6.2 -2.1 0-4.2 0.9-5.8 2.6L381.4 60c-2.6 2.6-5.2 7.4-5.9 11l-7.3 37.6c-0.3 1.7-0.3 3.5 0.1 5.2l-20.2 20.2c-32.4-29-75.2-46.7-122-46.7 -100.9 0-183 82.1-183 183s82.1 183 183 183 183-82.1 183-183c0-43.3-15.1-83.1-40.3-114.4l20.7-20.7c1 0.2 2 0.3 3.1 0.3 0.8 0 1.6-0.1 2.3-0.2l37.6-7.3c3.7-0.7 8.4-3.2 11-5.9l30.7-30.7C476.5 89.2 477.3 86.4 476.6 83.8zM285.1 270.3c0 32.5-26.4 58.9-58.9 58.9 -32.5 0-58.9-26.4-58.9-58.9 0-32.5 26.4-58.9 58.9-58.9 5.5 0 10.9 0.8 16 2.2l-8.2 25c-2.5-0.6-5.1-0.9-7.8-0.9 -18 0-32.7 14.7-32.7 32.7s14.7 32.7 32.7 32.7c17.5 0 31.8-13.8 32.7-31.1l25.8-9.1C284.9 265.3 285.1 267.8 285.1 270.3zM295.3 186.7c-18.8-15.6-42.9-25-69.2-25 -59.9 0-108.6 48.7-108.6 108.6s48.7 108.5 108.6 108.5 108.6-48.7 108.6-108.5c0-22.8-7.1-43.9-19.1-61.4l20.3-20.3c17 22.8 27.1 51.1 27.1 81.7 0 75.5-61.4 136.9-136.9 136.9S89.2 345.8 89.2 270.3s61.4-136.9 136.9-136.9c34.1 0 65.3 12.5 89.3 33.2L295.3 186.7z"/></svg>',
listView:{
title: '<joe-subtitle>${code}</joe-subtitle><joe-title>${name}</joe-title><joe-subtitle>${info}</joe-subtitle>',
listWindowTitle: 'Goals'
},
sorter:['priority','group','name'],
subsets:function(){
var sets = [
{group_start:'groups',collapsed:false}
];
_joe.Data.group.sortBy('name').map(function(g){
sets.push({name:g.name,filter:{group:g._id}});
})
sets.push({group_end:'groups'});
return sets;
},
filters:function(){
var stats = [].concat(_joe.Filter.Options.tags({group:'tags',collapsed:true}));
return stats;
},
stripeColor:function(item){
if(item.priority && item.priority < 100){
return {
title:`P${item.priority}`,
color:_joe.Colors.priority[item.priority]
};
}
},
itemExpander:function(g){
var projects = _joe.Data.project.where({aligned_goals:{$in:[g._id]}});
var html =`<joe-subtitle>${projects.length} projects</joe-subtitle>
${projects.map(p=>{
return _joe.renderFieldListItem(p,null,'project');
}).join('')}
`
return html;
},
fields:[
{extend:'name',specs:{width:'75%'}},
{name:'code',width:'25%'},
'info',
'description',
{name:'completion_equation',display:'completion equation',type:'code',language:'javascript',comment:'This is a javascript function that takes an item as an argument and returns a number between 0 and 1 representing the completion percentage of the goal. It can use any properties of the item or datasets in joe'},
{name:'complettion_percentage', reloadable:true, display:'completion percentage',type:'content',run:function(item){
const fn = tryEval(item.completion_equation);
const result = fn(item); // or any item
return Math.round(result*100) + '%'; // Assuming the function returns a number between 0 and 1
return 80 + '%'; // Placeholder, should be calculated based on completion_equation
}},
'impact',
'group',
// {name:'has_milestones',display:'has milestones',type:'boolean',comment:'If true, this goal has milestones that can be tracked.',rerender:['milestones','timeline']},
{name:'milestones',
/*condition:function(item){return !!!item.has_milestones;},*/
type:'objectList',properties:[
{name:'name'},
{name:'status',type:'select',values:['','roadmap','in-progress','completed'],width:'120px'}
]},
{section_start:'timeline',
// condition:function(item){
// return !!!item.has_milestones;
// }
},
{name:'start_dt',display:'kickoff',type:'date', native:true,width:'50%'},
{name:'end_dt',display:'completion',type:'date', native:true,width:'50%'},
{name:'phases',type:'objectList',
template:function(obj,subobj){
//var done = (subobj.sub_complete)?'joe-strike':'';
var t =
'<joe-title >${name} '+(subobj.hasOwnProperty('id') && '['+subobj.id+']'||'')+'</joe-title>'
+((subobj.start_date || subobj.end_date) && '<joe-subtext>${start_date} - ${end_date}</joe-subtext>'||'');
return t;
},
properties:[
{name:'name'},
{name:'id',width:'120px'},
{name:'due_date', display:'start', type:'date', native:true,width:'80px'},
],
hideheader:true},
{section_end:'timeline'},
{section_start:'system',collapsed:true},
'_id','created','itemtype',
{section_end:'system'},
{sidebar_start:'right'},
'reports',
'priority',
{section_start:'tags', collapsed:function(i){
return !(i.tags || i.tags.length)
}},
'tags',
{section_end:'tags'},
{sidebar_end:'right'}
],
idprop : "_id"
};
module.exports = schema;