| rev | 
   line source | 
| 
bsw@11
 | 
     1 execute.view{
 | 
| 
bsw@11
 | 
     2   module = "timeline",
 | 
| 
bsw@11
 | 
     3   view = "_constants"
 | 
| 
bsw@11
 | 
     4 }
 | 
| 
bsw@11
 | 
     5 
 | 
| 
poelzi@144
 | 
     6 local active_name = ""
 | 
| 
poelzi@145
 | 
     7 local areas_ignored = {}
 | 
| 
bsw@11
 | 
     8 local options_box_count = param.get("options_box_count", atom.number) or 1
 | 
| 
bsw@11
 | 
     9 if options_box_count > 10 then
 | 
| 
bsw@11
 | 
    10   options_box_count = 10
 | 
| 
bsw@11
 | 
    11 end
 | 
| 
bsw@10
 | 
    12 
 | 
| 
bsw@10
 | 
    13 local function format_dow(dow)
 | 
| 
bsw@10
 | 
    14   local dows = {
 | 
| 
bsw@10
 | 
    15     _"Monday",
 | 
| 
bsw@10
 | 
    16     _"Tuesday",
 | 
| 
bsw@10
 | 
    17     _"Wednesday",
 | 
| 
bsw@10
 | 
    18     _"Thursday",
 | 
| 
bsw@10
 | 
    19     _"Friday",
 | 
| 
bsw@10
 | 
    20     _"Saturday",
 | 
| 
bsw@10
 | 
    21     _"Sunday"
 | 
| 
bsw@10
 | 
    22   }
 | 
| 
bsw@10
 | 
    23   return dows[dow+1]
 | 
| 
bsw@10
 | 
    24 end
 | 
| 
bsw@11
 | 
    25 slot.put_into("title", _"Timeline")
 | 
| 
bsw@10
 | 
    26 
 | 
| 
bsw@11
 | 
    27 slot.select("actions", function()
 | 
| 
bsw@11
 | 
    28   local setting_key = "liquidfeedback_frontend_timeline_current_options"
 | 
| 
bsw@11
 | 
    29   local setting = Setting:by_pk(app.session.member.id, setting_key)
 | 
| 
bsw@11
 | 
    30   local current_options = ""
 | 
| 
bsw@11
 | 
    31   if setting then
 | 
| 
bsw@11
 | 
    32     current_options = setting.value
 | 
| 
bsw@11
 | 
    33   end
 | 
| 
bsw@11
 | 
    34   local setting_maps = app.session.member:get_setting_maps_by_key("timeline_filters")
 | 
| 
bsw@11
 | 
    35   for i, setting_map in ipairs(setting_maps) do
 | 
| 
bsw@11
 | 
    36     local active
 | 
| 
bsw@11
 | 
    37     local options_string = setting_map.value
 | 
| 
bsw@11
 | 
    38     local name = setting_map.subkey
 | 
| 
bsw@11
 | 
    39     if options_string == current_options then
 | 
| 
bsw@11
 | 
    40       active = true
 | 
| 
poelzi@144
 | 
    41       active_name = name
 | 
| 
bsw@11
 | 
    42     end
 | 
| 
bsw@11
 | 
    43     ui.link{
 | 
| 
bsw/jbe@19
 | 
    44       image  = { static = "icons/16/time.png" },
 | 
| 
bsw/jbe@19
 | 
    45       attr   = { class = active and "action_active" or nil },
 | 
| 
bsw/jbe@19
 | 
    46       text   = name,
 | 
| 
poelzi@145
 | 
    47       form_attr = { class = "inline" },
 | 
| 
bsw@11
 | 
    48       module = 'timeline',
 | 
| 
bsw@11
 | 
    49       action = 'update',
 | 
| 
bsw@11
 | 
    50       params = {
 | 
| 
bsw@11
 | 
    51         options_string = options_string
 | 
| 
bsw@11
 | 
    52       },
 | 
| 
bsw@11
 | 
    53     }
 | 
| 
bsw@11
 | 
    54   end
 | 
| 
bsw@11
 | 
    55   if #setting_maps > 0 then
 | 
| 
bsw@11
 | 
    56     ui.link{
 | 
| 
bsw@11
 | 
    57       content = function()
 | 
| 
bsw@11
 | 
    58         ui.image{ static = "icons/16/wrench.png" }
 | 
| 
bsw@11
 | 
    59         slot.put(_"Manage filter")
 | 
| 
bsw@11
 | 
    60       end,
 | 
| 
bsw@11
 | 
    61       module = "timeline",
 | 
| 
bsw@11
 | 
    62       view = "list_filter",
 | 
| 
bsw@11
 | 
    63     }
 | 
| 
bsw@11
 | 
    64   end
 | 
| 
bsw@11
 | 
    65   ui.link{
 | 
| 
bsw@11
 | 
    66     content = function()
 | 
| 
bsw@11
 | 
    67       ui.image{ static = "icons/16/bullet_disk.png" }
 | 
| 
bsw@11
 | 
    68       slot.put(_"Save current filter")
 | 
| 
bsw@11
 | 
    69     end,
 | 
| 
bsw@11
 | 
    70     module = "timeline",
 | 
| 
bsw@11
 | 
    71     view = "save_filter",
 | 
| 
poelzi@144
 | 
    72     params = {
 | 
| 
poelzi@144
 | 
    73       current_name = active_name
 | 
| 
poelzi@144
 | 
    74     },
 | 
| 
bsw@11
 | 
    75     attr = { 
 | 
| 
bsw@11
 | 
    76       onclick = "el=document.getElementById('timeline_save');el.checked=true;el.form.submit();return(false);"
 | 
| 
bsw@11
 | 
    77     }
 | 
| 
bsw@11
 | 
    78   }
 | 
| 
bsw@11
 | 
    79 end)
 | 
| 
bsw@10
 | 
    80 
 | 
| 
bsw@11
 | 
    81 util.help("timeline.index", _"Timeline")
 | 
| 
bsw@10
 | 
    82 
 | 
| 
bsw@10
 | 
    83 ui.form{
 | 
| 
bsw@10
 | 
    84   module = "timeline",
 | 
| 
bsw@11
 | 
    85   action = "update",
 | 
| 
bsw@10
 | 
    86   content = function()
 | 
| 
bsw/jbe@19
 | 
    87     ui.container{
 | 
| 
bsw@11
 | 
    88 
 | 
| 
bsw@11
 | 
    89       content = function()
 | 
| 
bsw/jbe@19
 | 
    90 
 | 
| 
bsw/jbe@19
 | 
    91         ui.tag{
 | 
| 
bsw/jbe@19
 | 
    92           tag = "input",
 | 
| 
bsw/jbe@19
 | 
    93           attr = {
 | 
| 
bsw/jbe@19
 | 
    94             type = "radio",
 | 
| 
bsw/jbe@19
 | 
    95             id = "timeline_search_last_24h",
 | 
| 
bsw/jbe@19
 | 
    96             name = "search_from",
 | 
| 
bsw/jbe@19
 | 
    97             value = "last_24h",
 | 
| 
bsw/jbe@19
 | 
    98             checked = param.get("date") == "last_24h" and "checked" or nil
 | 
| 
bsw/jbe@19
 | 
    99           },
 | 
| 
bsw@11
 | 
   100         }
 | 
| 
bsw/jbe@19
 | 
   101 
 | 
| 
bsw/jbe@19
 | 
   102         ui.tag{
 | 
| 
bsw/jbe@19
 | 
   103           tag = "label",
 | 
| 
bsw/jbe@19
 | 
   104           attr = {
 | 
| 
bsw/jbe@19
 | 
   105             ["for"] = "timeline_search_last_24h" 
 | 
| 
bsw/jbe@19
 | 
   106           },
 | 
| 
bsw/jbe@19
 | 
   107           content = " " .. _"last 24 hours" .. " "
 | 
| 
bsw/jbe@19
 | 
   108         }
 | 
| 
bsw/jbe@19
 | 
   109 
 | 
| 
bsw/jbe@19
 | 
   110         ui.tag{
 | 
| 
bsw/jbe@19
 | 
   111           tag = "input",
 | 
| 
bsw/jbe@19
 | 
   112           attr = {
 | 
| 
bsw/jbe@19
 | 
   113             type = "radio",
 | 
| 
bsw/jbe@19
 | 
   114             id = "timeline_search_from_date",
 | 
| 
bsw/jbe@19
 | 
   115             name = "search_from",
 | 
| 
bsw/jbe@19
 | 
   116             value = "date",
 | 
| 
bsw/jbe@19
 | 
   117             checked = not (param.get("date") == "last_24h") and "checked" or nil
 | 
| 
bsw/jbe@19
 | 
   118           },
 | 
| 
bsw@11
 | 
   119         }
 | 
| 
bsw@11
 | 
   120 
 | 
| 
bsw/jbe@19
 | 
   121         slot.put(" ")
 | 
| 
bsw/jbe@19
 | 
   122         local current_date = param.get("date")
 | 
| 
bsw/jbe@19
 | 
   123         if not current_date or #current_date == 0 or current_date == "last_24h" then
 | 
| 
bsw/jbe@19
 | 
   124           current_date = tostring(db:query("select now()::date as date")[1].date)
 | 
| 
bsw/jbe@19
 | 
   125         end
 | 
| 
bsw/jbe@19
 | 
   126         ui.tag{
 | 
| 
bsw/jbe@19
 | 
   127           tag = "input",
 | 
| 
bsw/jbe@19
 | 
   128           attr = {
 | 
| 
bsw/jbe@19
 | 
   129             type = "text",
 | 
| 
bsw/jbe@19
 | 
   130             id = "timeline_search_date",
 | 
| 
bsw/jbe@19
 | 
   131             style = "width: 10em;",
 | 
| 
bsw/jbe@19
 | 
   132             onchange = "this.form.submit();",
 | 
| 
bsw/jbe@19
 | 
   133             onclick = "document.getElementById('timeline_search_from_date').checked = true;",
 | 
| 
bsw/jbe@19
 | 
   134             name = "date",
 | 
| 
bsw/jbe@19
 | 
   135             value = current_date
 | 
| 
bsw/jbe@19
 | 
   136           },
 | 
| 
bsw/jbe@19
 | 
   137           content = function() end
 | 
| 
bsw/jbe@19
 | 
   138         }
 | 
| 
bsw/jbe@19
 | 
   139     
 | 
| 
bsw/jbe@19
 | 
   140         ui.script{ static = "gregor.js/gregor.js" }
 | 
| 
poelzi@146
 | 
   141         util.gregor("timeline_search_date", true)
 | 
| 
bsw/jbe@19
 | 
   142     
 | 
| 
bsw/jbe@19
 | 
   143     
 | 
| 
bsw/jbe@19
 | 
   144         ui.link{
 | 
| 
bsw/jbe@19
 | 
   145           attr = { style = "margin-left: 1em; font-weight: bold;", onclick = "document.getElementById('timeline_search_date').form.submit();return(false);" },
 | 
| 
bsw/jbe@19
 | 
   146           content = function()
 | 
| 
bsw/jbe@19
 | 
   147             ui.image{
 | 
| 
bsw/jbe@19
 | 
   148               attr = { style = "margin-right: 0.25em;" },
 | 
| 
bsw/jbe@19
 | 
   149               static = "icons/16/magnifier.png"
 | 
| 
bsw/jbe@19
 | 
   150             }
 | 
| 
bsw/jbe@19
 | 
   151             slot.put(_"Search")
 | 
| 
bsw/jbe@19
 | 
   152           end,
 | 
| 
bsw/jbe@19
 | 
   153           external = "#",
 | 
| 
bsw/jbe@19
 | 
   154         }
 | 
| 
bsw/jbe@19
 | 
   155         local show_options = param.get("show_options", atom.boolean)
 | 
| 
bsw/jbe@19
 | 
   156         ui.link{
 | 
| 
bsw/jbe@19
 | 
   157           attr = { style = "margin-left: 1em;", onclick = "el=document.getElementById('timeline_show_options');el.checked=" .. tostring(not show_options) .. ";el.form.submit();return(false);" },
 | 
| 
bsw/jbe@19
 | 
   158           content = function()
 | 
| 
bsw/jbe@19
 | 
   159             ui.image{
 | 
| 
bsw/jbe@19
 | 
   160               attr = { style = "margin-right: 0.25em;" },
 | 
| 
bsw/jbe@19
 | 
   161               static = "icons/16/text_list_bullets.png"
 | 
| 
bsw/jbe@19
 | 
   162             }
 | 
| 
bsw/jbe@19
 | 
   163             slot.put(not show_options and _"Show filter details" or _"Hide filter details")
 | 
| 
bsw/jbe@19
 | 
   164           end,
 | 
| 
bsw/jbe@19
 | 
   165           external = "#",
 | 
| 
bsw/jbe@19
 | 
   166         }
 | 
| 
bsw@11
 | 
   167 
 | 
| 
bsw/jbe@19
 | 
   168         ui.field.boolean{
 | 
| 
bsw/jbe@19
 | 
   169           attr = { id = "timeline_show_options", style = "display: none;", onchange="this.form.submit();" },
 | 
| 
bsw/jbe@19
 | 
   170           name = "show_options",
 | 
| 
bsw/jbe@19
 | 
   171           value = param.get("show_options", atom.boolean)
 | 
| 
bsw/jbe@19
 | 
   172         }
 | 
| 
poelzi@144
 | 
   173         ui.hidden_field{ name = "current_name", value = active_name }
 | 
| 
bsw/jbe@19
 | 
   174         ui.field.boolean{
 | 
| 
bsw/jbe@19
 | 
   175           attr = { id = "timeline_save", style = "display: none;", onchange="this.form.submit();" },
 | 
| 
bsw/jbe@19
 | 
   176           name = "save",
 | 
| 
bsw/jbe@19
 | 
   177           value = false
 | 
| 
bsw/jbe@19
 | 
   178         }
 | 
| 
bsw/jbe@19
 | 
   179 
 | 
| 
bsw/jbe@19
 | 
   180       end
 | 
| 
bsw@10
 | 
   181     }
 | 
| 
bsw@11
 | 
   182 
 | 
| 
bsw@11
 | 
   183     ui.container{
 | 
| 
bsw@11
 | 
   184       attr = { 
 | 
| 
bsw@11
 | 
   185         id = "timeline_options_boxes",
 | 
| 
bsw@11
 | 
   186         class = "vertical",
 | 
| 
bsw@11
 | 
   187         style = not param.get("show_options", atom.boolean) and "display: none;" or nil
 | 
| 
bsw@10
 | 
   188       },
 | 
| 
bsw@11
 | 
   189       content = function()
 | 
| 
bsw@11
 | 
   190 
 | 
| 
bsw@11
 | 
   191         local function option_field(event_ident, filter_ident)
 | 
| 
bsw@11
 | 
   192           local param_name
 | 
| 
bsw@11
 | 
   193           if not filter_ident then
 | 
| 
bsw@11
 | 
   194             param_name = "option_" .. event_ident
 | 
| 
bsw@11
 | 
   195           else
 | 
| 
bsw@11
 | 
   196             param_name = "option_" .. event_ident .. "_" .. filter_ident
 | 
| 
bsw@11
 | 
   197           end
 | 
| 
bsw@11
 | 
   198           local value = param.get(param_name, atom.boolean)
 | 
| 
bsw@11
 | 
   199           ui.field.boolean{
 | 
| 
bsw@11
 | 
   200             attr = { id = param_name },
 | 
| 
bsw@11
 | 
   201             name = param_name,
 | 
| 
bsw@11
 | 
   202             value = value,
 | 
| 
bsw@11
 | 
   203           }
 | 
| 
bsw@11
 | 
   204         end
 | 
| 
bsw@11
 | 
   205 
 | 
| 
bsw@11
 | 
   206         local function filter_option_fields(event_ident, filter_idents)
 | 
| 
bsw@11
 | 
   207 
 | 
| 
bsw@11
 | 
   208           for i, filter_ident in ipairs(filter_idents) do
 | 
| 
bsw@11
 | 
   209               slot.put("<td>")
 | 
| 
bsw@11
 | 
   210               option_field(event_ident, filter_ident)
 | 
| 
bsw@11
 | 
   211               slot.put("</td><td><div class='ui_field_label label_right'>")
 | 
| 
bsw@11
 | 
   212               ui.tag{
 | 
| 
bsw@11
 | 
   213                 attr = { ["for"] = "option_" .. event_ident .. "_" .. filter_ident },
 | 
| 
bsw@11
 | 
   214                 tag = "label",
 | 
| 
bsw@11
 | 
   215                 content = filter_names[filter_ident]
 | 
| 
bsw@11
 | 
   216               }
 | 
| 
bsw@11
 | 
   217               slot.put("</div></td>")
 | 
| 
bsw@11
 | 
   218           end
 | 
| 
bsw@11
 | 
   219 
 | 
| 
bsw@11
 | 
   220         end
 | 
| 
bsw@10
 | 
   221 
 | 
| 
bsw@11
 | 
   222         local event_groups = {
 | 
| 
bsw@11
 | 
   223           {
 | 
| 
bsw@11
 | 
   224             title = _"Issue events",
 | 
| 
bsw@11
 | 
   225             event_idents = {
 | 
| 
bsw@11
 | 
   226               "issue_created",
 | 
| 
bsw@11
 | 
   227               "issue_canceled",
 | 
| 
bsw@11
 | 
   228               "issue_accepted",
 | 
| 
bsw@11
 | 
   229               "issue_half_frozen",
 | 
| 
bsw@11
 | 
   230               "issue_finished_without_voting",
 | 
| 
bsw@11
 | 
   231               "issue_voting_started",
 | 
| 
bsw@11
 | 
   232               "issue_finished_after_voting",
 | 
| 
bsw@11
 | 
   233             },
 | 
| 
bsw@11
 | 
   234             filter_idents = {
 | 
| 
bsw@11
 | 
   235               "membership",
 | 
| 
bsw@11
 | 
   236               "interested"
 | 
| 
bsw@11
 | 
   237             }
 | 
| 
bsw@11
 | 
   238           },
 | 
| 
bsw@11
 | 
   239           {
 | 
| 
bsw@11
 | 
   240             title = _"Initiative events",
 | 
| 
bsw@11
 | 
   241             event_idents = {
 | 
| 
bsw@11
 | 
   242               "initiative_created",
 | 
| 
bsw@11
 | 
   243               "initiative_revoked",
 | 
| 
bsw@11
 | 
   244               "draft_created",
 | 
| 
bsw@11
 | 
   245               "suggestion_created",
 | 
| 
bsw@11
 | 
   246             },
 | 
| 
bsw@11
 | 
   247             filter_idents = {
 | 
| 
bsw@11
 | 
   248               "membership",
 | 
| 
bsw@11
 | 
   249               "interested",
 | 
| 
bsw@11
 | 
   250               "supporter",
 | 
| 
bsw@11
 | 
   251               "potential_supporter",
 | 
| 
bsw@11
 | 
   252               "initiator"
 | 
| 
bsw@11
 | 
   253             }
 | 
| 
bsw@11
 | 
   254           }
 | 
| 
bsw@11
 | 
   255         }
 | 
| 
bsw@11
 | 
   256 
 | 
| 
bsw@11
 | 
   257         slot.put("<table>")
 | 
| 
bsw@11
 | 
   258 
 | 
| 
bsw@11
 | 
   259         for i_event_group, event_group in ipairs(event_groups) do
 | 
| 
bsw@11
 | 
   260           slot.put("<tr>")
 | 
| 
bsw@11
 | 
   261           slot.put("<th colspan='2'>")
 | 
| 
bsw@11
 | 
   262           slot.put(event_group.title)
 | 
| 
bsw@11
 | 
   263           slot.put("</th><th colspan='10'>")
 | 
| 
bsw@11
 | 
   264           slot.put(_"Show only events which match... (or associtated)")
 | 
| 
bsw@11
 | 
   265           slot.put("</th>")
 | 
| 
bsw@11
 | 
   266           slot.put("</tr>")
 | 
| 
bsw@11
 | 
   267           local event_idents = event_group.event_idents
 | 
| 
bsw@11
 | 
   268           for i, event_ident in ipairs(event_idents) do
 | 
| 
bsw@11
 | 
   269             slot.put("<tr><td>")
 | 
| 
bsw@11
 | 
   270             option_field(event_ident)
 | 
| 
bsw@11
 | 
   271             slot.put("</td><td><div class='ui_field_label label_right'>")
 | 
| 
bsw@11
 | 
   272             ui.tag{
 | 
| 
bsw@11
 | 
   273               attr = { ["for"] = "option_" .. event_ident },
 | 
| 
bsw@11
 | 
   274               tag = "label",
 | 
| 
bsw@11
 | 
   275               content = event_names[event_ident]
 | 
| 
bsw@11
 | 
   276             }
 | 
| 
bsw@11
 | 
   277             slot.put("</div></td>")
 | 
| 
bsw@11
 | 
   278             filter_option_fields(event_ident, event_group.filter_idents)
 | 
| 
bsw@11
 | 
   279             slot.put("</tr>")
 | 
| 
bsw@11
 | 
   280           end
 | 
| 
bsw@11
 | 
   281         end
 | 
| 
bsw@11
 | 
   282 
 | 
| 
bsw@11
 | 
   283         slot.put("</table>")
 | 
| 
bsw@11
 | 
   284 
 | 
| 
poelzi@145
 | 
   285         local areas = Area:new_selector():add_where("active='t'"):exec()
 | 
| 
poelzi@145
 | 
   286         for i, area in ipairs(areas) do
 | 
| 
poelzi@145
 | 
   287           if param.get("option_ignore_area_"..tostring(area.id)) then
 | 
| 
poelzi@145
 | 
   288             areas_ignored[#areas_ignored+1] = area.id
 | 
| 
poelzi@145
 | 
   289           end
 | 
| 
poelzi@145
 | 
   290         end
 | 
| 
poelzi@145
 | 
   291 
 | 
| 
poelzi@145
 | 
   292         ui.multiselect{
 | 
| 
poelzi@145
 | 
   293           style = "checkbox",
 | 
| 
poelzi@145
 | 
   294           selected_ids = areas_ignored, 
 | 
| 
poelzi@145
 | 
   295           container_attr = { class = "ignore_area_list" },
 | 
| 
poelzi@145
 | 
   296           container2_attr = { class = "ignore_area_item" },
 | 
| 
poelzi@145
 | 
   297           label = _"Ignore Areas",
 | 
| 
poelzi@145
 | 
   298           name = "option_ignore_area[]",
 | 
| 
poelzi@145
 | 
   299           foreign_records = areas,
 | 
| 
poelzi@145
 | 
   300           foreign_id      = "id",
 | 
| 
poelzi@145
 | 
   301           foreign_name    = "name"
 | 
| 
poelzi@145
 | 
   302         }
 | 
| 
poelzi@145
 | 
   303 
 | 
| 
bsw@11
 | 
   304       end
 | 
| 
bsw@10
 | 
   305     }
 | 
| 
bsw@10
 | 
   306   end
 | 
| 
bsw@10
 | 
   307 }
 | 
| 
bsw@10
 | 
   308 
 | 
| 
bsw@10
 | 
   309 local date = param.get("date")
 | 
| 
bsw/jbe@19
 | 
   310 
 | 
| 
bsw@11
 | 
   311 if not date or #date == 0 then
 | 
| 
bsw@10
 | 
   312   date = "today"
 | 
| 
bsw@10
 | 
   313 end
 | 
| 
bsw@11
 | 
   314 
 | 
| 
bsw@11
 | 
   315 local timeline_selector
 | 
| 
bsw@11
 | 
   316 
 | 
| 
bsw@11
 | 
   317 for event, event_name in pairs(event_names) do
 | 
| 
bsw@11
 | 
   318 
 | 
| 
bsw@11
 | 
   319   if param.get("option_" .. event, atom.boolean) then
 | 
| 
bsw@11
 | 
   320 
 | 
| 
bsw@11
 | 
   321     local tmp = Timeline:new_selector()
 | 
| 
bsw/jbe@19
 | 
   322       if event == "draft_created" then
 | 
| 
bsw/jbe@19
 | 
   323         tmp
 | 
| 
bsw/jbe@19
 | 
   324           :reset_fields()
 | 
| 
bsw/jbe@19
 | 
   325           :add_field("max(timeline.occurrence)", "occurrence")
 | 
| 
bsw/jbe@19
 | 
   326           :add_field("timeline.event", nil,  { "grouped" })
 | 
| 
bsw/jbe@19
 | 
   327           :add_field("timeline.issue_id", nil, { "grouped" })
 | 
| 
bsw@41
 | 
   328           :add_field("draft.initiative_id", nil, { "grouped" })
 | 
| 
bsw/jbe@19
 | 
   329           :add_field("max(timeline.draft_id)", "draft_id")
 | 
| 
bsw/jbe@19
 | 
   330           :add_field("timeline.suggestion_id", nil, { "grouped" })
 | 
| 
bsw/jbe@19
 | 
   331           :add_field("COUNT(*)", "count")
 | 
| 
bsw/jbe@19
 | 
   332       else
 | 
| 
bsw/jbe@19
 | 
   333         tmp
 | 
| 
bsw/jbe@19
 | 
   334           :add_field("1", "count")
 | 
| 
bsw/jbe@19
 | 
   335       end
 | 
| 
bsw@11
 | 
   336 
 | 
| 
bsw/jbe@19
 | 
   337       if date == "last_24h" then
 | 
| 
bsw/jbe@19
 | 
   338         tmp:add_where{ "occurrence > now() - '24 hours'::interval" }
 | 
| 
bsw/jbe@19
 | 
   339       else
 | 
| 
poelzi@146
 | 
   340         local start,stop = string.gmatch(date, "(%d+-%d+-%d+):(%d+-%d+-%d+)")()
 | 
| 
poelzi@146
 | 
   341         if start and stop then
 | 
| 
poelzi@146
 | 
   342           tmp:add_where{ "occurrence::date >= ?::date AND occurrence::date <= ?::date", start, stop }
 | 
| 
poelzi@146
 | 
   343         else
 | 
| 
poelzi@146
 | 
   344           local age = string.gmatch(date, "age:(.+)")()
 | 
| 
poelzi@146
 | 
   345           if age then
 | 
| 
poelzi@146
 | 
   346             tmp:add_where{ "occurrence >= now() - ?::interval", age }
 | 
| 
poelzi@146
 | 
   347           else 
 | 
| 
poelzi@146
 | 
   348             local since = string.gmatch(date, "since:%s*(%d+-%d+-%d+)%s*")()
 | 
| 
poelzi@146
 | 
   349             if since then
 | 
| 
poelzi@146
 | 
   350               tmp:add_where{ "occurrence::date >= ?::date", since }
 | 
| 
poelzi@146
 | 
   351             else
 | 
| 
poelzi@146
 | 
   352               tmp:add_where{ "occurrence::date = ?::date", date }
 | 
| 
poelzi@146
 | 
   353             end
 | 
| 
poelzi@146
 | 
   354           end
 | 
| 
poelzi@146
 | 
   355         end
 | 
| 
bsw/jbe@19
 | 
   356       end
 | 
| 
bsw/jbe@19
 | 
   357       tmp
 | 
| 
bsw/jbe@19
 | 
   358         :left_join("draft", nil, "draft.id = timeline.draft_id")
 | 
| 
bsw/jbe@19
 | 
   359         :left_join("suggestion", nil, "suggestion.id = timeline.suggestion_id")
 | 
| 
bsw/jbe@19
 | 
   360         :left_join("initiative", nil, "initiative.id = timeline.initiative_id or initiative.id = draft.initiative_id or initiative.id = suggestion.initiative_id")
 | 
| 
bsw/jbe@19
 | 
   361         :left_join("issue", nil, "issue.id = timeline.issue_id or issue.id = initiative.issue_id")
 | 
| 
bsw/jbe@19
 | 
   362         :left_join("area", nil, "area.id = issue.area_id")
 | 
| 
bsw@11
 | 
   363 
 | 
| 
bsw/jbe@19
 | 
   364         :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id} )
 | 
| 
bsw/jbe@19
 | 
   365         :left_join("initiator", "_initiator", { "_initiator.initiative_id = initiative.id AND _initiator.member_id = ?", app.session.member.id} )
 | 
| 
bsw/jbe@19
 | 
   366         :left_join("membership", "_membership", { "_membership.area_id = area.id AND _membership.member_id = ?", app.session.member.id} )
 | 
| 
bsw/jbe@19
 | 
   367         :left_join("supporter", "_supporter", { "_supporter.initiative_id = initiative.id AND _supporter.member_id = ?", app.session.member.id} )
 | 
| 
bsw/jbe@19
 | 
   368 
 | 
| 
bsw/jbe@19
 | 
   369       local group
 | 
| 
bsw/jbe@19
 | 
   370       if event == "draft_created" then
 | 
| 
bsw/jbe@19
 | 
   371         group = { "grouped" }
 | 
| 
poelzi@172
 | 
   372         tmp:add_where{"EXISTS(SELECT 1 from draft as cdraft WHERE draft.initiative_id = cdraft.initiative_id AND cdraft.id != draft.id ORDER BY cdraft.id DESC)"}
 | 
| 
bsw/jbe@19
 | 
   373       end
 | 
| 
bsw/jbe@19
 | 
   374 
 | 
| 
bsw/jbe@19
 | 
   375       tmp
 | 
| 
bsw/jbe@19
 | 
   376         :add_field("(_interest.member_id NOTNULL)", "is_interested", group)
 | 
| 
bsw/jbe@19
 | 
   377         :add_field("(_initiator.member_id NOTNULL)", "is_initiator", group)
 | 
| 
bsw/jbe@19
 | 
   378         :add_field({"(_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_supporter", group)
 | 
| 
bsw/jbe@19
 | 
   379         :add_field({"EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_potential_supporter", group)
 | 
| 
bsw/jbe@19
 | 
   380   --    :left_join("member", nil, "member.id = timeline.member_id", group)
 | 
| 
bsw/jbe@19
 | 
   381 
 | 
| 
poelzi@145
 | 
   382       if #areas_ignored > 0 then
 | 
| 
poelzi@145
 | 
   383         tmp:add_where{"area.id NOT IN ($)", areas_ignored}
 | 
| 
poelzi@145
 | 
   384       end
 | 
| 
bsw@11
 | 
   385 
 | 
| 
bsw@11
 | 
   386     tmp:add_where{ "event = ?", event }
 | 
| 
bsw@11
 | 
   387 
 | 
| 
bsw@11
 | 
   388     local filters = {}
 | 
| 
bsw@11
 | 
   389     if param.get("option_" .. event .. "_membership", atom.boolean) then
 | 
| 
bsw@11
 | 
   390       filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _membership.member_id NOTNULL"
 | 
| 
bsw@11
 | 
   391     end
 | 
| 
bsw@11
 | 
   392 
 | 
| 
bsw@11
 | 
   393     if param.get("option_" .. event .. "_supporter", atom.boolean) then
 | 
| 
bsw@11
 | 
   394       filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR ((_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1))"
 | 
| 
bsw@11
 | 
   395     end
 | 
| 
bsw@11
 | 
   396 
 | 
| 
bsw@11
 | 
   397     if param.get("option_" .. event .. "_potential_supporter", atom.boolean) then
 | 
| 
bsw@11
 | 
   398       filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR ((_supporter.member_id NOTNULL) AND EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1))"
 | 
| 
bsw@11
 | 
   399     end
 | 
| 
bsw@10
 | 
   400 
 | 
| 
bsw@11
 | 
   401     if param.get("option_" .. event .. "_interested", atom.boolean) then
 | 
| 
bsw@11
 | 
   402       filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _interest.member_id NOTNULL"
 | 
| 
bsw@11
 | 
   403     end
 | 
| 
bsw@11
 | 
   404 
 | 
| 
bsw@11
 | 
   405     if param.get("option_" .. event .. "_initiator", atom.boolean) then
 | 
| 
bsw@11
 | 
   406       filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _initiator.member_id NOTNULL"
 | 
| 
bsw@11
 | 
   407     end
 | 
| 
bsw@11
 | 
   408 
 | 
| 
bsw@11
 | 
   409     if #filters > 0 then
 | 
| 
bsw@11
 | 
   410       local filter_string = "(" .. table.concat(filters, ") OR (") .. ")"
 | 
| 
bsw/jbe@19
 | 
   411       tmp:add_where{ filter_string, app.session.member.id, app.session.member.id }
 | 
| 
bsw@11
 | 
   412     end
 | 
| 
bsw@11
 | 
   413   
 | 
| 
bsw@11
 | 
   414     if not timeline_selector then
 | 
| 
bsw@11
 | 
   415       timeline_selector = tmp
 | 
| 
bsw@11
 | 
   416     else
 | 
| 
bsw@11
 | 
   417       timeline_selector:union_all(tmp)
 | 
| 
bsw@11
 | 
   418     end
 | 
| 
bsw@11
 | 
   419   end
 | 
| 
bsw@11
 | 
   420 end
 | 
| 
bsw@11
 | 
   421 
 | 
| 
bsw@11
 | 
   422 if timeline_selector then
 | 
| 
bsw@11
 | 
   423   
 | 
| 
bsw@11
 | 
   424   local initiatives_per_page = param.get("initiatives_per_page", atom.number)
 | 
| 
bsw@11
 | 
   425   
 | 
| 
bsw@11
 | 
   426   local outer_timeline_selector = db:new_selector()
 | 
| 
bsw@11
 | 
   427   outer_timeline_selector._class = Timeline
 | 
| 
bsw/jbe@19
 | 
   428   outer_timeline_selector
 | 
| 
bsw/jbe@19
 | 
   429     :add_field{ "timeline.*" }
 | 
| 
bsw/jbe@19
 | 
   430     :from({"($)", { timeline_selector }}, "timeline" )
 | 
| 
bsw/jbe@19
 | 
   431     :add_order_by("occurrence DESC")
 | 
| 
bsw/jbe@19
 | 
   432 
 | 
| 
bsw@11
 | 
   433   slot.put("<br />")
 | 
| 
bsw@11
 | 
   434   execute.view{
 | 
| 
bsw@11
 | 
   435     module = "timeline",
 | 
| 
bsw@11
 | 
   436     view = "_list",
 | 
| 
bsw@11
 | 
   437     params = {
 | 
| 
bsw@11
 | 
   438       timeline_selector = outer_timeline_selector,
 | 
| 
bsw@11
 | 
   439       per_page = param.get("per_page", atom.number),
 | 
| 
bsw@11
 | 
   440       event_names = event_names,
 | 
| 
bsw@11
 | 
   441       initiatives_per_page = initiatives_per_page
 | 
| 
bsw@11
 | 
   442     }
 | 
| 
bsw@10
 | 
   443   }
 | 
| 
bsw@11
 | 
   444 
 | 
| 
bsw@11
 | 
   445 else
 | 
| 
bsw@10
 | 
   446 
 | 
| 
bsw@11
 | 
   447   slot.put(_"No events selected to list")
 | 
| 
bsw@11
 | 
   448 
 | 
| 
bsw@11
 | 
   449 end |