Login
reports-util.fossi1ish at [c0b759f730]
Login

File th1ish/cgi/pages/reports-util.fossi1ish artifact bf4b1964e2 part of check-in c0b759f730


/**
  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{})