mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-03-10 13:49:17 +01:00
Enabled React server page in Frontend BETA
Various fixes to React frontend - Implemented Extension DataTables table support - Fixed colors in night mode - Fixed DataTables night mode - Fixed chart opacity in night mode (HighCharts doesn't like hsl values) - Fixed color selector buttons in night mode - Translated Login button - Added license to package.json - Changed Extension endpoint table representation to objects to allow value formatting
This commit is contained in:
parent
c824994cb9
commit
4c53a9a406
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Player Analytics (Plan).
|
||||||
|
*
|
||||||
|
* Plan is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Plan is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.djrapitops.plan.delivery.domain.datatransfer.extension;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author AuroraLS3
|
||||||
|
*/
|
||||||
|
public class TableCellDto {
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
@Nullable
|
||||||
|
private final Object valueUnformatted;
|
||||||
|
|
||||||
|
public TableCellDto(String value) {
|
||||||
|
this.value = value;
|
||||||
|
this.valueUnformatted = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableCellDto(String value, @Nullable Object valueUnformatted) {
|
||||||
|
this.value = value;
|
||||||
|
this.valueUnformatted = valueUnformatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Object getValueUnformatted() {
|
||||||
|
return valueUnformatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
TableCellDto that = (TableCellDto) o;
|
||||||
|
return Objects.equals(getValue(), that.getValue()) && Objects.equals(getValueUnformatted(), that.getValueUnformatted());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(getValue(), getValueUnformatted());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TableCellDto{" +
|
||||||
|
"value='" + value + '\'' +
|
||||||
|
", valueUnformatted=" + valueUnformatted +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,7 @@ public class TableDto {
|
|||||||
private final List<String> columns;
|
private final List<String> columns;
|
||||||
private final List<IconDto> icons;
|
private final List<IconDto> icons;
|
||||||
|
|
||||||
private final List<List<Object>> rows;
|
private final List<List<TableCellDto>> rows;
|
||||||
|
|
||||||
public TableDto(Table table) {
|
public TableDto(Table table) {
|
||||||
columns = Arrays.stream(table.getColumns())
|
columns = Arrays.stream(table.getColumns())
|
||||||
@ -46,17 +46,17 @@ public class TableDto {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Object> constructRow(List<String> columns, Object[] row) {
|
private List<TableCellDto> constructRow(List<String> columns, TableCellDto[] row) {
|
||||||
List<Object> constructedRow = new ArrayList<>();
|
List<TableCellDto> constructedRow = new ArrayList<>();
|
||||||
|
|
||||||
int headerLength = row.length - 1;
|
int headerLength = row.length - 1;
|
||||||
int columnCount = columns.size();
|
int columnCount = columns.size();
|
||||||
for (int i = 0; i < columnCount; i++) {
|
for (int i = 0; i < columnCount; i++) {
|
||||||
if (i > headerLength) {
|
if (i > headerLength) {
|
||||||
constructedRow.add("-");
|
constructedRow.add(new TableCellDto("-"));
|
||||||
} else {
|
} else {
|
||||||
Object value = row[i];
|
TableCellDto cell = row[i];
|
||||||
constructedRow.add(value != null ? value : '-');
|
constructedRow.add(cell != null ? cell : new TableCellDto("-"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return constructedRow;
|
return constructedRow;
|
||||||
@ -70,7 +70,7 @@ public class TableDto {
|
|||||||
return icons;
|
return icons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<List<Object>> getRows() {
|
public List<List<TableCellDto>> getRows() {
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import java.text.ParseException;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class DynamicHtmlTable implements HtmlTable {
|
public class DynamicHtmlTable implements HtmlTable {
|
||||||
private final Header[] headers;
|
private final Header[] headers;
|
||||||
private final List<Object[]> rows;
|
private final List<Object[]> rows;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.delivery.rendering.html.structure;
|
package com.djrapitops.plan.delivery.rendering.html.structure;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.delivery.domain.datatransfer.extension.TableCellDto;
|
||||||
import com.djrapitops.plan.delivery.formatting.Formatters;
|
import com.djrapitops.plan.delivery.formatting.Formatters;
|
||||||
import com.djrapitops.plan.delivery.rendering.html.Html;
|
import com.djrapitops.plan.delivery.rendering.html.Html;
|
||||||
import com.djrapitops.plan.delivery.rendering.html.icon.Color;
|
import com.djrapitops.plan.delivery.rendering.html.icon.Color;
|
||||||
@ -25,8 +26,10 @@ import com.djrapitops.plan.extension.table.TableColumnFormat;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public interface HtmlTable {
|
public interface HtmlTable {
|
||||||
|
|
||||||
static HtmlTable fromExtensionTable(Table table, com.djrapitops.plan.extension.icon.Color tableColor) {
|
static HtmlTable fromExtensionTable(Table table, com.djrapitops.plan.extension.icon.Color tableColor) {
|
||||||
@ -57,25 +60,25 @@ public interface HtmlTable {
|
|||||||
return headers.toArray(new Header[0]);
|
return headers.toArray(new Header[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Object[]> mapToRows(List<Object[]> rows, TableColumnFormat[] tableColumnFormats) {
|
static List<TableCellDto[]> mapToRows(List<Object[]> rows, TableColumnFormat[] tableColumnFormats) {
|
||||||
return rows.stream()
|
return rows.stream()
|
||||||
.map(row -> {
|
.map(row -> {
|
||||||
List<Object> mapped = new ArrayList<>(row.length);
|
List<TableCellDto> mapped = new ArrayList<>(row.length);
|
||||||
for (int i = 0; i < row.length; i++) {
|
for (int i = 0; i < row.length; i++) {
|
||||||
Object value = row[i];
|
Object value = row[i];
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
mapped.add(null);
|
mapped.add(null);
|
||||||
} else {
|
} else {
|
||||||
TableColumnFormat format = tableColumnFormats[i];
|
TableColumnFormat format = tableColumnFormats[i];
|
||||||
mapped.add(applyFormat(format, value));
|
mapped.add(new TableCellDto(applyFormat(format, value), value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mapped.toArray();
|
return mapped.toArray(new TableCellDto[0]);
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object applyFormat(TableColumnFormat format, Object value) {
|
static String applyFormat(TableColumnFormat format, Object value) {
|
||||||
try {
|
try {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case TIME_MILLISECONDS:
|
case TIME_MILLISECONDS:
|
||||||
@ -90,7 +93,7 @@ public interface HtmlTable {
|
|||||||
return Html.swapColorCodesToSpan(value.toString());
|
return Html.swapColorCodesToSpan(value.toString());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return value;
|
return Objects.toString(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,17 +16,19 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.delivery.rendering.html.structure;
|
package com.djrapitops.plan.delivery.rendering.html.structure;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.delivery.domain.datatransfer.extension.TableCellDto;
|
||||||
import com.djrapitops.plan.delivery.rendering.html.icon.Color;
|
import com.djrapitops.plan.delivery.rendering.html.icon.Color;
|
||||||
import com.djrapitops.plan.extension.table.Table;
|
import com.djrapitops.plan.extension.table.Table;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class HtmlTableWithColoredHeader implements HtmlTable {
|
public class HtmlTableWithColoredHeader implements HtmlTable {
|
||||||
private final Header[] headers;
|
private final Header[] headers;
|
||||||
private final Color headerColor;
|
private final Color headerColor;
|
||||||
private final List<Object[]> rows;
|
private final List<TableCellDto[]> rows;
|
||||||
|
|
||||||
public HtmlTableWithColoredHeader(Header[] headers, Color headerColor, List<Object[]> rows) {
|
public HtmlTableWithColoredHeader(Header[] headers, Color headerColor, List<TableCellDto[]> rows) {
|
||||||
this.headers = headers;
|
this.headers = headers;
|
||||||
this.headerColor = headerColor;
|
this.headerColor = headerColor;
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
@ -63,15 +65,15 @@ public class HtmlTableWithColoredHeader implements HtmlTable {
|
|||||||
StringBuilder builtBody = new StringBuilder();
|
StringBuilder builtBody = new StringBuilder();
|
||||||
builtBody.append("<tbody>");
|
builtBody.append("<tbody>");
|
||||||
if (rows.isEmpty()) {
|
if (rows.isEmpty()) {
|
||||||
appendRow(builtBody, "No Data");
|
appendRow(builtBody, new TableCellDto("No Data"));
|
||||||
}
|
}
|
||||||
for (Object[] row : rows) {
|
for (TableCellDto[] row : rows) {
|
||||||
appendRow(builtBody, row);
|
appendRow(builtBody, row);
|
||||||
}
|
}
|
||||||
return builtBody.append("</tbody>").toString();
|
return builtBody.append("</tbody>").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendRow(StringBuilder builtBody, Object... row) {
|
private void appendRow(StringBuilder builtBody, TableCellDto... row) {
|
||||||
int headerLength = row.length - 1;
|
int headerLength = row.length - 1;
|
||||||
builtBody.append("<tr>");
|
builtBody.append("<tr>");
|
||||||
for (int i = 0; i < headers.length; i++) {
|
for (int i = 0; i < headers.length; i++) {
|
||||||
@ -80,8 +82,8 @@ public class HtmlTableWithColoredHeader implements HtmlTable {
|
|||||||
builtBody.append("<td>-");
|
builtBody.append("<td>-");
|
||||||
} else {
|
} else {
|
||||||
builtBody.append("<td>");
|
builtBody.append("<td>");
|
||||||
Object value = row[i];
|
TableCellDto cell = row[i];
|
||||||
builtBody.append(value != null ? value : '-');
|
builtBody.append(cell != null ? cell.getValue() : '-');
|
||||||
}
|
}
|
||||||
builtBody.append("</td>");
|
builtBody.append("</td>");
|
||||||
} catch (ClassCastException | ArrayIndexOutOfBoundsException e) {
|
} catch (ClassCastException | ArrayIndexOutOfBoundsException e) {
|
||||||
|
@ -107,6 +107,12 @@ public class PageFactory {
|
|||||||
public Page serverPage(ServerUUID serverUUID) throws IOException {
|
public Page serverPage(ServerUUID serverUUID) throws IOException {
|
||||||
Server server = dbSystem.get().getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverUUID))
|
Server server = dbSystem.get().getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverUUID))
|
||||||
.orElseThrow(() -> new NotFoundException("Server not found in the database"));
|
.orElseThrow(() -> new NotFoundException("Server not found in the database"));
|
||||||
|
|
||||||
|
if (config.get().isTrue(PluginSettings.FRONTEND_BETA)) {
|
||||||
|
String reactHtml = getResource("index.html");
|
||||||
|
return () -> reactHtml;
|
||||||
|
}
|
||||||
|
|
||||||
return new ServerPage(
|
return new ServerPage(
|
||||||
getResource("server.html"),
|
getResource("server.html"),
|
||||||
server,
|
server,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"license": "LGPL-3.0-or-later",
|
||||||
"name": "dashboard",
|
"name": "dashboard",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -9,6 +9,7 @@ import KillsTable from "../table/KillsTable";
|
|||||||
import Accordion from "./Accordion";
|
import Accordion from "./Accordion";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {baseAddress} from "../../service/backendConfiguration";
|
import {baseAddress} from "../../service/backendConfiguration";
|
||||||
|
import {ChartLoader} from "../navigation/Loader";
|
||||||
|
|
||||||
const SessionHeader = ({session}) => {
|
const SessionHeader = ({session}) => {
|
||||||
return (
|
return (
|
||||||
@ -88,7 +89,7 @@ const SessionAccordion = (
|
|||||||
) => {
|
) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
||||||
|
|
||||||
if (!sessions) return <></>
|
if (!sessions) return <ChartLoader/>
|
||||||
|
|
||||||
const firstColumn = isPlayer ? (<><Fa icon={faUser}/> {t('html.label.player')}</>)
|
const firstColumn = isPlayer ? (<><Fa icon={faUser}/> {t('html.label.player')}</>)
|
||||||
: (<><Fa icon={faServer}/> {t('html.label.server')}</>)
|
: (<><Fa icon={faServer}/> {t('html.label.server')}</>)
|
||||||
|
@ -3,8 +3,7 @@ import {Card, Col} from "react-bootstrap-v5";
|
|||||||
import ExtensionIcon from "./ExtensionIcon";
|
import ExtensionIcon from "./ExtensionIcon";
|
||||||
import Datapoint from "../Datapoint";
|
import Datapoint from "../Datapoint";
|
||||||
import Masonry from 'masonry-layout'
|
import Masonry from 'masonry-layout'
|
||||||
import {useTheme} from "../../hooks/themeHook";
|
import ExtensionTable from "./ExtensionTable";
|
||||||
import {useTranslation} from "react-i18next";
|
|
||||||
|
|
||||||
export const ExtensionCardWrapper = ({extension, children}) => {
|
export const ExtensionCardWrapper = ({extension, children}) => {
|
||||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||||
@ -65,32 +64,6 @@ const ExtensionValues = ({tab}) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExtensionTable = ({table}) => {
|
|
||||||
const {nightModeEnabled} = useTheme();
|
|
||||||
const {t} = useTranslation();
|
|
||||||
|
|
||||||
const columns = table.table.rows.length ? table.table.rows.map((row, i) => <tr key={i}>{row.map((value, j) => <td
|
|
||||||
key={i + '' + j}>{value}</td>)}</tr>) :
|
|
||||||
<tr>{table.table.columns.map((column, i) =>
|
|
||||||
<td key={i}>{i === 0 ? t('generic.noData') : '-'}</td>)}
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
return (
|
|
||||||
<table className={"table table-striped" + (nightModeEnabled ? " table-dark" : '')}>
|
|
||||||
<thead className={table.tableColorClass}>
|
|
||||||
<tr>
|
|
||||||
{table.table.columns.map((column, i) => <th key={i}><ExtensionIcon
|
|
||||||
icon={table.table.icons[i]}/> {column}
|
|
||||||
</th>)}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{columns}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ExtensionTables = ({tab}) => {
|
const ExtensionTables = ({tab}) => {
|
||||||
return (<>
|
return (<>
|
||||||
{tab.tableData.map((table, i) => (
|
{tab.tableData.map((table, i) => (
|
||||||
|
@ -11,4 +11,8 @@ const ExtensionIcon = ({icon}) => (
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const toExtensionIconHtmlString = ({icon}) => {
|
||||||
|
return icon ? `<i class="${iconTypeToFontAwesomeClass(icon.family)} ${icon.iconName} ${icon.colorClass}"></i>` : '';
|
||||||
|
}
|
||||||
|
|
||||||
export default ExtensionIcon;
|
export default ExtensionIcon;
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
import React, {useState} from 'react';
|
||||||
|
import {useTheme} from "../../hooks/themeHook";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
import ExtensionIcon, {toExtensionIconHtmlString} from "./ExtensionIcon";
|
||||||
|
import DataTablesTable from "../table/DataTablesTable";
|
||||||
|
|
||||||
|
const ExtensionDataTable = ({table}) => {
|
||||||
|
const [id] = useState("extension-table-" + new Date().getTime() + "-" + (Math.floor(Math.random() * 100000)));
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
columns: table.table.columns.map((column, i) => {
|
||||||
|
return {
|
||||||
|
title: toExtensionIconHtmlString(table.table.icons[i]) + ' ' + column,
|
||||||
|
data: {
|
||||||
|
"_": `col${i}.v`,
|
||||||
|
display: `col${i}.d`
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
data: table.table.rows.map((row) => {
|
||||||
|
const dataRow = {};
|
||||||
|
row.forEach((cell, j) => dataRow[`col${j}`] = {
|
||||||
|
v: cell['valueUnformatted'] || cell.value || cell,
|
||||||
|
d: cell.value || cell
|
||||||
|
});
|
||||||
|
return dataRow;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
const options = {
|
||||||
|
responsive: true,
|
||||||
|
deferRender: true,
|
||||||
|
columns: data.columns,
|
||||||
|
data: data.data,
|
||||||
|
order: [[1, "desc"]]
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<DataTablesTable id={id} options={options}/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ExtensionColoredTable = ({table}) => {
|
||||||
|
const {nightModeEnabled} = useTheme();
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
|
const rows = table.table.rows.length ? table.table.rows.map((row, i) => <tr key={i}>{row.map((value, j) => <td
|
||||||
|
key={i + '' + j}>{value.value || String(value)}</td>)}</tr>) :
|
||||||
|
<tr>{table.table.columns.map((column, i) =>
|
||||||
|
<td key={i}>{i === 0 ? t('generic.noData') : '-'}</td>)}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<table className={"table table-striped" + (nightModeEnabled ? " table-dark" : '')}>
|
||||||
|
<thead className={table.tableColorClass}>
|
||||||
|
<tr>
|
||||||
|
{table.table.columns.map((column, i) => <th key={i}><ExtensionIcon
|
||||||
|
icon={table.table.icons[i]}/> {column}
|
||||||
|
</th>)}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{rows}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ExtensionTable = ({table}) => {
|
||||||
|
const tableLength = table.table.rows.length;
|
||||||
|
|
||||||
|
if (tableLength > 25) {
|
||||||
|
return <ExtensionDataTable table={table}/>
|
||||||
|
} else {
|
||||||
|
return <ExtensionColoredTable table={table}/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtensionTable
|
@ -8,7 +8,7 @@ import {useTranslation} from "react-i18next";
|
|||||||
|
|
||||||
const LineGraph = ({id, series}) => {
|
const LineGraph = ({id, series}) => {
|
||||||
const {t} = useTranslation()
|
const {t} = useTranslation()
|
||||||
const {graphTheming} = useTheme();
|
const {graphTheming, nightModeEnabled} = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
NoDataDisplay(Highcharts);
|
NoDataDisplay(Highcharts);
|
||||||
@ -27,12 +27,12 @@ const LineGraph = ({id, series}) => {
|
|||||||
title: {text: ''},
|
title: {text: ''},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
areaspline: {
|
areaspline: {
|
||||||
fillOpacity: 0.4
|
fillOpacity: nightModeEnabled ? 0.2 : 0.4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
series: series
|
series: series
|
||||||
})
|
})
|
||||||
}, [series, graphTheming, id, t])
|
}, [series, graphTheming, id, t, nightModeEnabled])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="chart-area" id={id}>
|
<div className="chart-area" id={id}>
|
||||||
|
@ -2,10 +2,13 @@ import React, {useEffect, useState} from "react";
|
|||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {tooltip} from "../../util/graphs";
|
import {tooltip} from "../../util/graphs";
|
||||||
import LineGraph from "./LineGraph";
|
import LineGraph from "./LineGraph";
|
||||||
|
import {useTheme} from "../../hooks/themeHook";
|
||||||
|
import {withReducedSaturation} from "../../util/colors";
|
||||||
|
|
||||||
const PlayerPingGraph = ({data}) => {
|
const PlayerPingGraph = ({data}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
||||||
const [series, setSeries] = useState([]);
|
const [series, setSeries] = useState([]);
|
||||||
|
const {nightModeEnabled} = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const avgPingSeries = {
|
const avgPingSeries = {
|
||||||
@ -13,23 +16,23 @@ const PlayerPingGraph = ({data}) => {
|
|||||||
type: 'spline',
|
type: 'spline',
|
||||||
tooltip: tooltip.twoDecimals,
|
tooltip: tooltip.twoDecimals,
|
||||||
data: data.avg_ping_series,
|
data: data.avg_ping_series,
|
||||||
color: data.colors.avg
|
color: nightModeEnabled ? withReducedSaturation(data.colors.avg) : data.colors.avg
|
||||||
}
|
}
|
||||||
const maxPingSeries = {
|
const maxPingSeries = {
|
||||||
name: t('html.label.worstPing'),
|
name: t('html.label.worstPing'),
|
||||||
type: 'spline',
|
type: 'spline',
|
||||||
tooltip: tooltip.twoDecimals,
|
tooltip: tooltip.twoDecimals,
|
||||||
data: data.max_ping_series,
|
data: data.max_ping_series,
|
||||||
color: data.colors.max
|
color: nightModeEnabled ? withReducedSaturation(data.colors.max) : data.colors.max
|
||||||
}
|
}
|
||||||
const minPingSeries = {
|
const minPingSeries = {
|
||||||
name: t('html.label.bestPing'),
|
name: t('html.label.bestPing'),
|
||||||
type: 'spline',
|
type: 'spline',
|
||||||
tooltip: tooltip.twoDecimals,
|
tooltip: tooltip.twoDecimals,
|
||||||
data: data.min_ping_series,
|
data: data.min_ping_series,
|
||||||
color: data.colors.min
|
color: nightModeEnabled ? withReducedSaturation(data.colors.min) : data.colors.min
|
||||||
}
|
}
|
||||||
setSeries([avgPingSeries, maxPingSeries, minPingSeries]);
|
setSeries([avgPingSeries, maxPingSeries, minPingSeries, nightModeEnabled]);
|
||||||
}, [data, t])
|
}, [data, t])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -3,14 +3,15 @@ import Highcharts from 'highcharts';
|
|||||||
import {useTheme} from "../../hooks/themeHook";
|
import {useTheme} from "../../hooks/themeHook";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import Accessibility from "highcharts/modules/accessibility";
|
import Accessibility from "highcharts/modules/accessibility";
|
||||||
|
import {withReducedSaturation} from "../../util/colors";
|
||||||
|
|
||||||
const PunchCard = ({series}) => {
|
const PunchCard = ({series}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
||||||
const {graphTheming} = useTheme();
|
const {graphTheming, nightModeEnabled} = useTheme();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const punchCard = {
|
const punchCard = {
|
||||||
name: t('html.label.relativeJoinActivity'),
|
name: t('html.label.relativeJoinActivity'),
|
||||||
color: '#222',
|
color: nightModeEnabled ? withReducedSaturation('#222') : '#222',
|
||||||
data: series
|
data: series
|
||||||
};
|
};
|
||||||
Accessibility(Highcharts);
|
Accessibility(Highcharts);
|
||||||
@ -46,7 +47,7 @@ const PunchCard = ({series}) => {
|
|||||||
},
|
},
|
||||||
series: [punchCard]
|
series: [punchCard]
|
||||||
}), 25)
|
}), 25)
|
||||||
}, [series, graphTheming, t])
|
}, [series, graphTheming, t, nightModeEnabled])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="chart-area" id="punchcard">
|
<div className="chart-area" id="punchcard">
|
||||||
|
@ -2,10 +2,13 @@ import {useTranslation} from "react-i18next";
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import {tooltip} from "../../util/graphs";
|
import {tooltip} from "../../util/graphs";
|
||||||
import LineGraph from "./LineGraph";
|
import LineGraph from "./LineGraph";
|
||||||
|
import {useTheme} from "../../hooks/themeHook";
|
||||||
|
import {withReducedSaturation} from "../../util/colors";
|
||||||
|
|
||||||
const TimeByTimeGraph = ({data}) => {
|
const TimeByTimeGraph = ({data}) => {
|
||||||
const {t} = useTranslation();
|
const {t} = useTranslation();
|
||||||
const [series, setSeries] = useState([]);
|
const [series, setSeries] = useState([]);
|
||||||
|
const {nightModeEnabled} = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const uniquePlayers = {
|
const uniquePlayers = {
|
||||||
@ -13,16 +16,16 @@ const TimeByTimeGraph = ({data}) => {
|
|||||||
type: 'spline',
|
type: 'spline',
|
||||||
tooltip: tooltip.zeroDecimals,
|
tooltip: tooltip.zeroDecimals,
|
||||||
data: data.uniquePlayers,
|
data: data.uniquePlayers,
|
||||||
color: data.colors.playersOnline
|
color: nightModeEnabled ? withReducedSaturation(data.colors.playersOnline) : data.colors.playersOnline
|
||||||
};
|
};
|
||||||
const newPlayers = {
|
const newPlayers = {
|
||||||
name: t('html.label.newPlayers'),
|
name: t('html.label.newPlayers'),
|
||||||
type: 'spline',
|
type: 'spline',
|
||||||
tooltip: tooltip.zeroDecimals,
|
tooltip: tooltip.zeroDecimals,
|
||||||
data: data.newPlayers,
|
data: data.newPlayers,
|
||||||
color: data.colors.newPlayers
|
color: nightModeEnabled ? withReducedSaturation(data.colors.newPlayers) : data.colors.newPlayers
|
||||||
};
|
};
|
||||||
setSeries([uniquePlayers, newPlayers]);
|
setSeries([uniquePlayers, newPlayers, nightModeEnabled]);
|
||||||
}, [data, t])
|
}, [data, t])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -110,7 +110,7 @@ const AllPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
type: 'areaspline',
|
type: 'areaspline',
|
||||||
tooltip: tooltip.zeroDecimals,
|
tooltip: tooltip.zeroDecimals,
|
||||||
data: dataSeries.playersOnline,
|
data: dataSeries.playersOnline,
|
||||||
color: nightModeEnabled ? withReducedSaturation(data.colors.playersOnline) : data.colors.playersOnline,
|
color: data.colors.playersOnline,
|
||||||
yAxis: 0
|
yAxis: 0
|
||||||
}, tps: {
|
}, tps: {
|
||||||
name: t('html.label.tps'),
|
name: t('html.label.tps'),
|
||||||
@ -164,7 +164,7 @@ const AllPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
title: {text: ''},
|
title: {text: ''},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
areaspline: {
|
areaspline: {
|
||||||
fillOpacity: 0.4
|
fillOpacity: nightModeEnabled ? 0.2 : 0.4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
|
@ -21,7 +21,7 @@ const CpuRamPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
type: 'areaspline',
|
type: 'areaspline',
|
||||||
tooltip: tooltip.zeroDecimals,
|
tooltip: tooltip.zeroDecimals,
|
||||||
data: dataSeries.playersOnline,
|
data: dataSeries.playersOnline,
|
||||||
color: nightModeEnabled ? withReducedSaturation(data.colors.playersOnline) : data.colors.playersOnline,
|
color: data.colors.playersOnline,
|
||||||
yAxis: 0
|
yAxis: 0
|
||||||
}, cpu: {
|
}, cpu: {
|
||||||
name: t('html.label.cpu'),
|
name: t('html.label.cpu'),
|
||||||
@ -76,7 +76,7 @@ const CpuRamPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
title: {text: ''},
|
title: {text: ''},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
areaspline: {
|
areaspline: {
|
||||||
fillOpacity: 0.4
|
fillOpacity: nightModeEnabled ? 0.2 : 0.4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
|
@ -16,13 +16,13 @@ const DiskPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
const zones = {
|
const zones = {
|
||||||
disk: [{
|
disk: [{
|
||||||
value: data.zones.diskThresholdMed,
|
value: data.zones.diskThresholdMed,
|
||||||
color: nightModeEnabled ? withReducedSaturation(data.colors.low) : data.colors.low
|
color: data.colors.low
|
||||||
}, {
|
}, {
|
||||||
value: data.zones.diskThresholdHigh,
|
value: data.zones.diskThresholdHigh,
|
||||||
color: nightModeEnabled ? withReducedSaturation(data.colors.med) : data.colors.med
|
color: data.colors.med
|
||||||
}, {
|
}, {
|
||||||
value: Number.MAX_VALUE,
|
value: Number.MAX_VALUE,
|
||||||
color: nightModeEnabled ? withReducedSaturation(data.colors.high) : data.colors.high
|
color: data.colors.high
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ const DiskPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
title: {text: ''},
|
title: {text: ''},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
areaspline: {
|
areaspline: {
|
||||||
fillOpacity: 0.4
|
fillOpacity: nightModeEnabled ? 0.2 : 0.4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
|
@ -33,7 +33,7 @@ const TpsPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
type: 'areaspline',
|
type: 'areaspline',
|
||||||
tooltip: tooltip.zeroDecimals,
|
tooltip: tooltip.zeroDecimals,
|
||||||
data: dataSeries.playersOnline,
|
data: dataSeries.playersOnline,
|
||||||
color: nightModeEnabled ? withReducedSaturation(data.colors.playersOnline) : data.colors.playersOnline,
|
color: data.colors.playersOnline,
|
||||||
yAxis: 0
|
yAxis: 0
|
||||||
}, tps: {
|
}, tps: {
|
||||||
name: t('html.label.tps'),
|
name: t('html.label.tps'),
|
||||||
@ -73,7 +73,7 @@ const TpsPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
title: {text: ''},
|
title: {text: ''},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
areaspline: {
|
areaspline: {
|
||||||
fillOpacity: 0.4
|
fillOpacity: nightModeEnabled ? 0.2 : 0.4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
|
@ -21,7 +21,7 @@ const WorldPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
type: 'areaspline',
|
type: 'areaspline',
|
||||||
tooltip: tooltip.zeroDecimals,
|
tooltip: tooltip.zeroDecimals,
|
||||||
data: dataSeries.playersOnline,
|
data: dataSeries.playersOnline,
|
||||||
color: nightModeEnabled ? withReducedSaturation(data.colors.playersOnline) : data.colors.playersOnline,
|
color: data.colors.playersOnline,
|
||||||
yAxis: 0
|
yAxis: 0
|
||||||
}, entities: {
|
}, entities: {
|
||||||
name: t('html.label.loadedEntities'),
|
name: t('html.label.loadedEntities'),
|
||||||
@ -75,7 +75,7 @@ const WorldPerformanceGraph = ({id, data, dataSeries}) => {
|
|||||||
title: {text: ''},
|
title: {text: ''},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
areaspline: {
|
areaspline: {
|
||||||
fillOpacity: 0.4
|
fillOpacity: nightModeEnabled ? 0.2 : 0.4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
|
@ -7,7 +7,7 @@ import {Modal} from "react-bootstrap-v5";
|
|||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
|
|
||||||
const ColorSelectorButton = ({color, setColor, disabled}) =>
|
const ColorSelectorButton = ({color, setColor, disabled}) =>
|
||||||
<button className={"btn color-chooser " + colorEnumToBgClass(color)}
|
<button className={"btn color-chooser " + colorEnumToBgClass(color) + (disabled ? " disabled" : '')}
|
||||||
id={"choose-" + color}
|
id={"choose-" + color}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={() => setColor(color)}
|
onClick={() => setColor(color)}
|
||||||
|
@ -4,9 +4,11 @@ import 'datatables.net-bs5'
|
|||||||
import 'datatables.net-responsive-bs5'
|
import 'datatables.net-responsive-bs5'
|
||||||
import 'datatables.net-bs5/css/dataTables.bootstrap5.min.css';
|
import 'datatables.net-bs5/css/dataTables.bootstrap5.min.css';
|
||||||
import 'datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css';
|
import 'datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css';
|
||||||
|
import {useTheme} from "../../hooks/themeHook";
|
||||||
|
|
||||||
const DataTablesTable = ({id, options}) => {
|
const DataTablesTable = ({id, options}) => {
|
||||||
const dataTableRef = useRef(null);
|
const dataTableRef = useRef(null);
|
||||||
|
const {nightModeEnabled} = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const idSelector = `#${id}`;
|
const idSelector = `#${id}`;
|
||||||
@ -24,7 +26,8 @@ const DataTablesTable = ({id, options}) => {
|
|||||||
}, [id, options, dataTableRef]);
|
}, [id, options, dataTableRef]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table id={id} className="table table-bordered table-striped" style={{width: "100%"}}/>
|
<table id={id} className={"table table-bordered table-striped" + (nightModeEnabled ? " table-dark" : '')}
|
||||||
|
style={{width: "100%"}}/>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ div.scrollbar {
|
|||||||
.color-chooser {
|
.color-chooser {
|
||||||
margin-right: 0.15rem;
|
margin-right: 0.15rem;
|
||||||
margin-bottom: 0.2rem;
|
margin-bottom: 0.2rem;
|
||||||
|
border-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Navbar ====================================== */
|
/* Navbar ====================================== */
|
||||||
@ -767,111 +768,133 @@ div#navSrvContainer::-webkit-scrollbar-thumb {
|
|||||||
|
|
||||||
.bg-red, body.theme-red .fc-toolbar-chunk .btn.btn-primary {
|
.bg-red, body.theme-red .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #F44336;
|
background-color: #F44336;
|
||||||
|
--bs-btn-disabled-bg: #F44336;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-pink, body.theme-pink .fc-toolbar-chunk .btn.btn-primary {
|
.bg-pink, body.theme-pink .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #E91E63;
|
background-color: #E91E63;
|
||||||
|
--bs-btn-disabled-bg: #E91E63;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-purple, body.theme-purple .fc-toolbar-chunk .btn.btn-primary {
|
.bg-purple, body.theme-purple .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #9C27B0;
|
background-color: #9C27B0;
|
||||||
|
--bs-btn-disabled-bg: #9C27B0;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-deep-purple, body.theme-deep-purple .fc-toolbar-chunk .btn.btn-primary {
|
.bg-deep-purple, body.theme-deep-purple .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #673AB7;
|
background-color: #673AB7;
|
||||||
|
--bs-btn-disabled-bg: #673AB7;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-indigo, body.theme-indigo .fc-toolbar-chunk .btn.btn-primary {
|
.bg-indigo, body.theme-indigo .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #3F51B5;
|
background-color: #3F51B5;
|
||||||
|
--bs-btn-disabled-bg: #3F51B5;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-blue, body.theme-blue .fc-toolbar-chunk .btn.btn-primary {
|
.bg-blue, body.theme-blue .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #2196F3;
|
background-color: #2196F3;
|
||||||
|
--bs-btn-disabled-bg: #2196F3;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-light-blue, body.theme-light-blue .fc-toolbar-chunk .btn.btn-primary {
|
.bg-light-blue, body.theme-light-blue .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #03A9F4;
|
background-color: #03A9F4;
|
||||||
|
--bs-btn-disabled-bg: #03A9F4;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-cyan, body.theme-cyan .fc-toolbar-chunk .btn.btn-primary {
|
.bg-cyan, body.theme-cyan .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #00BCD4;
|
background-color: #00BCD4;
|
||||||
|
--bs-btn-disabled-bg: #00BCD4;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-teal, body.theme-teal .fc-toolbar-chunk .btn.btn-primary {
|
.bg-teal, body.theme-teal .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #009688;
|
background-color: #009688;
|
||||||
|
--bs-btn-disabled-bg: #009688;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-green, body.theme-green .fc-toolbar-chunk .btn.btn-primary {
|
.bg-green, body.theme-green .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #4CAF50;
|
background-color: #4CAF50;
|
||||||
|
--bs-btn-disabled-bg: #4CAF50;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-light-green, body.theme-light-green .fc-toolbar-chunk .btn.btn-primary {
|
.bg-light-green, body.theme-light-green .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #8BC34A;
|
background-color: #8BC34A;
|
||||||
|
--bs-btn-disabled-bg: #8BC34A;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-lime, body.theme-lime .fc-toolbar-chunk .btn.btn-primary {
|
.bg-lime, body.theme-lime .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #CDDC39;
|
background-color: #CDDC39;
|
||||||
|
--bs-btn-disabled-bg: #CDDC39;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-yellow, body.theme-yellow .fc-toolbar-chunk .btn.btn-primary {
|
.bg-yellow, body.theme-yellow .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #ffe821;
|
background-color: #ffe821;
|
||||||
|
--bs-btn-disabled-bg: #ffe821;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-amber, body.theme-amber .fc-toolbar-chunk .btn.btn-primary {
|
.bg-amber, body.theme-amber .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #FFC107;
|
background-color: #FFC107;
|
||||||
|
--bs-btn-disabled-bg: #FFC107;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-orange, body.theme-orange .fc-toolbar-chunk .btn.btn-primary {
|
.bg-orange, body.theme-orange .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #FF9800;
|
background-color: #FF9800;
|
||||||
|
--bs-btn-disabled-bg: #FF9800;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-deep-orange, body.theme-deep-orange .fc-toolbar-chunk .btn.btn-primary {
|
.bg-deep-orange, body.theme-deep-orange .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #FF5722;
|
background-color: #FF5722;
|
||||||
|
--bs-btn-disabled-bg: #FF5722;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-brown, body.theme-brown .fc-toolbar-chunk .btn.btn-primary {
|
.bg-brown, body.theme-brown .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #795548;
|
background-color: #795548;
|
||||||
|
--bs-btn-disabled-bg: #795548;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-grey, body.theme-grey .fc-toolbar-chunk .btn.btn-primary {
|
.bg-grey, body.theme-grey .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #9E9E9E;
|
background-color: #9E9E9E;
|
||||||
|
--bs-btn-disabled-bg: #9E9E9E;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-blue-grey, body.theme-blue-grey .fc-toolbar-chunk .btn.btn-primary {
|
.bg-blue-grey, body.theme-blue-grey .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #607D8B;
|
background-color: #607D8B;
|
||||||
|
--bs-btn-disabled-bg: #607D8B;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-black, body.theme-black .fc-toolbar-chunk .btn.btn-primary {
|
.bg-black, body.theme-black .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #555555;
|
background-color: #555555;
|
||||||
|
--bs-btn-disabled-bg: #555555;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-white, body.theme-white .fc-toolbar-chunk .btn.btn-primary {
|
.bg-white, body.theme-white .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
--bs-btn-disabled-bg: #ffffff;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-plan, body.theme-plan .fc-toolbar-chunk .btn.btn-primary {
|
.bg-plan, body.theme-plan .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #368F17;
|
background-color: #368F17;
|
||||||
|
--bs-btn-disabled-bg: #368F17;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,6 +925,7 @@ div#navSrvContainer::-webkit-scrollbar-thumb {
|
|||||||
|
|
||||||
.bg-night, body.theme-night .fc-toolbar-chunk .btn.btn-primary {
|
.bg-night, body.theme-night .fc-toolbar-chunk .btn.btn-primary {
|
||||||
background-color: #44475a;
|
background-color: #44475a;
|
||||||
|
--bs-btn-disabled-bg: #44475a;
|
||||||
color: #eee8d5;
|
color: #eee8d5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ const createNightModeColorCss = () => {
|
|||||||
return `.bg-${color.name}{background-color: ${desaturatedColor} !important;color: ${nightColors.yellow};}` +
|
return `.bg-${color.name}{background-color: ${desaturatedColor} !important;color: ${nightColors.yellow};}` +
|
||||||
`.bg-${color.name}-outline{outline-color: ${desaturatedColor};border-color: ${desaturatedColor};}` +
|
`.bg-${color.name}-outline{outline-color: ${desaturatedColor};border-color: ${desaturatedColor};}` +
|
||||||
`.col-${color.name}{color: ${desaturatedColor} !important;}`
|
`.col-${color.name}{color: ${desaturatedColor} !important;}`
|
||||||
}).join();
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createNightModeCss = () => {
|
export const createNightModeCss = () => {
|
||||||
|
@ -66,7 +66,7 @@ const LoginForm = ({login}) => {
|
|||||||
value={password} onChange={event => setPassword(event.target.value)}/>
|
value={password} onChange={event => setPassword(event.target.value)}/>
|
||||||
</div>
|
</div>
|
||||||
<button className="btn bg-plan btn-user w-100" id="login-button" onClick={onLogin}>
|
<button className="btn bg-plan btn-user w-100" id="login-button" onClick={onLogin}>
|
||||||
Login
|
{t('html.login.login')}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user