diff --git a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/dnn-bi-log-pagination.scss b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/dnn-bi-log-pagination.scss
new file mode 100644
index 00000000000..2d94d545015
--- /dev/null
+++ b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/dnn-bi-log-pagination.scss
@@ -0,0 +1,26 @@
+:host {
+ .pagination {
+ display: flex;
+ margin: 0;
+ padding: 1em;
+ gap: 1em;
+ li {
+ flex: 0 0 fit-content;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ button {
+ border: 1px solid transparent;
+ background: none;
+ }
+ &.ellipsis {
+ color: var(--dnn-color-neutral, #ededee);
+ }
+ &.active {
+ button {
+ border-bottom-color: var(--dnn-color-neutral, #ededee);
+ }
+ }
+ }
+ }
+}
diff --git a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/dnn-bi-log-pagination.tsx b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/dnn-bi-log-pagination.tsx
new file mode 100644
index 00000000000..1de97cb947f
--- /dev/null
+++ b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/dnn-bi-log-pagination.tsx
@@ -0,0 +1,85 @@
+import { Component, Host, h, Prop, Event, EventEmitter, Fragment } from '@stencil/core';
+import { Pagination } from '../../../../clients/event-log-client';
+
+type PageItem = { type: 'page'; index: number; isCurrent: boolean } | { type: 'ellipsis' };
+
+const ellipsisItem: PageItem = { type: 'ellipsis' };
+function toPageItem(index: number, current: number): PageItem {
+ return {
+ type: 'page',
+ index: index,
+ isCurrent: index === current,
+ };
+}
+
+function* makePagesIterator(current: number, lastIndex: number) {
+ const start = Math.max(current - 5, 0);
+ const end = Math.min(start + 10, lastIndex);
+ if (start !== 0) {
+ yield toPageItem(0, current);
+ if (start === 2) {
+ yield toPageItem(1, current);
+ } else if (start !== 1) {
+ yield ellipsisItem;
+ }
+ }
+
+ for (let i = start; i <= end; i++) {
+ yield toPageItem(i, current);
+ }
+
+ if (end !== lastIndex) {
+ if (end === lastIndex - 2) {
+ yield toPageItem(lastIndex - 1, current);
+ } else if (end !== lastIndex - 1) {
+ yield ellipsisItem;
+ }
+
+ yield toPageItem(lastIndex, current);
+ }
+}
+
+@Component({
+ tag: 'dnn-bi-log-pagination',
+ styleUrl: 'dnn-bi-log-pagination.scss',
+ shadow: true,
+})
+export class DnnBiLogPagination {
+ /** The pagination */
+ @Prop() public pagination!: Pagination;
+
+ @Event() public pageSelected: EventEmitter
;
+
+ private getPages(): PageItem[] {
+ return Array.from(makePagesIterator(this.pagination.currentPage, this.pagination.pages - 1));
+ }
+
+ render() {
+ return (
+
+ {this.pagination.pages > 1 && (
+
+ )}
+
+ );
+ }
+}
diff --git a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/readme.md b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/readme.md
new file mode 100644
index 00000000000..9b55a8b2fb3
--- /dev/null
+++ b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-log-pagination/readme.md
@@ -0,0 +1,37 @@
+# dnn-bi-log-pagination
+
+
+
+
+
+
+## Properties
+
+| Property | Attribute | Description | Type | Default |
+| ------------------------- | --------- | -------------- | ------------ | ----------- |
+| `pagination` _(required)_ | -- | The pagination | `Pagination` | `undefined` |
+
+
+## Events
+
+| Event | Description | Type |
+| -------------- | ----------- | --------------------- |
+| `pageSelected` | | `CustomEvent` |
+
+
+## Dependencies
+
+### Used by
+
+ - [dnn-bi-logs](..)
+
+### Graph
+```mermaid
+graph TD;
+ dnn-bi-logs --> dnn-bi-log-pagination
+ style dnn-bi-log-pagination fill:#f9f,stroke:#333,stroke-width:4px
+```
+
+----------------------------------------------
+
+*Built with [StencilJS](https://stenciljs.com/)*
diff --git a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.scss b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.scss
index 0fe9917e27c..aa9c2608411 100644
--- a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.scss
+++ b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.scss
@@ -57,6 +57,12 @@
width: fit-content;
}
+ .filters {
+ display: flex;
+ justify-content: end;
+ gap: 1em;
+ }
+
/* Table styling */
.table {
width: 100%;
@@ -74,11 +80,4 @@
background-color: var(--dnn-color-neutral-dark, #999999);
color: var(--dnn-color-neutral, #ededee);
}
-
- /* Utility */
- .clearfix::after {
- content: '';
- display: table;
- clear: both;
- }
}
diff --git a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.tsx b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.tsx
index 63cbe732175..85b13cbddf3 100644
--- a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.tsx
+++ b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/dnn-bi-logs.tsx
@@ -1,7 +1,8 @@
-import { Component, Host, h } from '@stencil/core';
+import { Component, Host, h, State } from '@stencil/core';
+import store from '../../../stores/store';
+import { EventLogClient, Pagination } from '../../../clients/event-log-client';
import { Event } from './dnn-bi-logs.model';
-import state from '../../../stores/store';
-import { EventLogClient } from '../../../clients/event-log-client';
+import { eventLogSeverity, EventLogSeverityInfo } from '../../../enums/EventLogSeverity';
@Component({
tag: 'dnn-bi-logs',
@@ -9,26 +10,48 @@ import { EventLogClient } from '../../../clients/event-log-client';
shadow: true,
})
export class DnnBiLogs {
- private events: Event[] = [];
+ @State() private events: Event[] = [];
+ @State() private eventTypes: string[] = [];
+ @State() private pagination: Pagination;
+ @State() private severityFilter: EventLogSeverityInfo;
+ @State() private eventTypeFilter: string;
private eventLogClient: EventLogClient;
constructor() {
- this.eventLogClient = new EventLogClient(state.moduleId);
+ this.eventLogClient = new EventLogClient(store.moduleId);
}
async componentWillLoad() {
try {
- const browseResponse = await this.eventLogClient.browse();
- this.events = browseResponse.Data;
+ const { data, pagination } = await this.eventLogClient.browse();
+ this.events = data;
+ this.pagination = pagination;
+ this.eventTypes = await this.eventLogClient.getEventTypes();
} catch (error) {
console.error(error);
}
}
- private static formatDate(event: Event): string {
+ private async setSeverityFilter(key: string) {
+ this.severityFilter = eventLogSeverity.fromKey(key);
+ await this.loadPage(0);
+ }
+
+ private async setEventTypeFilter(eventType: string) {
+ this.eventTypeFilter = eventType;
+ await this.loadPage(0);
+ }
+
+ private async loadPage(pageIndex: number) {
+ const { data, pagination } = await this.eventLogClient.browse(pageIndex, this.severityFilter, this.eventTypeFilter);
+ this.events = data;
+ this.pagination = pagination;
+ }
+
+ private static formatDate(date: Date): string {
const formatter = new Intl.DateTimeFormat(undefined, { dateStyle: 'long', timeStyle: 'medium' });
- return formatter.format(event.date);
+ return formatter.format(date);
}
render() {
@@ -38,22 +61,39 @@ export class DnnBiLogs {
-
{state.resx.Events}
+ {store.resx.Events}
+
+ this.setSeverityFilter(e.detail).catch(console.error)}>
+
+
+
+
+
+
+ this.setEventTypeFilter(e.detail).catch(console.error)}>
+
+ {this.eventTypes.map(eventType => (
+
+ ))}
+
+
- | {state.resx.Date} |
- {state.resx.Severity} |
- {state.resx.Type} |
- {state.resx.Message} |
+ {store.resx.Date} |
+ {store.resx.Severity} |
+ {store.resx.Type} |
+ {store.resx.Message} |
{this.events.map(event => (
- | {DnnBiLogs.formatDate(event)} |
+
+
+ |
{event.severity.localizedName} |
{event.type} |
{event.message} |
@@ -61,6 +101,7 @@ export class DnnBiLogs {
))}
+
this.loadPage(e.detail).catch(console.error)} />
diff --git a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/readme.md b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/readme.md
index 78ef6100d15..deed93bf1d8 100644
--- a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/readme.md
+++ b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/components/tabs/dnn-bi-logs/readme.md
@@ -9,9 +9,17 @@
- [dnn-bulk-install](../../dnn-bulk-install)
+### Depends on
+
+- dnn-select
+- [dnn-bi-log-pagination](dnn-bi-log-pagination)
+
### Graph
```mermaid
graph TD;
+ dnn-bi-logs --> dnn-select
+ dnn-bi-logs --> dnn-bi-log-pagination
+ dnn-select --> dnn-fieldset
dnn-bulk-install --> dnn-bi-logs
style dnn-bi-logs fill:#f9f,stroke:#333,stroke-width:4px
```
diff --git a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/enums/EventLogSeverity.ts b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/enums/EventLogSeverity.ts
index 526b7203345..acd49e37fd4 100644
--- a/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/enums/EventLogSeverity.ts
+++ b/DNN Platform/Modules/BulkInstall/BulkInstall.Web/src/enums/EventLogSeverity.ts
@@ -12,6 +12,21 @@ export class EventLogSeverity {
this.alert = new EventLogSeverityInfo('Alert');
this.critical = new EventLogSeverityInfo('Critical');
}
+
+ public fromKey(eventLogSeverityKey: string) {
+ switch (eventLogSeverityKey) {
+ case this.info.eventLogSeverityKey:
+ return this.info;
+ case this.warning.eventLogSeverityKey:
+ return this.warning;
+ case this.alert.eventLogSeverityKey:
+ return this.alert;
+ case this.critical.eventLogSeverityKey:
+ return this.critical;
+ default:
+ throw new Error(`Invalid EventLogSeverity key: ${eventLogSeverityKey}`);
+ }
+ }
}
export class EventLogSeverityInfo {
diff --git a/DNN Platform/Modules/BulkInstall/Components/WebAPI/EventLogController.cs b/DNN Platform/Modules/BulkInstall/Components/WebAPI/EventLogController.cs
index aa1c8514922..dbc4f2b81fa 100644
--- a/DNN Platform/Modules/BulkInstall/Components/WebAPI/EventLogController.cs
+++ b/DNN Platform/Modules/BulkInstall/Components/WebAPI/EventLogController.cs
@@ -29,77 +29,19 @@ public class EventLogController(EventLogManager eventLogManager) : DnnApiControl
/// The 0-based page index.
/// The page size.
/// An event type to filter by, or .
- /// A to filter by, or -1.
+ /// A to filter by, or .
/// A response with a list of and pagination data.
[HttpGet]
- public HttpResponseMessage Browse(int pageIndex = 0, int pageSize = 30, string eventType = null, int severity = -1)
+ public HttpResponseMessage Browse(int pageIndex = 0, int pageSize = 30, string eventType = null, EventLogSeverity? severity = null)
{
- EventLogSeverity? actualSeverity = null;
-
- // Is there a severity set?
- if (severity >= 0)
- {
- actualSeverity = (EventLogSeverity)severity;
- }
-
// Get event logs.
- IEnumerable eventLogs = this.eventLogManager.Browse(pageIndex, pageSize, eventType, actualSeverity);
+ IEnumerable eventLogs = this.eventLogManager.Browse(pageIndex, pageSize, eventType, severity);
// Work out pagination details.
- int rowCount = this.eventLogManager.BrowseCount(pageIndex, pageSize, eventType, actualSeverity);
+ int rowCount = this.eventLogManager.BrowseCount(pageIndex, pageSize, eventType, severity);
int pageCount = (int)Math.Ceiling(rowCount / (double)pageSize);
- // Build navigation.
- Dictionary navigation = new Dictionary();
-
- // Parameters passed in not changed by pagination.
- string fixedParams = string.Empty;
-
- // Page size.
- if (pageSize != 30)
- {
- fixedParams += $"pageSize={pageSize}";
- }
-
- // Event type.
- if (eventType != null)
- {
- fixedParams += $"eventType={eventType}";
- }
-
- // Severity.
- if (severity != -1)
- {
- fixedParams += $"eventType={severity}";
- }
-
- // Is there a next page?
- if (pageIndex < pageCount)
- {
- string nextLink = $"Browse?pageIndex={pageIndex + 1}";
-
- if (!string.IsNullOrEmpty(fixedParams))
- {
- nextLink = $"{nextLink}&{fixedParams}";
- }
-
- navigation.Add("Next", nextLink);
- }
-
- // Is there a previous page?
- if (pageIndex > 0)
- {
- string prevLink = $"Browse?pageIndex={pageIndex - 1}";
-
- if (!string.IsNullOrEmpty(fixedParams))
- {
- prevLink = $"{prevLink}&{fixedParams}";
- }
-
- navigation.Add("Previous", prevLink);
- }
-
- var pagination = new { Records = rowCount, Pages = pageCount, CurrentPage = pageIndex, Navigation = navigation, };
+ var pagination = new { Pages = pageCount, CurrentPage = pageIndex, };
return this.Request.CreateResponse(HttpStatusCode.OK, new { Data = eventLogs, Pagination = pagination, });
}