json-object-editor
Version:
JOE the Json Object Editor | Platform Edition
373 lines (354 loc) • 16.5 kB
JavaScript
var schema = {
title : '${name}',
default_schema:true,
menuicon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="-11 -11 48 48"><path d="M10.2 0.1A1 1 0 0 0 10 0.1 1 1 0 0 0 9.3 0.8L4.4 13.9A1 1 0 1 0 6.3 14.6L10.8 2.2 23.6 4.8C23.3 5.8 21.4 12 19.1 17.9 18.2 20.4 17.4 22 16.6 22.9 16.1 23.4 15.6 23.7 14.9 23.8 11.3 24.3 11.8 19.8 11.8 19.8L0.4 15.2C-0.8 20.3 3.1 21.6 3.1 21.6L11.5 25.3C11.5 25.3 12.3 25.7 13.2 25.9A1 1 0 0 0 13.3 25.9C13.5 25.9 13.8 26 14.1 25.9 14.1 25.9 14.2 25.9 14.2 25.9 15.8 25.9 17.1 25.3 18.1 24.2 19.2 23 20 21.2 21 18.6 23.5 12.1 25.9 4.3 25.9 4.3A1 1 0 0 0 25.2 3L10.4 0.1A1 1 0 0 0 10.2 0.1zM11.7 5.6A1 1 0 0 0 11.7 7.6C11.8 7.6 11.8 7.6 11.9 7.6A1 1 0 1 0 12.3 5.7C12.2 5.6 12.2 5.6 12.2 5.6A1 1 0 0 0 11.8 5.6 1 1 0 0 0 11.7 5.6zM14.9 6.5A1 1 0 0 0 14.8 8.5L19.1 9.7A1 1 0 1 0 19.7 7.8L15.3 6.6A1 1 0 0 0 15 6.5 1 1 0 0 0 14.9 6.5zM10.2 9.8A1 1 0 0 0 10.2 11.7C10.2 11.7 10.3 11.7 10.3 11.8A1 1 0 1 0 10.7 9.8C10.7 9.8 10.6 9.8 10.6 9.8A1 1 0 0 0 10.2 9.8zM13.1 10.7A1 1 0 0 0 12.9 12.6L17.3 14A1 1 0 1 0 17.9 12.1L13.6 10.7A1 1 0 0 0 13.1 10.7zM8.6 13.6A1 1 0 0 0 8.6 15.6C8.6 15.6 8.7 15.6 8.7 15.6A1 1 0 1 0 9.2 13.7C9.1 13.6 9 13.6 9 13.6A1 1 0 0 0 8.6 13.6zM11.4 14.7A1 1 0 0 0 11.3 16.6L15.7 18.1A1 1 0 1 0 16.3 16.2L11.9 14.8A1 1 0 0 0 11.4 14.7z" /></svg>',
// Curated summary for agents
summary:{
description:'Named collection that aggregates existing items and/or freeform entries.',
purpose:'Lists bundle references to items across schemas and optional custom bullet-style entries for lightweight tracking or checklists.',
labelField:'name',
defaultSort:{ field:'joeUpdated', dir:'desc' },
searchableFields:['name','info','description','list_type','_id'],
allowedSorts:['joeUpdated','created','date','name','list_type'],
relationships:{
outbound:[
{ field:'items', targetSchema:'*', cardinality:'many' },
{ field:'status', targetSchema:'status', 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:'list' },
{ name:'name', type:'string', required:true },
{ name:'info', type:'string' },
{ name:'description', type:'string' },
{ name:'items', type:'string', isArray:true, isReference:true, targetSchema:'*' },
{ name:'custom_items', type:'objectList' },
{ name:'status', type:'string', isReference:true, targetSchema:'status' },
{ name:'list_type', type:'string' },
{ name:'date', type:'string', format:'date' },
{ 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 }
]
},
listView:{
title: function(list){
var itemCount = (list.items||[]).length+(list.custom_items||[]).length;
var title =
((itemCount && `<joe-fright>
<joe-om-indicator><big>${itemCount}</big> <div class="joe-subtext">items</div></joe-om-indicator>
</joe-fright>`) || '')
+`<joe-subtext>${list.list_type ||''} `
+(list.date &&_joe.Utils.toDateString(list.date)||'')
+'</joe-subtext><joe-title>${name}</joe-title><joe-subtitle>${info}</joe-subtitle>';
return title;
},
listWindowTitle: 'Lists'
},
//hideCounts:true,
onDemandExpander:true,
itemMenu:function(item){
var menu = [
{
name:_joe.schemas.report.menuicon,
action:'window.open(\'/API/plugin/reportbuilder/standard?itemid='+item._id+'\')'}
];
// var itemCount = (list.items||[]).length+(list.custom_items||[]).length;
// if(itemCount.length){
// menu.push({name:'<div style="line-height:1;"><big>'+itemCount.length+'</big> <div class="joe-subtext">items</div>',
// action:'goJoe(_joe.Data.task,{schema:\'task\',subset:\''+item.name+'\'})'});
// }
return menu;
},
itemExpander:function(list){
var h = '';
h+=
'<joe-content-section class="no-padding">'
+list.items.map(item=>{
let itemObj = $J.get(item);
return _joe.renderFieldListItem(itemObj,'',itemObj.itemType);
}).join('')
+'</joe-content-section>';
if(list.custom_items && list.custom_items.length){
h+=`<joe-content-section class="no-padding">${
list.custom_items.map(ci=>{
var done = (ci.sub_complete)?'joe-strike':'';
return`<joe-list-item class="custom-item"><joe-subtext>${ci.type ||''}</joe-subtext>
<joe-title class="${done}">${ci.name}</joe-title></joe-list-item>`;
}).join(' ')
}</joe-content-section>` ;
}
h+=((list.description &&`<joe-content-section>${list.description}</joe-content-section>`) ||'')
+`<joe-subtext class="fright">created <b>${_joe.Utils.toDateString(list.created)}</b></joe-subtext>`;
return h;
},
// itemMenu:function(){
// return [{name:'view',action:'window.open(\'/API/plugin/reportbuilder/standard?itemid=${_id}\')'}];
// },
subsets:function(){
var filters = [
{name:'ACTIVE',default:true,filter:
function(){
if(!this.status){
return false;
}
else{
var s = _joe.Cache.get(this.status);
//var s = $.get(this.status);
if(s.inactive || s.terminal || s.default){
return false;
}
}
return true;
}
}
];
var tags = _joe.Data.tag.filter(function(tag){
if(tag.datasets.indexOf(_joe.current.schema.__schemaname) != -1){
filters.push({name:tag.name,
filter:{tags:{$in:[tag._id]}}
});
}
});
filters.push({name:'untagged',
filter:{$or:[{tags:{$size:0}},{tags:{$exists:false}}]}
})
return filters;
},
bgcolor:function(item){
if(!item.status){
return '';
}
var status = _joe.getDataItem(item.status,'status');
/* var color = _joe.getDataItemProp(item.status,'status','color');*/
return {color:status.color,title:status.name};
},
filters:function(i){
var fils = [];
fils = fils.concat(_joe.Filter.Options.status({
schema:'list',
group:'status'
}),
_joe.Filter.Options.getDatasetPropertyValues('list','list_type',{
group:'list_types'
})
);
return fils;
},
fields:function(){
return [
'name',
{section_start:'items'},
{
name:'items',
display:"existing items",
type:'objectReference',
values:function(list){
var haystack = [];
for(var d in _joe.Data){
haystack = haystack.concat(_joe.Data[d]);
}
return haystack;
}
},
{name:'addingredient',label:false, type:'create',schema:'ingredient',width:'50%'},
{name:'addtask',label:false, type:'create',schema:'task',width:'50%'},
{name:'custom_items', display:'freeform items',type:"objectList",properties:[
'name',
{name:'type',width:'80px'},
{name:'sub_complete',display:'done',type:'boolean',width:'50px'}
],
template:function(obj,subobj){
var done = (subobj.sub_complete)?'joe-strike':'';
return`<joe-subtext>${subobj.type ||''}</joe-subtext>
<joe-title class="${done}">${subobj.name}</joe-title>`
}},
{section_end:'items'},
{section_start:'notes',collapsed:function(){
return !(i.info || i.description)
}},
'info',
'description',
{section_end:'notes'},
{sidebar_start:'right',collapsed:function(i){
return (i.list_type || (i.tags || i.tags.length));
}},
{section_start:'activity'},
'status',
{name:'date',type:'date',native:true},
'reports',
{section_end:'activity'},
{section_start:'classification'},
{name:'list_type',display:"List Type",
autocomplete:{text:true},
values:function(i){
//get list list types
var listTypes = [];
for(var l=0;l<_joe.Data.list.length;l++){
let lt = _joe.Data.list[l].list_type;
if(lt){
listTypes.push(lt);
}
}
listTypes = Array.from(new Set(listTypes));
return listTypes;
}},
'tags',
{section_end:'classification'},
{section_start:'access'},
'_protected',
{section_end:'access'},
{sidebar_end:'right'},
{section_start:'system',collapsed:true},
'_id','created','itemtype',
{section_end:'system'}
];
},
idprop : "_id",
sorter:['!joeUpdated','date','name','list_type','created'],
report:{
name:'List',
info:'basic list view',
template:function(data){
logit('listData',data)
var itemInfo = {};
var itemsArray = []
data.items.map(i=>{
if(!itemInfo[i]){
itemInfo[i] = Object.assign({},$J.get(i));
}
itemsArray.push(itemInfo[i]);
})
var listItems = itemsArray.concat(data.custom_items||[]);
function renderListItems(pItems){
var items = pItems || listItems;
logit(['listItmes',items]);
var content = items.map((li,i)=>{
console.log(li);
if(li._id){
return renderListItem(li);
}else{
return renderCustomListItem(li,i);
}
}).join('');
return content;
}
function renderListItem(ing){
//let ing = $J.get(itemid);
//console.log(itemid,ing.name);
return `<report-list-item toggleable id="${ing._id}" class="card">
<joe-subtext>${ing.itemtype}</joe-subtext>
<joe-title>${ing.name}</joe-title>
<joe-subtitle>${ing.info}</joe-subtitle>
</report-list-item>`;
}
function renderCustomListItem(ing,index){
return `<report-list-item toggleable id="ci-${index}" class="card">
<joe-subtext>${ing.type}</joe-subtext>
<joe-title>${ing.name}</joe-title>
</report-list-item>`;
}
return `<report-section>\
<report-section-label>${listItems.length} Items</report-section-label>\
${renderListItems()}
</report-section>`
}
},
reports:{
chore_cards:{
name:'Chore Cards from List',
template_type:'module',
template:function(data){
logit(data);
var schema = JOE.Schemas.raw_schemas.task;
var icon = schema.menuicon;
//var icon = JOE.SC
//var start=0,count=10,
var tasks=JOE.Data.task;
if(data.ITEM && data.ITEM.items){
//console.log($J.get(data.ITEM._id));
tasks = data.ITEM.items.map(it=>{
return $J.get(it)
})
}
if(data.request.query && data.request.query.where){
tasks = tasks.where(eval('('+data.request.query.where+')'));
}
//tasks = tasks.slice(start,count);
var extras = 10-(tasks.length%10);
console.log('extras',extras);
var extrasHtml='';
for(var i =0;i<extras;i++){
extrasHtml+=renderCard();
}
function renderCard(task,blank){
var taskContent = '';
if(task){
taskContent = `<joe-title>${task.name}</joe-title>
<card-points>${(task.points && `<pts-number>${task.points}</pts-number> pts`)||''}</card-points>`;
}
return `<task-card><card-front>
<card-icon>${icon}</card-icon>
${taskContent}
</card-front>
</task-card>`;
}
var template =`
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="/JsonObjectEditor/css/joe.css">
<link rel="stylesheet" href="/JsonObjectEditor/css/report-styles.css">
<title>Chore Cards from List</title>
<style>
html,body{
background:#fff;
}
*{ padding:0; margin:0; position:relative;}
task-card{
width:calc(50% - 12px);
margin:4px;
height:198px;
border:2px solid #999;
display:block;
float:left;
}
card-front{
display:block;
text-align:center;
padding-top:20px;
}
card-icon {
position: absolute;
top: -10px;
left: -10px;
width: 80px;
opacity:.8;
}
card-points{
font-weight:bold;
color:#999;
font-size:24px;
}
card-front joe-title {
font-size: 24px;
margin: 30px 20px 10px 20px;
}
</style>
</head>
<body>
${tasks.map(renderCard).join('')}
${extrasHtml}
</body>
</html>
`;
return template;
}
}
}
};
module.exports = schema;