static S webChatBotLogsHTML2(final S baseLink, final SS params) { ret withDBLock(func -> S { new L l; for (Conversation conv : sortByCalculatedFieldDesc(list Conversation(), func(Conversation c) { empty(c.msgs) ? c.created : last(c.msgs).time })) { LL dialogs = reversed(unnull(conv.oldDialogs)); if (l(conv.msgs) > 1) l.add(webChatBotLogsHTML_formatDialog(str(conv.id), conv.msgs)); int i = 2; for (L msgs : dialogs) if (l(msgs) > 1) l.add(webChatBotLogsHTML_formatDialog(conv.id + "/" + (i++), msgs)); } int perPage = 50, n = parseIntOpt(params.get("n")); ret h3_htitle("Chat Logs") + pageNav2(baseLink, l(l), n, perPage, "n") + ul(subList(l, n, n+perPage), null, style := "margin-top: 1em"); }); }