client-app/app/controllers/index.js in logster-2.15.0 vs client-app/app/controllers/index.js in logster-2.16.0

- old
+ new

@@ -11,10 +11,12 @@ import { tracked } from "@glimmer/tracking"; @classic export default class IndexController extends Controller { @tracked loading = false; + @tracked buildingGroupingPattern = false; + @tracked rowMessagesForGroupingPattern = []; showDebug = getLocalStorage("showDebug", false); showInfo = getLocalStorage("showInfo", false); showWarn = getLocalStorage("showWarn", true); showErr = getLocalStorage("showErr", true); @@ -31,10 +33,17 @@ return ( /mobile/i.test(navigator.userAgent) && !/iPad/.test(navigator.userAgent) ); } + get showCreateGroupingPattern() { + return ( + this.buildingGroupingPattern && + this.rowMessagesForGroupingPattern.length > 1 + ); + } + @computed("search") get searchTerm() { if (this.search) { this.doSearch(this.search); return this.search; @@ -66,10 +75,23 @@ selectRowAction(row, opts = {}) { this.model.selectRow(row, opts); } @action + handleCheckboxChange(row, event) { + if (event.target.checked) { + this.rowMessagesForGroupingPattern = [ + ...this.rowMessagesForGroupingPattern, + row.message, + ]; + } else { + this.rowMessagesForGroupingPattern = + this.rowMessagesForGroupingPattern.filter((i) => i !== row.message); + } + } + + @action tabChangedAction(newTab) { this.model.tabChanged(newTab); } @action @@ -85,11 +107,10 @@ @action async clear() { // eslint-disable-next-line no-alert if (confirm("Clear the logs?\n\nCancel = No, OK = Clear")) { await ajax("/clear", { type: "POST" }); - this.loading = true; this.model.reload(); this.loading = false; } } @@ -168,7 +189,66 @@ if (term && term.length === 1) { return; } debounce(this, this.doSearch, term, 250); + } + + @action + toggleGroupingPatternFromSelectedRows() { + this.buildingGroupingPattern = !this.buildingGroupingPattern; + this.rowMessagesForGroupingPattern = []; + } + + @action + async createGroupingPatternFromSelectedRows() { + let match = this.findLongestMatchingPrefix( + this.rowMessagesForGroupingPattern + ); + match = this.escapeRegExp(match); + + if ( + match.trim().length && + // eslint-disable-next-line no-alert + confirm( + `Do you want to create the grouping pattern\n\n"${match}"\n\nCancel = No, OK = Create` + ) + ) { + await ajax("/patterns/grouping.json", { + method: "POST", + data: { + pattern: match, + }, + }); + this.rowMessagesForGroupingPattern = []; + this.buildingGroupingPattern = false; + this.model.reload(); + } else if (!match.trim().length) { + // eslint-disable-next-line no-alert + alert("Can not create a grouping pattern with the given rows"); + } + } + + findLongestMatchingPrefix(strings) { + const shortestString = strings.reduce( + (shortest, str) => (str.length < shortest.length ? str : shortest), + strings[0] + ); + + let longestMatchingSubstring = ""; + for (let i = 0; i < shortestString.length; i++) { + const currentSubstring = shortestString.substring(0, i + 1); + + if (strings.every((str) => str.includes(currentSubstring))) { + longestMatchingSubstring = currentSubstring; + } else { + break; + } + } + + return longestMatchingSubstring; + } + + escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string } }