mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-15 11:51:59 +01:00
[Debt] NetworkContainer creation
Added a Factory to NetworkContainer class. Users can gain access to NetworkContainers via FetchOperations.
This commit is contained in:
parent
e7b2770295
commit
b56deeb546
@ -8,7 +8,6 @@ import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
|||||||
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
||||||
import com.djrapitops.plan.data.store.mutators.health.NetworkHealthInformation;
|
import com.djrapitops.plan.data.store.mutators.health.NetworkHealthInformation;
|
||||||
import com.djrapitops.plan.system.database.databases.Database;
|
import com.djrapitops.plan.system.database.databases.Database;
|
||||||
import com.djrapitops.plan.system.info.server.Server;
|
|
||||||
import com.djrapitops.plan.system.info.server.properties.ServerProperties;
|
import com.djrapitops.plan.system.info.server.properties.ServerProperties;
|
||||||
import com.djrapitops.plan.system.settings.Settings;
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||||
@ -21,7 +20,11 @@ import com.djrapitops.plan.utilities.html.graphs.stack.StackGraph;
|
|||||||
import com.djrapitops.plan.utilities.html.structure.NetworkServerBox;
|
import com.djrapitops.plan.utilities.html.structure.NetworkServerBox;
|
||||||
import com.djrapitops.plugin.api.Check;
|
import com.djrapitops.plugin.api.Check;
|
||||||
import com.djrapitops.plugin.api.TimeAmount;
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
import dagger.Lazy;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -39,17 +42,32 @@ public class NetworkContainer extends DataContainer {
|
|||||||
|
|
||||||
private final ServerContainer bungeeContainer;
|
private final ServerContainer bungeeContainer;
|
||||||
|
|
||||||
// TODO
|
private final String version;
|
||||||
private String version;
|
private final PlanConfig config;
|
||||||
private PlanConfig config;
|
private final Theme theme;
|
||||||
private Theme theme;
|
private final Database database;
|
||||||
private Database database;
|
private final ServerProperties serverProperties;
|
||||||
private ServerProperties serverProperties;
|
private final Formatters formatters;
|
||||||
private Formatters formatters;
|
private final Graphs graphs;
|
||||||
private Graphs graphs;
|
|
||||||
|
|
||||||
public NetworkContainer(ServerContainer bungeeContainer) {
|
public NetworkContainer(
|
||||||
|
ServerContainer bungeeContainer,
|
||||||
|
String version,
|
||||||
|
PlanConfig config,
|
||||||
|
Theme theme,
|
||||||
|
Database database,
|
||||||
|
ServerProperties serverProperties,
|
||||||
|
Formatters formatters,
|
||||||
|
Graphs graphs
|
||||||
|
) {
|
||||||
this.bungeeContainer = bungeeContainer;
|
this.bungeeContainer = bungeeContainer;
|
||||||
|
this.version = version;
|
||||||
|
this.config = config;
|
||||||
|
this.theme = theme;
|
||||||
|
this.database = database;
|
||||||
|
this.serverProperties = serverProperties;
|
||||||
|
this.formatters = formatters;
|
||||||
|
this.graphs = graphs;
|
||||||
|
|
||||||
putSupplier(NetworkKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(bungeeContainer));
|
putSupplier(NetworkKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(bungeeContainer));
|
||||||
|
|
||||||
@ -66,13 +84,15 @@ public class NetworkContainer extends DataContainer {
|
|||||||
putSupplier(NetworkKeys.SERVERS_TAB, () -> {
|
putSupplier(NetworkKeys.SERVERS_TAB, () -> {
|
||||||
StringBuilder serverBoxes = new StringBuilder();
|
StringBuilder serverBoxes = new StringBuilder();
|
||||||
Map<Integer, List<TPS>> playersOnlineData = getValue(NetworkKeys.NETWORK_PLAYER_ONLINE_DATA).orElse(new HashMap<>());
|
Map<Integer, List<TPS>> playersOnlineData = getValue(NetworkKeys.NETWORK_PLAYER_ONLINE_DATA).orElse(new HashMap<>());
|
||||||
for (Server server : getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>())) {
|
getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>())
|
||||||
TPSMutator tpsMutator = new TPSMutator(playersOnlineData.getOrDefault(server.getId(), new ArrayList<>()));
|
.stream()
|
||||||
|
.sorted((one, two) -> String.CASE_INSENSITIVE_ORDER.compare(one.getName(), two.getName()))
|
||||||
// TODO Add Registered players per server.
|
.forEach(server -> {
|
||||||
NetworkServerBox serverBox = new NetworkServerBox(server, 0, tpsMutator, graphs);
|
TPSMutator tpsMutator = new TPSMutator(playersOnlineData.getOrDefault(server.getId(), new ArrayList<>()));
|
||||||
serverBoxes.append(serverBox.toHtml());
|
// TODO Add Registered players per server.
|
||||||
}
|
NetworkServerBox serverBox = new NetworkServerBox(server, 0, tpsMutator, graphs);
|
||||||
|
serverBoxes.append(serverBox.toHtml());
|
||||||
|
});
|
||||||
return serverBoxes.toString();
|
return serverBoxes.toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -183,4 +203,48 @@ public class NetworkContainer extends DataContainer {
|
|||||||
putSupplier(NetworkKeys.PLAYERS_MONTH, () -> getUnsafe(uniqueMonth).count());
|
putSupplier(NetworkKeys.PLAYERS_MONTH, () -> getUnsafe(uniqueMonth).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class Factory {
|
||||||
|
|
||||||
|
private final Lazy<String> version;
|
||||||
|
private final Lazy<PlanConfig> config;
|
||||||
|
private final Lazy<Theme> theme;
|
||||||
|
private final Lazy<Database> database;
|
||||||
|
private final Lazy<ServerProperties> serverProperties;
|
||||||
|
private final Lazy<Formatters> formatters;
|
||||||
|
private final Lazy<Graphs> graphs;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public Factory(
|
||||||
|
@Named("currentVersion") Lazy<String> version,
|
||||||
|
Lazy<PlanConfig> config,
|
||||||
|
Lazy<Theme> theme,
|
||||||
|
Lazy<Database> database,
|
||||||
|
Lazy<ServerProperties> serverProperties,
|
||||||
|
Lazy<Formatters> formatters,
|
||||||
|
Lazy<Graphs> graphs
|
||||||
|
) {
|
||||||
|
this.version = version;
|
||||||
|
this.config = config;
|
||||||
|
this.theme = theme;
|
||||||
|
this.database = database;
|
||||||
|
this.serverProperties = serverProperties;
|
||||||
|
this.formatters = formatters;
|
||||||
|
this.graphs = graphs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkContainer forBungeeContainer(ServerContainer bungeeContainer) {
|
||||||
|
return new NetworkContainer(
|
||||||
|
bungeeContainer,
|
||||||
|
version.get(),
|
||||||
|
config.get(),
|
||||||
|
theme.get(),
|
||||||
|
database.get(),
|
||||||
|
serverProperties.get(),
|
||||||
|
formatters.get(),
|
||||||
|
graphs.get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package com.djrapitops.plan.system.database.databases.sql;
|
|||||||
|
|
||||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||||
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||||
import com.djrapitops.plan.system.locale.Locale;
|
import com.djrapitops.plan.system.locale.Locale;
|
||||||
import com.djrapitops.plan.system.locale.lang.PluginLang;
|
import com.djrapitops.plan.system.locale.lang.PluginLang;
|
||||||
@ -37,12 +38,13 @@ public class MySQLDB extends SQLDB {
|
|||||||
Locale locale,
|
Locale locale,
|
||||||
PlanConfig config,
|
PlanConfig config,
|
||||||
Lazy<ServerInfo> serverInfo,
|
Lazy<ServerInfo> serverInfo,
|
||||||
|
NetworkContainer.Factory networkContainerFactory,
|
||||||
RunnableFactory runnableFactory,
|
RunnableFactory runnableFactory,
|
||||||
PluginLogger pluginLogger,
|
PluginLogger pluginLogger,
|
||||||
Timings timings,
|
Timings timings,
|
||||||
ErrorHandler errorHandler
|
ErrorHandler errorHandler
|
||||||
) {
|
) {
|
||||||
super(() -> serverInfo.get().getServerUUID(), locale, config, runnableFactory, pluginLogger, timings, errorHandler);
|
super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, pluginLogger, timings, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized void increment() {
|
private static synchronized void increment() {
|
||||||
|
@ -2,6 +2,7 @@ package com.djrapitops.plan.system.database.databases.sql;
|
|||||||
|
|
||||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||||
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
import com.djrapitops.plan.system.database.databases.Database;
|
import com.djrapitops.plan.system.database.databases.Database;
|
||||||
import com.djrapitops.plan.system.database.databases.operation.*;
|
import com.djrapitops.plan.system.database.databases.operation.*;
|
||||||
import com.djrapitops.plan.system.database.databases.sql.operation.*;
|
import com.djrapitops.plan.system.database.databases.sql.operation.*;
|
||||||
@ -46,6 +47,7 @@ public abstract class SQLDB extends Database {
|
|||||||
|
|
||||||
protected final Locale locale;
|
protected final Locale locale;
|
||||||
protected final PlanConfig config;
|
protected final PlanConfig config;
|
||||||
|
protected final NetworkContainer.Factory networkContainerFactory;
|
||||||
protected final RunnableFactory runnableFactory;
|
protected final RunnableFactory runnableFactory;
|
||||||
protected final PluginLogger logger;
|
protected final PluginLogger logger;
|
||||||
protected final Timings timings;
|
protected final Timings timings;
|
||||||
@ -81,7 +83,7 @@ public abstract class SQLDB extends Database {
|
|||||||
Supplier<UUID> serverUUIDSupplier,
|
Supplier<UUID> serverUUIDSupplier,
|
||||||
Locale locale,
|
Locale locale,
|
||||||
PlanConfig config,
|
PlanConfig config,
|
||||||
RunnableFactory runnableFactory,
|
NetworkContainer.Factory networkContainerFactory, RunnableFactory runnableFactory,
|
||||||
PluginLogger logger,
|
PluginLogger logger,
|
||||||
Timings timings,
|
Timings timings,
|
||||||
ErrorHandler errorHandler
|
ErrorHandler errorHandler
|
||||||
@ -89,6 +91,7 @@ public abstract class SQLDB extends Database {
|
|||||||
this.serverUUIDSupplier = serverUUIDSupplier;
|
this.serverUUIDSupplier = serverUUIDSupplier;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.networkContainerFactory = networkContainerFactory;
|
||||||
this.runnableFactory = runnableFactory;
|
this.runnableFactory = runnableFactory;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.timings = timings;
|
this.timings = timings;
|
||||||
@ -471,4 +474,8 @@ public abstract class SQLDB extends Database {
|
|||||||
public Supplier<UUID> getServerUUIDSupplier() {
|
public Supplier<UUID> getServerUUIDSupplier() {
|
||||||
return serverUUIDSupplier;
|
return serverUUIDSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NetworkContainer.Factory getNetworkContainerFactory() {
|
||||||
|
return networkContainerFactory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.djrapitops.plan.system.database.databases.sql;
|
package com.djrapitops.plan.system.database.databases.sql;
|
||||||
|
|
||||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||||
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
import com.djrapitops.plan.system.file.PlanFiles;
|
import com.djrapitops.plan.system.file.PlanFiles;
|
||||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||||
import com.djrapitops.plan.system.locale.Locale;
|
import com.djrapitops.plan.system.locale.Locale;
|
||||||
@ -17,6 +18,7 @@ import com.djrapitops.plugin.task.RunnableFactory;
|
|||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -36,12 +38,13 @@ public class SQLiteDB extends SQLDB {
|
|||||||
Locale locale,
|
Locale locale,
|
||||||
PlanConfig config,
|
PlanConfig config,
|
||||||
Lazy<ServerInfo> serverInfo,
|
Lazy<ServerInfo> serverInfo,
|
||||||
|
NetworkContainer.Factory networkContainerFactory,
|
||||||
RunnableFactory runnableFactory,
|
RunnableFactory runnableFactory,
|
||||||
PluginLogger logger,
|
PluginLogger logger,
|
||||||
Timings timings,
|
Timings timings,
|
||||||
ErrorHandler errorHandler
|
ErrorHandler errorHandler
|
||||||
) {
|
) {
|
||||||
super(() -> serverInfo.get().getServerUUID(), locale, config, runnableFactory, logger, timings, errorHandler);
|
super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, logger, timings, errorHandler);
|
||||||
dbName = databaseFile.getName();
|
dbName = databaseFile.getName();
|
||||||
this.databaseFile = databaseFile;
|
this.databaseFile = databaseFile;
|
||||||
}
|
}
|
||||||
@ -178,11 +181,13 @@ public class SQLiteDB extends SQLDB {
|
|||||||
return Objects.hash(super.hashCode(), dbName);
|
return Objects.hash(super.hashCode(), dbName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
public static class Factory {
|
public static class Factory {
|
||||||
|
|
||||||
private final Locale locale;
|
private final Locale locale;
|
||||||
private final PlanConfig config;
|
private final PlanConfig config;
|
||||||
private final Lazy<ServerInfo> serverInfo;
|
private final Lazy<ServerInfo> serverInfo;
|
||||||
|
private final NetworkContainer.Factory networkContainerFactory;
|
||||||
private final RunnableFactory runnableFactory;
|
private final RunnableFactory runnableFactory;
|
||||||
private final PluginLogger logger;
|
private final PluginLogger logger;
|
||||||
private final Timings timings;
|
private final Timings timings;
|
||||||
@ -195,6 +200,7 @@ public class SQLiteDB extends SQLDB {
|
|||||||
PlanConfig config,
|
PlanConfig config,
|
||||||
PlanFiles files,
|
PlanFiles files,
|
||||||
Lazy<ServerInfo> serverInfo,
|
Lazy<ServerInfo> serverInfo,
|
||||||
|
NetworkContainer.Factory networkContainerFactory,
|
||||||
RunnableFactory runnableFactory,
|
RunnableFactory runnableFactory,
|
||||||
PluginLogger logger,
|
PluginLogger logger,
|
||||||
Timings timings,
|
Timings timings,
|
||||||
@ -204,6 +210,7 @@ public class SQLiteDB extends SQLDB {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
this.files = files;
|
this.files = files;
|
||||||
this.serverInfo = serverInfo;
|
this.serverInfo = serverInfo;
|
||||||
|
this.networkContainerFactory = networkContainerFactory;
|
||||||
this.runnableFactory = runnableFactory;
|
this.runnableFactory = runnableFactory;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.timings = timings;
|
this.timings = timings;
|
||||||
@ -219,7 +226,11 @@ public class SQLiteDB extends SQLDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SQLiteDB usingFile(File databaseFile) {
|
public SQLiteDB usingFile(File databaseFile) {
|
||||||
return new SQLiteDB(databaseFile, locale, config, serverInfo, runnableFactory, logger, timings, errorHandler);
|
return new SQLiteDB(databaseFile,
|
||||||
|
locale, config, serverInfo,
|
||||||
|
networkContainerFactory,
|
||||||
|
runnableFactory, logger, timings, errorHandler
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.djrapitops.plan.system.database.databases.sql;
|
package com.djrapitops.plan.system.database.databases.sql;
|
||||||
|
|
||||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||||
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||||
import com.djrapitops.plan.system.locale.Locale;
|
import com.djrapitops.plan.system.locale.Locale;
|
||||||
import com.djrapitops.plan.system.settings.Settings;
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
@ -30,12 +31,13 @@ public class SpongeMySQLDB extends MySQLDB {
|
|||||||
Locale locale,
|
Locale locale,
|
||||||
PlanConfig config,
|
PlanConfig config,
|
||||||
Lazy<ServerInfo> serverInfo,
|
Lazy<ServerInfo> serverInfo,
|
||||||
|
NetworkContainer.Factory networkContainerFactory,
|
||||||
RunnableFactory runnableFactory,
|
RunnableFactory runnableFactory,
|
||||||
PluginLogger pluginLogger,
|
PluginLogger pluginLogger,
|
||||||
Timings timings,
|
Timings timings,
|
||||||
ErrorHandler errorHandler
|
ErrorHandler errorHandler
|
||||||
) {
|
) {
|
||||||
super(locale, config, serverInfo, runnableFactory, pluginLogger, timings, errorHandler);
|
super(locale, config, serverInfo, networkContainerFactory, runnableFactory, pluginLogger, timings, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,7 +24,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkContainer getNetworkContainer() {
|
public NetworkContainer getNetworkContainer() {
|
||||||
NetworkContainer networkContainer = new NetworkContainer(getBungeeServerContainer());
|
NetworkContainer networkContainer = db.getNetworkContainerFactory().forBungeeContainer(getBungeeServerContainer());
|
||||||
networkContainer.putSupplier(NetworkKeys.BUKKIT_SERVERS, () -> getBukkitServers().values());
|
networkContainer.putSupplier(NetworkKeys.BUKKIT_SERVERS, () -> getBukkitServers().values());
|
||||||
return networkContainer;
|
return networkContainer;
|
||||||
}
|
}
|
||||||
|
@ -304,9 +304,8 @@ public class TPSTable extends Table {
|
|||||||
public Map<Integer, List<TPS>> getPlayersOnlineForServers(Collection<Server> servers) {
|
public Map<Integer, List<TPS>> getPlayersOnlineForServers(Collection<Server> servers) {
|
||||||
WhereParser sqlParser = Select.from(tableName, Col.SERVER_ID, Col.DATE, Col.PLAYERS_ONLINE)
|
WhereParser sqlParser = Select.from(tableName, Col.SERVER_ID, Col.DATE, Col.PLAYERS_ONLINE)
|
||||||
.where(Col.DATE.get() + ">" + (System.currentTimeMillis() - TimeAmount.WEEK.toMillis(2L)));
|
.where(Col.DATE.get() + ">" + (System.currentTimeMillis() - TimeAmount.WEEK.toMillis(2L)));
|
||||||
String statementSelectServerID = serverTable.statementSelectServerID;
|
|
||||||
for (Server server : servers) {
|
for (Server server : servers) {
|
||||||
sqlParser.or(Col.SERVER_ID + "=" + statementSelectServerID.replace("?", server.getUuid().toString()));
|
sqlParser.or(Col.SERVER_ID + "=" + server.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
String sql = sqlParser.toString();
|
String sql = sqlParser.toString();
|
||||||
|
@ -72,9 +72,11 @@ public class NetworkServerBox {
|
|||||||
"<span class=\"pull-right\">" + onlineCount + " / " + maxCount + "</span></p>" +
|
"<span class=\"pull-right\">" + onlineCount + " / " + maxCount + "</span></p>" +
|
||||||
"</div>" +
|
"</div>" +
|
||||||
"<div class=\"col-md-4\">" +
|
"<div class=\"col-md-4\">" +
|
||||||
"<p><i class=\"far fa-chart-pie \"></i> Analysis Cached" +
|
"<p><i class=\"fa fa-chart-pie \"></i> Analysis Cached" +
|
||||||
"<span class=\"pull-right\"><b>" + cached + "</b></span></p>" +
|
"<span class=\"pull-right\"><b>" + cached + "</b></span></p>" +
|
||||||
"<a href=\"" + address + "\"><button href=\"" + address + "\" type=\"button\" class=\"pull-right btn bg-light-green waves-effect\">" +
|
"<a href=\"" + address + "\"><button href=\"" + address + "\" type=\"button\" class=\"pull-right btn bg-" +
|
||||||
|
(isCached ? "light-green" : "grey") +
|
||||||
|
" waves-effect\">" +
|
||||||
"<i class=\"material-icons\">trending_up</i>" +
|
"<i class=\"material-icons\">trending_up</i>" +
|
||||||
"<span>ANALYSIS</span>" +
|
"<span>ANALYSIS</span>" +
|
||||||
"</button></a></div></div></div></div></div></div>" +
|
"</button></a></div></div></div></div></div></div>" +
|
||||||
|
Loading…
Reference in New Issue
Block a user