/**
Utilities for importing from the various reports-* pages.
*/
return proc(ns){
ns.createAnchor = proc(page, label, urlParams){
const opt = object {
year: this.year,
type: this.eventType,
user: this.user,
yearWeek: util.yearWeek
}
urlParams || (urlParams = object{})
assert 'object' === typename urlParams
opt.eachProperty(proc(k,v){
urlParams.hasOwnProperty(k) || urlParams.set(k,v)
})
('*'===urlParams.type) && unset urlParams.type
return api.cgi.html.createAnchor( api.cgi.cgiRoot + page +
'?'+api.cgi.objToUrlParams(urlParams),
label)
}
ns.getYearList = proc(){
const aYears = array[]
var stmt = api.cgi.getFossilInstance().db.prepare(
{SELECT DISTINCT substr(date(mtime),1,4) AS y
FROM /*v_reports*/ event GROUP BY y ORDER BY y})
while(stmt.step()){
aYears.push( stmt.get(0) )
}
stmt.finalize()
return aYears
}
ns.generateYearSelection = proc(urlParams){
const CGI = api.cgi
const aYears = this.getYearList()
aYears.length() || return
const out = api.io.output
urlParams || (urlParams = object{})
urlParams.user = this.user
// th1ish bug: assertion crash: ((this.eventType==='*') ? undefined : this.eventType)
('*' !== this.eventType) && (urlParams.type = this.eventType)
const filterYear = (this.year || CGI.getVar('year'))
const currentYear = (filterYear || strftime("%Y"))
$out {<div class='reports-filter-year'>Select year:} ' '
var gotCurrentYear
$out "<a href='?" CGI.objToUrlParams(object{
user: this.user,
type: this.eventType
}) "'"
filterYear || $out " class='active'"
$out {>all</a>}
aYears.eachIndex(proc(y){
urlParams.year = y
if(0){
if(y===filterYear){
$out " <span class='active'>" y {</span>}
gotCurrentYear = true
}else{
$out " <a href='?" CGI.objToUrlParams(urlParams) "'>" y {</a>}
}
}else{
$out " <a href='?" CGI.objToUrlParams(urlParams) "'"
if(y === filterYear){
gotCurrentYear = true
$out " class='active'"
}
$out ">" y {</a>}
}
})
if(0 && filterYear && !gotCurrentYear){
$out ' '{<span title='No activity for this year for the active filter(s).'>} currentYear {</span>}
}
$out {</div>}
}
ns.initReportsView2 = proc(callingFilename, opt = null){
const CGI = api.cgi
const optDefaults = object{
filterOnTime: true,
filterOnUser: true
}
opt || (opt = object{})
optDefaults.eachProperty(proc(k,v){
opt.hasOwnProperty(k) || opt.set(k,v)
});
/*(undefined === opt.addMenu) && (opt.addMenu = true)
(undefined === opt.filterOnUser) && (opt.filterOnUser = true)
(undefined === opt.filterOnTime) && (opt.filterOnTime = false)
*/
var eventType = this.eventType = (CGI.getVar('type') || '*')
const sql = api.Buffer(200)
sql.appendf({CREATE TEMP VIEW v_reports AS
SELECT * FROM event WHERE type GLOB %1$Q},
this.eventType)
this.user = CGI.getVar('user')
if(this.user && opt.filterOnUser){
sql.appendf(' AND user=%1$Q', this.user)
}
if(opt.filterOnTime){
const year = (opt.year || CGI.getVar('year'))
if(Fossil.globMatches({[12][0-9][0-9][0-9]}, year)){
this.year = year
sql.appendf(' AND strftime("%%Y",mtime)=%1$Q', year)
}else if(year && ('integer' !==typename year)){
throw "Bad year value: "+year
}
}
//api.io.output(sql)
F.db.exec(sql)
this.generateSubmenu()
this.generateTypeLinks()
this.generateYearSelection()
return true
}
const typeMap = object{
'*': 'all',
ci: 'checkins',
w: 'wiki',
g: 'tags',
e: 'events',
t: 'tickets'
}
ns.getEventTypeLabel = proc(){
('*'===this.eventType) && return 'all types'
return typeMap.(this.eventType)
}.importSymbols(nameof typeMap)
ns.generateTypeLinks = proc(linkObj){
const CGI = api.cgi
const out = api.io.output
const currentEventType = (this.eventType || '*')
linkObj || (linkObj = object{})
linkObj.user = this.user
linkObj.year = this.year
linkObj.yearMonth = this.yearMonth
linkObj.yearWeek = this.yearWeek
$out {<div class='reports-filter-type'>Event type filter:}
const linker = proc(k){
const v = typeMap.(k)
linkObj.type = k
if(0){
if(k===currentEventType){
$out " <span class='active'>" v {</span>}
}else{
$out " <a href='?" CGI.objToUrlParams(linkObj) "'>" v {</a>}
}
}else{
$out " <a href='?" CGI.objToUrlParams(linkObj) "'"
(k===currentEventType) && $out " class='active'"
$out {>} v {</a>}
}
//return argv.callee
}
// bug: call chaining is not working here:
//linker({*})({ci})({t})({g})({wiki})
linker({*})
linker({ci})
linker({t})
linker({g})
linker({w})
linker({e})
$out {</div>}
}.importSymbols(nameof typeMap)
ns.generateRemoveUserLink = proc(params){
this.user || return
const out = api.io.output
params || (params = object{})
params.type = this.eventType
params.year = this.year
unset params.user
params = api.cgi.objToUrlParams(params)
$out {<div>[<a href='?} params {'>Remove "user" filter</a>]</div>}
}
ns.generateSubmenu = proc(){
const CGI = api.cgi
const out = api.io.output
const obj = object {
'reports/by-user': 'User',
'reports/by-week': 'Week',
'reports/by-month': 'Month',
'reports/by-year': 'Year',
'timeline': 'Timeline'
}
var urlParams = object{
user: this.user,
// CRASH: type: (('*'===this.eventType) ? undefined : this.eventType),
//type: this.eventType
year: this.year
}
('*'==this.eventType) || (urlParams.type = this.eventType)
urlParams = CGI.objToUrlParams(urlParams)
var activePage
const PI = CGI.request.ENV.PATH_INFO
const reportLink = proc(name, label, tryMarkActive=true){
label || (label = obj.(name))
const isActive = tryMarkActive && (PI && (0<PI.indexOf(name)))
if(0 && isActive){
activePage = name
$out " <strong>" label {</strong>}
}else{
$out "<a href='" CGI.cgiRoot name
urlParams && $out {?} urlParams
$out "'"
if(isActive){
activePage = name
tryMarkActive && $out " class='active'"
}
$out ">" label '</a> '
}
}
$out {<div class='menu-sub'>Activity reports by:} ' '
reportLink('reports/by-year')
reportLink('reports/by-month')
reportLink('reports/by-week')
reportLink('reports/by-user')
reportLink('timeline')
if(activePage && CGI.request.GET){
urlParams = ''
reportLink(activePage, '[remove filters]', false)
}
$out {</div>}
}
return ns
}(object{})