logs: Added filtering.
This commit is contained in:
@@ -1,8 +1,12 @@
|
|||||||
module.exports = class {
|
module.exports = class {
|
||||||
onCreate(input) {
|
onCreate() {
|
||||||
this.state = {
|
this.state = {
|
||||||
classes: ["menu-link", "color-menu"],
|
classes: [],
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onInput(input) {
|
||||||
|
this.state.classes = ["menu-link", "color-menu"]
|
||||||
|
|
||||||
if (input.dark) {
|
if (input.dark) {
|
||||||
this.state.classes.push(input)
|
this.state.classes.push(input)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<menu-gap />
|
<menu-gap />
|
||||||
</if-permitted>
|
</if-permitted>
|
||||||
<menu-header>Links</menu-header>
|
<menu-header>Links</menu-header>
|
||||||
<menu-link href=("/logs/?channels="+input.log.channel.name) icon="#">${input.log.channel.name}</menu-link>
|
<menu-link href=("/logs/?channels="+encodeURIComponent(input.log.channel.name)) icon="#">${input.log.channel.name}</menu-link>
|
||||||
<menu-link if(input.log.channel.eventName) href=("/logs/?channels="+input.log.channel.eventName) icon="E">${input.log.channel.eventName}</menu-link>
|
<menu-link if(input.log.channel.eventName) href=("/logs/?channels="+input.log.channel.eventName) icon="E">${input.log.channel.eventName}</menu-link>
|
||||||
<for(character in input.log.characters)>
|
<for(character in input.log.characters)>
|
||||||
<menu-link href=("/logs/?characters="+character.id) icon="C">${character.name} <span class="weak">(${character.author})</span></menu-link>
|
<menu-link href=("/logs/?characters="+character.id) icon="C">${character.name} <span class="weak">(${character.author})</span></menu-link>
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
const {channelApi} = require("../../../../../rpdata/api/Channel")
|
||||||
|
const {logHeaderApi} = require("../../../../../rpdata/api/LogHeader")
|
||||||
|
|
||||||
|
module.exports = class {
|
||||||
|
onCreate() {
|
||||||
|
this.state = {
|
||||||
|
search: "",
|
||||||
|
filters: [],
|
||||||
|
channels: [],
|
||||||
|
eventNames: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
this.first = true
|
||||||
|
}
|
||||||
|
|
||||||
|
onInput(input) {
|
||||||
|
if (input.filters) {
|
||||||
|
if (this.timeout != null) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.searchFilters()
|
||||||
|
}, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(input.eventNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount() {
|
||||||
|
this.timeout = null
|
||||||
|
|
||||||
|
if (this.state.channels.length === 0) {
|
||||||
|
channelApi.list().then(channels => {
|
||||||
|
this.state.channels = channels
|
||||||
|
this.searchFilters()
|
||||||
|
}).catch(err => {
|
||||||
|
console.warn("Failed to fetch channels:", err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.state.eventNames.length === 0) {
|
||||||
|
logHeaderApi.eventNames().then(eventNames => {
|
||||||
|
this.state.eventNames = eventNames
|
||||||
|
this.searchFilters()
|
||||||
|
}).catch(err => {
|
||||||
|
console.warn("Failed to fetch eventNames:", err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getEl("search").addEventListener("keydown", ev => {
|
||||||
|
if (this.waiting) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.timeout != null) {
|
||||||
|
clearTimeout(this.timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.timeout = setTimeout(() => {
|
||||||
|
this.timeout = null
|
||||||
|
this.state.search = ev.target.value
|
||||||
|
|
||||||
|
this.searchFilters()
|
||||||
|
}, 200)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnmount() {
|
||||||
|
clearTimeout(this.timeout)
|
||||||
|
this.timeout = null
|
||||||
|
|
||||||
|
this.state.search = ""
|
||||||
|
this.state.filters = []
|
||||||
|
}
|
||||||
|
|
||||||
|
add(type, value, filter) {
|
||||||
|
this.emit("add", type, value)
|
||||||
|
|
||||||
|
this.state.filters = this.state.filters.filter(f => f != filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
searchFilters() {
|
||||||
|
const filters = []
|
||||||
|
const search = this.state.search.toLowerCase()
|
||||||
|
|
||||||
|
for (const channel of this.state.channels) {
|
||||||
|
if (search == "" || channel.name.toLowerCase().includes(search)) {
|
||||||
|
if (this.input.filter.channels && this.input.filter.channels.includes(channel.name)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filters.push({
|
||||||
|
colorClass: "color-tag-location",
|
||||||
|
text: channel.name,
|
||||||
|
type: "channels",
|
||||||
|
value: channel.name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const name of this.state.eventNames) {
|
||||||
|
if (search == "" || name.toLowerCase().includes(search)) {
|
||||||
|
if (this.input.filter.events && this.input.filter.events.includes(name)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filters.push({
|
||||||
|
colorClass: "color-tag-event",
|
||||||
|
text: name,
|
||||||
|
type: "events",
|
||||||
|
value: name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const character of this.input.characters) {
|
||||||
|
if (search == "" || character.name.toLowerCase().includes(search)) {
|
||||||
|
if (this.input.filter.characters && this.input.filter.characters.includes(character.id)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filters.push({
|
||||||
|
colorClass: "color-tag-character",
|
||||||
|
text: character.name,
|
||||||
|
type: "characters",
|
||||||
|
value: character.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filters.sort((a, b) => {
|
||||||
|
let aCompare = a.text
|
||||||
|
let bCompare = b.text
|
||||||
|
|
||||||
|
if (a.text.charAt(0) === "#") {
|
||||||
|
aCompare = a.text.slice(1)
|
||||||
|
}
|
||||||
|
if (b.text.charAt(0) === "#") {
|
||||||
|
bCompare = b.text.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return aCompare.localeCompare(bCompare)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.state.filters = filters
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<label>Search</label>
|
||||||
|
<input key="search" placeholder="" class="big" value=state.search />
|
||||||
|
|
||||||
|
<label>Filters</label>
|
||||||
|
<div if(state.search.length > 0) class="filter-row" >
|
||||||
|
<div class=["content", "color-text"]>Search: ${state.search}</div>
|
||||||
|
<button disabled=state.loading on-click("emit", "add", "search", state.search)>${input.filter.search ? "Replace" : "Add"}</button>
|
||||||
|
</div>
|
||||||
|
<div for(filter in state.filters) class="filter-row" >
|
||||||
|
<div class=["content", filter.colorClass]>${filter.text}</div>
|
||||||
|
<button disabled=state.loading on-click("add", filter.type, filter.value, filter)>Add</button>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
const moment = require("moment")
|
||||||
|
|
||||||
|
const {logsApi} = require("../../../../../rpdata/api/Log")
|
||||||
|
|
||||||
|
module.exports = class {
|
||||||
|
onCreate(input) {
|
||||||
|
this.state = {
|
||||||
|
filters: [],
|
||||||
|
search: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.emit("close")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import moment from "moment"
|
||||||
|
|
||||||
|
<modal class="modal color-text nolabel" key="modal" enabled=(input.enabled) closable on-close("close") >
|
||||||
|
<h1 key="stuff">Add Filter</h1>
|
||||||
|
|
||||||
|
<add-filter-modal-body characters=input.characters filter=input.filter on-add("emit", "add") />
|
||||||
|
</modal>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
div.filter-row {
|
||||||
|
padding: 0.25em;
|
||||||
|
border-bottom: 1px solid rgba(0, 220, 255, 0.125);
|
||||||
|
|
||||||
|
div.content {
|
||||||
|
width: 80%;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 20% !important;
|
||||||
|
display: inline-block !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,68 @@
|
|||||||
module.exports = class {
|
module.exports = class {
|
||||||
|
onCreate() {
|
||||||
|
this.state = {
|
||||||
|
filters: [],
|
||||||
|
filtered: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onInput(input) {
|
||||||
|
if (!input.filter) {
|
||||||
|
this.state.filters = []
|
||||||
|
this.state.filtered = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const filters = []
|
||||||
|
const {characters, channels, events, search} = input.filter
|
||||||
|
|
||||||
|
if (search != null) {
|
||||||
|
filters.push({
|
||||||
|
type: "search",
|
||||||
|
key: "search",
|
||||||
|
icon: "T",
|
||||||
|
color: "color-text",
|
||||||
|
text: search,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const character of (characters || [])) {
|
||||||
|
filters.push({
|
||||||
|
type: "characters",
|
||||||
|
key: character,
|
||||||
|
icon: "C",
|
||||||
|
color: "color-tag-character",
|
||||||
|
id: character,
|
||||||
|
text: (input.characters.find(c => c.id === character) || {name: "Unknown ("+character+")"}).name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const channel of (channels || [])) {
|
||||||
|
filters.push({
|
||||||
|
type: "channels",
|
||||||
|
key: channel.replace(/'/g, "__"),
|
||||||
|
icon: "#",
|
||||||
|
color: "color-tag-location",
|
||||||
|
id: channel,
|
||||||
|
text: channel,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const event of (events || [])) {
|
||||||
|
filters.push({
|
||||||
|
type: "events",
|
||||||
|
key: event.replace(/['\s\.]/g, "__"),
|
||||||
|
icon: "E",
|
||||||
|
color: "color-tag-event",
|
||||||
|
id: event,
|
||||||
|
text: event,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.filters = filters
|
||||||
|
this.state.filtered = (filters.length > 0)
|
||||||
|
}
|
||||||
|
|
||||||
select(value) {
|
select(value) {
|
||||||
this.emit("select", value)
|
this.emit("select", value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
<menu user=input.user>
|
<menu user=input.user>
|
||||||
<menu-header key="logs">Logs</menu-header>
|
<menu-header key="logs">Logs</menu-header>
|
||||||
<menu-link key="logs" selected=input.selected.index icon="L" href="/logs/">All</menu-link>
|
<menu-link key="logs" selected=(input.selected.index && !state.filtered) icon="L" href="/logs/">All</menu-link>
|
||||||
<if-permitted key="if-permitted" user=input.user permission="log.add">
|
<if-permitted key="if-permitted" user=input.user permission="log.add">
|
||||||
<menu-link key="add_log" dark on-click("select", "add") icon="+">Add Log</menu-link>
|
<menu-link key="add_log" dark on-click("select", "log.add") icon="+">Add Log</menu-link>
|
||||||
</if-permitted>
|
</if-permitted>
|
||||||
<menu-gap />
|
<menu-gap />
|
||||||
<menu-header key="filters">Filters</menu-header>
|
<menu-header key="filters">Filters</menu-header>
|
||||||
|
<menu-link for(filter in state.filters) textClass=filter.color unselectable icon=filter.icon on-click("emit", "removefilter", filter.type, filter.id)>${filter.text}</menu-link>
|
||||||
|
<menu-link key="add_filter" dark on-click("select", "filter.add") icon="+">Add Filter</menu-link>
|
||||||
<menu-gap />
|
<menu-gap />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -3,6 +3,7 @@ const {logHeaderApi} = require("../../../../../rpdata/api/LogHeader")
|
|||||||
module.exports = class {
|
module.exports = class {
|
||||||
onCreate(input) {
|
onCreate(input) {
|
||||||
this.state = {
|
this.state = {
|
||||||
|
filter: input.filter,
|
||||||
logs: input.logs,
|
logs: input.logs,
|
||||||
modal: null,
|
modal: null,
|
||||||
}
|
}
|
||||||
@@ -16,8 +17,40 @@ module.exports = class {
|
|||||||
this.state.modal = null
|
this.state.modal = null
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount() {
|
addFilter(type, filter) {
|
||||||
logHeaderApi.list({limit: 0}).then(logs => {
|
if (type === "search") {
|
||||||
|
this.state.filter = Object.assign({}, this.state.filter, {search: filter})
|
||||||
|
} else {
|
||||||
|
this.state.filter = Object.assign({}, this.state.filter, {[type]: (this.state.filter[type] || []).concat(filter)})
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("FILTER:", this.state.filter)
|
||||||
|
|
||||||
|
this.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFilter(type, filter) {
|
||||||
|
console.log(type, filter, this.state.filter)
|
||||||
|
|
||||||
|
if (type === "search") {
|
||||||
|
this.state.filter = Object.assign({}, this.state.filter, {search: null})
|
||||||
|
this.refresh()
|
||||||
|
} else if ((this.state.filter[type] || []).length === 1) {
|
||||||
|
this.state.filter = Object.assign({}, this.state.filter, {[type]: null})
|
||||||
|
this.refresh()
|
||||||
|
} else {
|
||||||
|
const index = (this.state.filter[type] || []).indexOf(filter)
|
||||||
|
if (index !== -1) {
|
||||||
|
this.state.filter = Object.assign({}, this.state.filter, {[type]: this.state.filter[type].splice(0, index).concat(this.state.filter[type].splice(index + 1))},)
|
||||||
|
this.refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh() {
|
||||||
|
console.log("REFRESH", this.state.filter)
|
||||||
|
|
||||||
|
logHeaderApi.list(this.state.filter).then(logs => {
|
||||||
this.state.logs = logs
|
this.state.logs = logs
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<background src="/assets/images/bg.png" opacity=0.25 />
|
<background src="/assets/images/bg.png" opacity=0.25 />
|
||||||
<logs-menu key="menu" on-select("open") selected=(input.selected || {}) user=input.user />
|
<logs-menu key="menu" on-select("open") on-removefilter("removeFilter") selected=(input.selected || {}) user=input.user filter=state.filter characters=input.characters />
|
||||||
<main>
|
<main>
|
||||||
<logs-list logs=state.logs />
|
<logs-list logs=state.logs />
|
||||||
</main>
|
</main>
|
||||||
<add-log-modal enabled=(state.modal === "add") on-close("close") />
|
<add-log-modal enabled=(state.modal === "log.add") on-close("close") />
|
||||||
|
<add-filter-modal enabled=(state.modal === "filter.add") characters=input.characters filter=state.filter on-add("addFilter") on-close("close") />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<include("../layout", {title: "Logs", site: "logs"})>
|
<include("../layout", {title: "Logs", site: "logs"})>
|
||||||
<@body>
|
<@body>
|
||||||
<!-- Page needed to get component.js functionality -->
|
<!-- Page needed to get component.js functionality -->
|
||||||
<page logs=input.logs user=input.user selected=input.selected />
|
<page logs=input.logs filter=input.filter characters=input.characters user=input.user selected=input.selected />
|
||||||
</@body>
|
</@body>
|
||||||
</include>
|
</include>
|
||||||
+20
-2
@@ -1,14 +1,32 @@
|
|||||||
const express = require("express")
|
const express = require("express")
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
const {logHeaderApi} = require("../../rpdata/api/LogHeader")
|
const {logHeaderApi, eventNames} = require("../../rpdata/api/LogHeader")
|
||||||
|
const {charactersApi} = require("../../rpdata/api/Character")
|
||||||
|
|
||||||
const listTemplate = require("../../marko/page/logs/list.marko")
|
const listTemplate = require("../../marko/page/logs/list.marko")
|
||||||
|
|
||||||
router.get("/", async(req, res) => {
|
router.get("/", async(req, res) => {
|
||||||
|
const filter = {limit: 0}
|
||||||
|
|
||||||
|
if (req.query.characters) {
|
||||||
|
filter.characters = req.query.characters.split(",")
|
||||||
|
}
|
||||||
|
if (req.query.channels) {
|
||||||
|
filter.channels = req.query.channels.split(",")
|
||||||
|
}
|
||||||
|
if (req.query.events) {
|
||||||
|
filter.events = req.query.events.split(",")
|
||||||
|
}
|
||||||
|
if (req.query.search) {
|
||||||
|
filter.search = req.query.search
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
res.markoAsync(listTemplate, {
|
res.markoAsync(listTemplate, {
|
||||||
logs: logHeaderApi.list({limit: 0}),
|
filter: filter,
|
||||||
|
logs: logHeaderApi.list(filter),
|
||||||
|
characters: charactersApi.listHeaders(),
|
||||||
selected: {index: true},
|
selected: {index: true},
|
||||||
})
|
})
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
|||||||
+41
-8
@@ -27,21 +27,34 @@ class Character {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CharacterHeader {
|
||||||
|
/**
|
||||||
|
* @param {string} id
|
||||||
|
* @param {string} author
|
||||||
|
* @param {string} name
|
||||||
|
*/
|
||||||
|
constructor(id, author, name) {
|
||||||
|
this.id = id
|
||||||
|
this.author = author
|
||||||
|
this.name = name
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a character object from data.
|
||||||
|
*/
|
||||||
|
static fromData(data) {
|
||||||
|
return new CharacterHeader(data.id, data.author, data.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ChracterAPI {
|
class ChracterAPI {
|
||||||
/**
|
/**
|
||||||
* Call `characters(filter)` query
|
* Call `characters(filter)` query
|
||||||
*
|
*
|
||||||
* @param {{ids:string[], nicks:string[], names:string[], author:string, search:string, logged:boolean}} filter
|
* @param {{ids:string[], nicks:string[], names:string[], author:string, search:string, logged:boolean}} filter
|
||||||
* @returns {Promise<Story[]>}
|
* @returns {Promise<Character[]>}
|
||||||
*/
|
*/
|
||||||
list(filter = {}) {
|
list(filter = {}) {
|
||||||
if (filter.earliestFictionalDate != null && typeof(filter.earliestFictionalDate) !== "string") {
|
|
||||||
filter.earliestFictionalDate = filter.earliestFictionalDate.toISOString()
|
|
||||||
}
|
|
||||||
if (filter.latestFictionalDate != null && typeof(filter.latestFictionalDate) !== "string") {
|
|
||||||
filter.latestFictionalDate = filter.latestFictionalDate.toISOString()
|
|
||||||
}
|
|
||||||
|
|
||||||
return query(`
|
return query(`
|
||||||
query ListCharacters($filter: CharactersFilter) {
|
query ListCharacters($filter: CharactersFilter) {
|
||||||
characters(filter: $filter) {
|
characters(filter: $filter) {
|
||||||
@@ -58,6 +71,26 @@ class ChracterAPI {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call `characters(filter)` query
|
||||||
|
*
|
||||||
|
* @param {{ids:string[], nicks:string[], names:string[], author:string, search:string, logged:boolean}} filter
|
||||||
|
* @returns {Promise<CharacterHeader[]>}
|
||||||
|
*/
|
||||||
|
listHeaders(filter = {}) {
|
||||||
|
return query(`
|
||||||
|
query ListCharacters($filter: CharactersFilter) {
|
||||||
|
characters(filter: $filter) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
author
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, {filter}).then(({characters}) => {
|
||||||
|
return characters.map(d => CharacterHeader.fromData(d))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call `addCharacter(input)` mutation, returns addable fields.
|
* Call `addCharacter(input)` mutation, returns addable fields.
|
||||||
*
|
*
|
||||||
|
|||||||
+36
-3
@@ -1,5 +1,7 @@
|
|||||||
const {query} = require("../client")
|
const {query} = require("../client")
|
||||||
|
|
||||||
|
let eventNames = []
|
||||||
|
|
||||||
class LogHeader {
|
class LogHeader {
|
||||||
/**
|
/**
|
||||||
* Construct a log header. You should probably use the logHeaderApi instead of doing
|
* Construct a log header. You should probably use the logHeaderApi instead of doing
|
||||||
@@ -50,7 +52,38 @@ class LogHeaderCharacter {
|
|||||||
*/
|
*/
|
||||||
const logHeaderApi = {
|
const logHeaderApi = {
|
||||||
/**
|
/**
|
||||||
* Call `stories(filter)` query
|
* Call `logs` query, returns event name
|
||||||
|
*
|
||||||
|
* @returns {Promise<string[]>}
|
||||||
|
*/
|
||||||
|
eventNames() {
|
||||||
|
return query(`
|
||||||
|
query LogHeadersEventNames() {
|
||||||
|
headers: logs(filter:{limit:0}) {
|
||||||
|
eventName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, {}).then(({headers}) => {
|
||||||
|
const eventNames = []
|
||||||
|
const seen = {}
|
||||||
|
|
||||||
|
for (const header of headers) {
|
||||||
|
if (!header.eventName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!seen[header.eventName]) {
|
||||||
|
eventNames.push(header.eventName)
|
||||||
|
seen[header.eventName] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventNames
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call `logs(filter)` query
|
||||||
*
|
*
|
||||||
* @param {{search:string, channels:string|string[], events:string|string[], open:boolean, characters:string|string[], limit:number}} filter
|
* @param {{search:string, channels:string|string[], events:string|string[], open:boolean, characters:string|string[], limit:number}} filter
|
||||||
* @returns {Promise<LogHeader[]>}
|
* @returns {Promise<LogHeader[]>}
|
||||||
@@ -76,9 +109,9 @@ const logHeaderApi = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, {filter}).then(({headers}) => {
|
`, {filter}).then(({headers}) => {
|
||||||
return headers.map(h => new LogHeader(h.id, h.shortId, h.date, h.channelName, h.title, h.description, h.eventName, h.open, h.characters))
|
return headers.map(h => new LogHeader(h.id, h.shortId, h.date, h.channelName, h.title, h.description, h.eventName, h.open, h.characters))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {LogHeader, LogHeaderCharacter, logHeaderApi}
|
module.exports = {LogHeader, LogHeaderCharacter, logHeaderApi, eventNames}
|
||||||
Reference in New Issue
Block a user