isundil 2 сар өмнө
parent
commit
a28f68b5a4

+ 3 - 2
front/templates/menu.ts

@@ -8,13 +8,14 @@ class Menu {
     private filteredHostname: string[] =[];
     private filterUpdatedHandlers: (()=>void)[] = [];
 
-    public init(): Promise<void> {
+    public async init(): Promise<void> {
         if (this.initialized)
             return Promise.resolve();
         (document.getElementById("navbar-hostfilter")!).addEventListener("change", evt => {
             this.checkFilters(evt.target as HTMLSelectElement);
         });
-        return this.reload();
+        await this.reload();
+        this.initialized = true;
     }
 
     public addFilterEventListener(handler: ()=>void) {

+ 1 - 1
front/templates/page.ts

@@ -36,7 +36,7 @@ export abstract class Page {
         if (templateManager.currentSection === this)
             return Promise.resolve();
         this.showWithoutHistory();
-        await menu.show();
+        await menu.init();
         history.pushState("", "", `#${this.pageName}`)
         return this.load();
     }

+ 33 - 30
front/templates/servicesComponent.tsx

@@ -1,6 +1,7 @@
-import React, { Component } from "react";
+import React, { Component, RefObject } from "react";
 import * as ReactDom from "react-dom/client";
-import DataTable from 'datatables.net-react';
+import { Api as DTApiType } from 'datatables.net';
+import DataTable, {DataTableRef} from 'datatables.net-react';
 import {HostnameServiceDescription, Service} from "../../src/models/service";
 import menu from "./menu";
 
@@ -10,48 +11,50 @@ interface SingleServiceProp {
     status: string;
 }
 
-interface SystemServiceState {
-    loading: boolean;
-}
-
 interface SystemServiceProps {
     data: SingleServiceProp[];
 }
 
-export class SystemServiceComponent extends Component<SystemServiceProps, SystemServiceState> {
+export class SystemServiceComponent extends Component<SystemServiceProps> {
+    private dtRef: RefObject<DataTableRef|null>;
+
     public constructor(props: SystemServiceProps) {
         super(props);
 
-        this.state = {
-            loading: false,
-        };
+        this.dtRef = React.createRef<DataTableRef>();
         menu.addFilterEventListener(() => {
-            this.refreshFilter();
+            this.onMenuFilter();
         });
     }
 
-    private refreshFilter() {
-        // FIXME
-        /*
-        const hidden = this.isFiltered();
-        if (hidden === this.state.hidden)
-            return;
-        this.setState({...this.state, hidden: hidden});
-        */
+    private getDatatableApi(): DTApiType|null {
+        return this.dtRef?.current?.dt() ?? null;
+    }
+
+    private onMenuFilter() {
+        const dtApi = this.getDatatableApi();
+        const values = menu.getFilteredHostnames().join("|");
+        if (!dtApi) return;
+        dtApi.search("");
+        dtApi.column(0).search(values, { regex: true }).draw();
+    }
+
+    public componentDidMount() {
+        this.onMenuFilter();
     }
 
     public render(): React.JSX.Element {
-        if (this.state.loading)
-            return (<>Loading..</>);
-        else if (this.props.data === null)
+        if (this.props.data === null)
             return (<>Error</>);
-        return (<>
+        let defaultSearch = menu.getFilteredHostnames().join("|");
+        return (
             <DataTable options={{
                     layout: { topEnd: null },
-                    columnDefs: [
-                        { target: 0, columnControl: { target: 0, content: [ "order", [ "searchList" ] ] } },
-                        { target: 1, columnControl: { target: 0, content: [ "order", [ "search" ] ] } },
-                        { target: 2, columnControl: { target: 0, content: [ "order", [ "searchList" ] ] } }
+                    search: { search: defaultSearch, regex: true },
+                    columns: [
+                        { columnControl: { target: 0, content: [ "order" ] } },
+                        { columnControl: { target: 0, content: [ "order", [ "search" ] ] } },
+                        { columnControl: { target: 0, content: [ "order", [ "searchList" ] ] } }
                     ],
                     pageLength: 20,
                     lengthMenu: [10, 20, 50, 100, -1],
@@ -59,21 +62,21 @@ export class SystemServiceComponent extends Component<SystemServiceProps, System
                         indicators: false,
                         handler: false
                     }
-                }} data={this.props.data.map(x => [ x.hostname, x.serviceName, x.status ])}>
+                }} ref={this.dtRef} data={this.props.data.map(x => [ x.hostname, x.serviceName, x.status ])}>
                 <thead><tr>
                     <th>Host</th>
                     <th>Service Name</th>
                     <th>Status</th>
                 </tr></thead>
             </DataTable>
-            </>);
+            );
     }
 
     public static renderMultiple(container: HTMLElement, data: HostnameServiceDescription): void {
         const dataArray: SingleServiceProp[] = Object.keys(data).reduce((acc: SingleServiceProp[], hostname: string): SingleServiceProp[] => {
             return acc.concat(data[hostname]!.map((x: Service) : SingleServiceProp => { return { hostname: hostname, serviceName: x.name, status: x.statusText }}));
         }, []);
-        ReactDom.createRoot(container).render(<SystemServiceComponent data={dataArray}/>);
+        ReactDom.createRoot(container).render(<SystemServiceComponent data={dataArray} />);
     }
 }
 

+ 1 - 1
src/index.ts

@@ -64,7 +64,7 @@ import {UnauthorizedMasterApiKey} from "./models/unauthorizedApi";
         app.use("/js/front.js.map", express.static(path.join(__dirname, "../build/"), {index: 'front.js.map'}));
         app.use("/js/front.min.js.map", express.static(path.join(__dirname, "../build/"), {index: 'front.min.js.map'}));
         app.use("/css/bootstrap.min.css", express.static(path.join(__dirname, "../node_modules/bootstrap/dist/css"), {index: 'bootstrap.min.css'}));
-        app.use("/css/datatables.net-bs.min.css", express.static(path.join(__dirname, "../node_modules/datatables.net-bs/css"), {index: 'dataTables.bootstrap.min.css'}));
+        app.use("/css/datatables.net-bs.min.css", express.static(path.join(__dirname, "../node_modules/datatables.net-bs4/css"), {index: 'dataTables.bootstrap4.min.css'}));
         app.use("/css/columnControl.datatables.net-bs.min.css", express.static(path.join(__dirname, "../node_modules/datatables.net-columncontrol-bs4/css"), {index: 'columnControl.bootstrap4.min.css'}));
         app.use("/css/bootstrap-select.min.css", express.static(path.join(__dirname, "../node_modules/bootstrap-select/dist/css"), {index: 'bootstrap-select.min.css'}));
         app.use(express.static(path.join(__dirname, '../public')));