mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-26 16:46:12 +01:00 
			
		
		
		
	feat: upgrade chartjs to 4.x
This commit is contained in:
		| @@ -45,7 +45,7 @@ | ||||
|         "bootstrap": "5.3.2", | ||||
|         "bootswatch": "5.3.2", | ||||
|         "chalk": "4.1.2", | ||||
|         "chart.js": "2.9.4", | ||||
|         "chart.js": "4.4.0", | ||||
|         "cli-graph": "3.2.2", | ||||
|         "clipboard": "2.0.11", | ||||
|         "colors": "1.4.0", | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| .dashboard { | ||||
| 	max-width: 1680px; | ||||
|  | ||||
| 	.card { | ||||
| 		max-width: 100% !important; | ||||
| 	} | ||||
| @@ -9,114 +7,70 @@ | ||||
| 		position: relative; | ||||
| 		background: var(--bg-body-bg); | ||||
|  | ||||
| 		&.pie-chart { | ||||
| 			max-height: 180px; | ||||
| 		} | ||||
|  | ||||
| 		&.fullscreen { | ||||
| 			width: 100%; | ||||
| 			padding: 40px; | ||||
|  | ||||
| 			.graph-legend { | ||||
| 				top: 7rem; | ||||
| 				left: 12rem; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 		&.pie-chart { | ||||
| 			padding-right: 0px; | ||||
| 			padding-left: 50px; | ||||
| 			min-height: 180px; | ||||
| 	.graph-legend { | ||||
| 		@include box-header-font; | ||||
| 		margin: 0; | ||||
|  | ||||
| 			.graph-legend { | ||||
| 				top: -10px; | ||||
| 				left: 0px; | ||||
| 		li { | ||||
| 			display: flex; | ||||
| 			word-wrap: break-word; | ||||
| 			word-break: break-word; | ||||
| 			gap: 0.5rem; | ||||
| 			span { | ||||
| 				flex: 1; | ||||
| 			} | ||||
| 			div { | ||||
| 				border: 1px solid; | ||||
| 				margin-top: 2px; | ||||
| 				width: 12px; | ||||
| 				min-width: 12px; | ||||
| 				height: 12px; | ||||
|  | ||||
| 			&.compact { | ||||
| 				padding-left: 0px; | ||||
| 				padding-top: 60px; | ||||
| 			} | ||||
|  | ||||
| 			&.legend-down { | ||||
| 				padding-left: 0px; | ||||
| 				padding-top: 0px; | ||||
|  | ||||
| 				canvas { | ||||
| 					margin-bottom: 25px; | ||||
| 				&.page-views { | ||||
| 					border-color: rgba(220,220,220,1); | ||||
| 					background-color: rgba(220,220,220,0.2); | ||||
| 				} | ||||
|  | ||||
| 				.graph-legend { | ||||
| 					position: relative; | ||||
|  | ||||
| 					li { | ||||
| 						float: left; | ||||
| 						width: 100%; | ||||
| 						white-space: nowrap; | ||||
| 						overflow: hidden; | ||||
| 						text-overflow: ellipsis; | ||||
|  | ||||
| 						&:nth-child(odd) { | ||||
| 							margin-right: 2%; | ||||
| 						} | ||||
| 					} | ||||
| 				&.unique-visitors { | ||||
| 					border-color: rgba(151,187,205,1); | ||||
| 					background-color: rgba(151,187,205,0.2); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		.graph-legend { | ||||
| 			@include box-header-font; | ||||
| 			display: inline-block; | ||||
| 			max-width: 100%; | ||||
| 			position: absolute; | ||||
| 			top: 2rem; | ||||
| 			left: 7rem; | ||||
| 			list-style-type: none; | ||||
| 			padding: 0.5rem 1rem; | ||||
| 			margin: 0; | ||||
|  | ||||
| 			li { | ||||
| 				div { | ||||
| 					border: 1px solid; | ||||
| 					width: 12px; | ||||
| 					height: 12px; | ||||
| 					vertical-align: -41%; | ||||
| 					margin-bottom: 5px; | ||||
| 					display: inline-block; | ||||
| 					margin-right: 5px; | ||||
|  | ||||
| 					&.page-views { | ||||
| 						border-color: rgba(220,220,220,1); | ||||
| 						background-color: rgba(220,220,220,0.2); | ||||
| 					} | ||||
| 					&.unique-visitors { | ||||
| 						border-color: rgba(151,187,205,1); | ||||
| 						background-color: rgba(151,187,205,0.2); | ||||
| 					} | ||||
| 					&.guest { | ||||
| 						border-color: #46BFBD; | ||||
| 						background-color: #5AD3D1; | ||||
| 					} | ||||
| 					&.registered { | ||||
| 						border-color: #F7464A; | ||||
| 						background-color: #FF5A5E; | ||||
| 					} | ||||
| 					&.reading-posts { | ||||
| 						border-color: #46BFBD; | ||||
| 						background-color: #5AD3D1; | ||||
| 					} | ||||
| 					&.on-categories { | ||||
| 						border-color: #F7464A; | ||||
| 						background-color: #FF5A5E; | ||||
| 					} | ||||
| 					&.browsing-topics { | ||||
| 						border-color: #FDB45C; | ||||
| 						background-color: #FFC870; | ||||
| 					} | ||||
| 					&.recent { | ||||
| 						border-color: #949FB1; | ||||
| 						background-color: #A8B3C5; | ||||
| 					} | ||||
| 					&.unread { | ||||
| 						border-color: #949FB1; | ||||
| 						background-color: #9FB194; | ||||
| 					} | ||||
| 				&.guest { | ||||
| 					border-color: #46BFBD; | ||||
| 					background-color: #5AD3D1; | ||||
| 				} | ||||
| 				&.registered { | ||||
| 					border-color: #F7464A; | ||||
| 					background-color: #FF5A5E; | ||||
| 				} | ||||
| 				&.reading-posts { | ||||
| 					border-color: #46BFBD; | ||||
| 					background-color: #5AD3D1; | ||||
| 				} | ||||
| 				&.on-categories { | ||||
| 					border-color: #F7464A; | ||||
| 					background-color: #FF5A5E; | ||||
| 				} | ||||
| 				&.browsing-topics { | ||||
| 					border-color: #FDB45C; | ||||
| 					background-color: #FFC870; | ||||
| 				} | ||||
| 				&.recent { | ||||
| 					border-color: #949FB1; | ||||
| 					background-color: #A8B3C5; | ||||
| 				} | ||||
| 				&.unread { | ||||
| 					border-color: #949FB1; | ||||
| 					background-color: #9FB194; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -1,7 +1,9 @@ | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| define('admin/advanced/errors', ['bootbox', 'alerts', 'Chart'], function (bootbox, alerts, Chart) { | ||||
| define('admin/advanced/errors', [ | ||||
| 	'bootbox', 'alerts', 'chart.js/auto', | ||||
| ], function (bootbox, alerts, { Chart }) { | ||||
| 	const Errors = {}; | ||||
|  | ||||
| 	Errors.init = function () { | ||||
| @@ -33,7 +35,7 @@ define('admin/advanced/errors', ['bootbox', 'alerts', 'Chart'], function (bootbo | ||||
| 		dailyLabels = dailyLabels.slice(-7); | ||||
|  | ||||
| 		if (utils.isMobile()) { | ||||
| 			Chart.defaults.global.tooltips.enabled = false; | ||||
| 			Chart.defaults.plugins.tooltip.enabled = false; | ||||
| 		} | ||||
|  | ||||
| 		const data = { | ||||
| @@ -42,6 +44,8 @@ define('admin/advanced/errors', ['bootbox', 'alerts', 'Chart'], function (bootbo | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: '', | ||||
| 						fill: 'origin', | ||||
| 						tension: 0.25, | ||||
| 						backgroundColor: 'rgba(186,139,175,0.2)', | ||||
| 						borderColor: 'rgba(186,139,175,1)', | ||||
| 						pointBackgroundColor: 'rgba(186,139,175,1)', | ||||
| @@ -57,6 +61,8 @@ define('admin/advanced/errors', ['bootbox', 'alerts', 'Chart'], function (bootbo | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: '', | ||||
| 						fill: 'origin', | ||||
| 						tension: 0.25, | ||||
| 						backgroundColor: 'rgba(151,187,205,0.2)', | ||||
| 						borderColor: 'rgba(151,187,205,1)', | ||||
| 						pointBackgroundColor: 'rgba(151,187,205,1)', | ||||
| @@ -69,23 +75,20 @@ define('admin/advanced/errors', ['bootbox', 'alerts', 'Chart'], function (bootbo | ||||
| 			}, | ||||
| 		}; | ||||
|  | ||||
| 		notFoundCanvas.width = $(notFoundCanvas).parent().width(); | ||||
| 		tooBusyCanvas.width = $(tooBusyCanvas).parent().width(); | ||||
|  | ||||
| 		new Chart(notFoundCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['not-found'], | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				plugins: { | ||||
| 					legend: { | ||||
| 						display: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 						}, | ||||
| 					}], | ||||
| 					y: { | ||||
| 						beginAtZero: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}); | ||||
| @@ -95,15 +98,15 @@ define('admin/advanced/errors', ['bootbox', 'alerts', 'Chart'], function (bootbo | ||||
| 			data: data.toobusy, | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				plugins: { | ||||
| 					legend: { | ||||
| 						display: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 						}, | ||||
| 					}], | ||||
| 					y: { | ||||
| 						beginAtZero: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}); | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
|  | ||||
|  | ||||
| define('admin/dashboard', [ | ||||
| 	'Chart', 'translator', 'benchpress', 'bootbox', 'alerts', 'helpers', | ||||
| ], function (Chart, translator, Benchpress, bootbox, alerts, helpers) { | ||||
| 	'chart.js/auto', 'translator', 'benchpress', 'bootbox', 'alerts', 'helpers', | ||||
| ], function ({ Chart }, translator, Benchpress, bootbox, alerts, helpers) { | ||||
| 	const Admin = {}; | ||||
| 	const intervals = { | ||||
| 		rooms: false, | ||||
| @@ -63,19 +63,19 @@ define('admin/dashboard', [ | ||||
|  | ||||
| 		graphData.rooms = data; | ||||
|  | ||||
| 		const html = '<div class="text-center float-start">' + | ||||
| 		const html = '<div class="text-center">' + | ||||
| 						'<span class="fs-5">' + helpers.formattedNumber(data.onlineRegisteredCount) + '</span>' + | ||||
| 						'<div class="stat text-nowrap text-uppercase fw-semibold text-xs text-muted">[[admin/dashboard:active-users.users]]</div>' + | ||||
| 					'</div>' + | ||||
| 					'<div class="text-center float-start">' + | ||||
| 					'<div class="text-center">' + | ||||
| 						'<span class="fs-5">' + helpers.formattedNumber(data.onlineGuestCount) + '</span>' + | ||||
| 						'<div class="stat text-nowrap text-uppercase fw-semibold text-xs text-muted">[[admin/dashboard:active-users.guests]]</div>' + | ||||
| 					'</div>' + | ||||
| 					'<div class="text-center float-start">' + | ||||
| 					'<div class="text-center">' + | ||||
| 						'<span class="fs-5">' + helpers.formattedNumber(data.onlineRegisteredCount + data.onlineGuestCount) + '</span>' + | ||||
| 						'<div class="stat text-nowrap text-uppercase fw-semibold text-xs text-muted">[[admin/dashboard:active-users.total]]</div>' + | ||||
| 					'</div>' + | ||||
| 					'<div class="text-center float-start">' + | ||||
| 					'<div class="text-center">' + | ||||
| 						'<span class="fs-5">' + helpers.formattedNumber(data.socketCount) + '</span>' + | ||||
| 						'<div class="stat text-nowrap text-uppercase fw-semibold text-xs text-muted">[[admin/dashboard:active-users.connections]]</div>' + | ||||
| 					'</div>'; | ||||
| @@ -140,7 +140,7 @@ define('admin/dashboard', [ | ||||
| 		const trafficLabels = utils.getHoursArray(); | ||||
|  | ||||
| 		if (isMobile) { | ||||
| 			Chart.defaults.global.tooltips.enabled = false; | ||||
| 			Chart.defaults.plugins.tooltip.enabled = false; | ||||
| 		} | ||||
|  | ||||
| 		const t = translator.Translator.create(); | ||||
| @@ -158,11 +158,14 @@ define('admin/dashboard', [ | ||||
| 			t.translateKey('admin/dashboard:recent', []), | ||||
| 			t.translateKey('admin/dashboard:unread', []), | ||||
| 		]).then(function (translations) { | ||||
| 			const tension = 0.25; | ||||
| 			const data = { | ||||
| 				labels: trafficLabels, | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: translations[0], | ||||
| 						fill: 'origin', | ||||
| 						tension: tension, | ||||
| 						backgroundColor: 'rgba(220,220,220,0.2)', | ||||
| 						borderColor: 'rgba(220,220,220,1)', | ||||
| 						pointBackgroundColor: 'rgba(220,220,220,1)', | ||||
| @@ -173,6 +176,8 @@ define('admin/dashboard', [ | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: translations[1], | ||||
| 						fill: 'origin', | ||||
| 						tension: tension, | ||||
| 						backgroundColor: '#ab464233', | ||||
| 						borderColor: '#ab4642', | ||||
| 						pointBackgroundColor: '#ab4642', | ||||
| @@ -183,6 +188,8 @@ define('admin/dashboard', [ | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: translations[2], | ||||
| 						fill: 'origin', | ||||
| 						tension: tension, | ||||
| 						backgroundColor: '#ba8baf33', | ||||
| 						borderColor: '#ba8baf', | ||||
| 						pointBackgroundColor: '#ba8baf', | ||||
| @@ -193,6 +200,8 @@ define('admin/dashboard', [ | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: translations[3], | ||||
| 						fill: 'origin', | ||||
| 						tension: tension, | ||||
| 						backgroundColor: '#f7ca8833', | ||||
| 						borderColor: '#f7ca88', | ||||
| 						pointBackgroundColor: '#f7ca88', | ||||
| @@ -203,6 +212,8 @@ define('admin/dashboard', [ | ||||
| 					}, | ||||
| 					{ | ||||
| 						label: translations[4], | ||||
| 						fill: 'origin', | ||||
| 						tension: tension, | ||||
| 						backgroundColor: 'rgba(151,187,205,0.2)', | ||||
| 						borderColor: 'rgba(151,187,205,1)', | ||||
| 						pointBackgroundColor: 'rgba(151,187,205,1)', | ||||
| @@ -227,43 +238,42 @@ define('admin/dashboard', [ | ||||
| 				data: data, | ||||
| 				options: { | ||||
| 					responsive: true, | ||||
| 					legend: { | ||||
| 						display: true, | ||||
| 					}, | ||||
| 					scales: { | ||||
| 						yAxes: [{ | ||||
| 							id: 'left-y-axis', | ||||
| 							ticks: { | ||||
| 								beginAtZero: true, | ||||
| 								precision: 0, | ||||
| 							}, | ||||
| 							type: 'linear', | ||||
| 						'left-y-axis': { | ||||
| 							position: 'left', | ||||
| 							scaleLabel: { | ||||
| 								display: true, | ||||
| 								labelString: translations[0], | ||||
| 							}, | ||||
| 						}, { | ||||
| 							id: 'right-y-axis', | ||||
| 							ticks: { | ||||
| 								beginAtZero: true, | ||||
| 								suggestedMax: 10, | ||||
| 								precision: 0, | ||||
| 							}, | ||||
| 							type: 'linear', | ||||
| 							position: 'right', | ||||
| 							scaleLabel: { | ||||
| 							title: { | ||||
| 								display: true, | ||||
| 								labelString: translations[4], | ||||
| 								text: translations[0], | ||||
| 							}, | ||||
| 						}], | ||||
| 							beginAtZero: true, | ||||
| 						}, | ||||
| 						'right-y-axis': { | ||||
| 							position: 'right', | ||||
| 							type: 'linear', | ||||
| 							title: { | ||||
| 								display: true, | ||||
| 								text: translations[4], | ||||
| 							}, | ||||
| 							beginAtZero: true, | ||||
| 						}, | ||||
| 					}, | ||||
| 					tooltips: { | ||||
| 						mode: 'x', | ||||
| 					interaction: { | ||||
| 						intersect: false, | ||||
| 						mode: 'index', | ||||
| 					}, | ||||
| 				}, | ||||
| 			}); | ||||
|  | ||||
| 			const doughnutOpts = { | ||||
| 				responsive: true, | ||||
| 				maintainAspectRatio: true, | ||||
| 				plugins: { | ||||
| 					legend: { | ||||
| 						display: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}; | ||||
| 			graphs.registered = new Chart(registeredCtx, { | ||||
| 				type: 'doughnut', | ||||
| 				data: { | ||||
| @@ -274,12 +284,7 @@ define('admin/dashboard', [ | ||||
| 						hoverBackgroundColor: ['#FF5A5E', '#5AD3D1'], | ||||
| 					}], | ||||
| 				}, | ||||
| 				options: { | ||||
| 					responsive: true, | ||||
| 					legend: { | ||||
| 						display: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 				options: doughnutOpts, | ||||
| 			}); | ||||
|  | ||||
| 			graphs.presence = new Chart(presenceCtx, { | ||||
| @@ -292,12 +297,7 @@ define('admin/dashboard', [ | ||||
| 						hoverBackgroundColor: ['#FF5A5E', '#5AD3D1', '#FFC870', '#A8B3C5', '#A8B3C5'], | ||||
| 					}], | ||||
| 				}, | ||||
| 				options: { | ||||
| 					responsive: true, | ||||
| 					legend: { | ||||
| 						display: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 				options: doughnutOpts, | ||||
| 			}); | ||||
|  | ||||
| 			graphs.topics = new Chart(topicsCtx, { | ||||
| @@ -310,19 +310,11 @@ define('admin/dashboard', [ | ||||
| 						hoverBackgroundColor: [], | ||||
| 					}], | ||||
| 				}, | ||||
| 				options: { | ||||
| 					responsive: true, | ||||
| 					legend: { | ||||
| 						display: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 				options: doughnutOpts, | ||||
| 			}); | ||||
|  | ||||
| 			updateTrafficGraph(); | ||||
|  | ||||
| 			$(window).on('resize', adjustPieCharts); | ||||
| 			adjustPieCharts(); | ||||
|  | ||||
| 			$('[data-action="updateGraph"]:not([data-units="custom"])').on('click', function () { | ||||
| 				let until = new Date(); | ||||
| 				const amount = $(this).attr('data-amount'); | ||||
| @@ -398,18 +390,6 @@ define('admin/dashboard', [ | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	function adjustPieCharts() { | ||||
| 		$('.pie-chart.legend-up').each(function () { | ||||
| 			const $this = $(this); | ||||
|  | ||||
| 			if ($this.width() < 320) { | ||||
| 				$this.addClass('compact'); | ||||
| 			} else { | ||||
| 				$this.removeClass('compact'); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	function updateTrafficGraph(units, until, amount) { | ||||
| 		// until and amount are optional | ||||
|  | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
|  | ||||
|  | ||||
| define('admin/manage/category-analytics', [ | ||||
| 	'Chart', 'categorySelector', | ||||
| ], function (Chart, categorySelector) { | ||||
| 	'chart.js/auto', 'categorySelector', | ||||
| ], function ({ Chart }, categorySelector) { | ||||
| 	const CategoryAnalytics = {}; | ||||
|  | ||||
| 	CategoryAnalytics.init = function () { | ||||
| @@ -27,20 +27,26 @@ define('admin/manage/category-analytics', [ | ||||
| 		}); | ||||
|  | ||||
| 		if (utils.isMobile()) { | ||||
| 			Chart.defaults.global.tooltips.enabled = false; | ||||
| 			Chart.defaults.plugins.tooltip.enabled = false; | ||||
| 		} | ||||
|  | ||||
| 		const commonDataSetOpts = { | ||||
| 			label: '', | ||||
| 			fill: true, | ||||
| 			tension: 0.25, | ||||
| 			pointHoverBackgroundColor: '#fff', | ||||
| 			pointBorderColor: '#fff', | ||||
| 		}; | ||||
|  | ||||
| 		const data = { | ||||
| 			'pageviews:hourly': { | ||||
| 				labels: hourlyLabels, | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: '', | ||||
| 						...commonDataSetOpts, | ||||
| 						backgroundColor: 'rgba(186,139,175,0.2)', | ||||
| 						borderColor: 'rgba(186,139,175,1)', | ||||
| 						pointBackgroundColor: 'rgba(186,139,175,1)', | ||||
| 						pointHoverBackgroundColor: '#fff', | ||||
| 						pointBorderColor: '#fff', | ||||
| 						pointHoverBorderColor: 'rgba(186,139,175,1)', | ||||
| 						data: ajaxify.data.analytics['pageviews:hourly'], | ||||
| 					}, | ||||
| @@ -50,12 +56,10 @@ define('admin/manage/category-analytics', [ | ||||
| 				labels: dailyLabels, | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: '', | ||||
| 						...commonDataSetOpts, | ||||
| 						backgroundColor: 'rgba(151,187,205,0.2)', | ||||
| 						borderColor: 'rgba(151,187,205,1)', | ||||
| 						pointBackgroundColor: 'rgba(151,187,205,1)', | ||||
| 						pointHoverBackgroundColor: '#fff', | ||||
| 						pointBorderColor: '#fff', | ||||
| 						pointHoverBorderColor: 'rgba(151,187,205,1)', | ||||
| 						data: ajaxify.data.analytics['pageviews:daily'], | ||||
| 					}, | ||||
| @@ -65,12 +69,10 @@ define('admin/manage/category-analytics', [ | ||||
| 				labels: dailyLabels.slice(-7), | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: '', | ||||
| 						...commonDataSetOpts, | ||||
| 						backgroundColor: 'rgba(171,70,66,0.2)', | ||||
| 						borderColor: 'rgba(171,70,66,1)', | ||||
| 						pointBackgroundColor: 'rgba(171,70,66,1)', | ||||
| 						pointHoverBackgroundColor: '#fff', | ||||
| 						pointBorderColor: '#fff', | ||||
| 						pointHoverBorderColor: 'rgba(171,70,66,1)', | ||||
| 						data: ajaxify.data.analytics['topics:daily'], | ||||
| 					}, | ||||
| @@ -80,12 +82,10 @@ define('admin/manage/category-analytics', [ | ||||
| 				labels: dailyLabels.slice(-7), | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: '', | ||||
| 						...commonDataSetOpts, | ||||
| 						backgroundColor: 'rgba(161,181,108,0.2)', | ||||
| 						borderColor: 'rgba(161,181,108,1)', | ||||
| 						pointBackgroundColor: 'rgba(161,181,108,1)', | ||||
| 						pointHoverBackgroundColor: '#fff', | ||||
| 						pointBorderColor: '#fff', | ||||
| 						pointHoverBorderColor: 'rgba(161,181,108,1)', | ||||
| 						data: ajaxify.data.analytics['posts:daily'], | ||||
| 					}, | ||||
| @@ -98,84 +98,43 @@ define('admin/manage/category-analytics', [ | ||||
| 		topicsCanvas.width = $(topicsCanvas).parent().width(); | ||||
| 		postsCanvas.width = $(postsCanvas).parent().width(); | ||||
|  | ||||
| 		new Chart(hourlyCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['pageviews:hourly'], | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				animation: false, | ||||
| 		const chartOpts = { | ||||
| 			responsive: true, | ||||
| 			animation: false, | ||||
| 			plugins: { | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 							precision: 0, | ||||
| 						}, | ||||
| 					}], | ||||
| 			}, | ||||
| 			scales: { | ||||
| 				y: { | ||||
| 					beginAtZero: true, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}; | ||||
|  | ||||
| 		new Chart(hourlyCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['pageviews:hourly'], | ||||
| 			options: chartOpts, | ||||
| 		}); | ||||
|  | ||||
| 		new Chart(dailyCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['pageviews:daily'], | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				animation: false, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 							precision: 0, | ||||
| 						}, | ||||
| 					}], | ||||
| 				}, | ||||
| 			}, | ||||
| 			options: chartOpts, | ||||
| 		}); | ||||
|  | ||||
| 		new Chart(topicsCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['topics:daily'], | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				animation: false, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 							precision: 0, | ||||
| 						}, | ||||
| 					}], | ||||
| 				}, | ||||
| 			}, | ||||
| 			options: chartOpts, | ||||
| 		}); | ||||
|  | ||||
| 		new Chart(postsCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['posts:daily'], | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				animation: false, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 							precision: 0, | ||||
| 						}, | ||||
| 					}], | ||||
| 				}, | ||||
| 			}, | ||||
| 			options: chartOpts, | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| define('admin/modules/dashboard-line-graph', ['Chart', 'translator', 'benchpress', 'api', 'hooks', 'bootbox'], function (Chart, translator, Benchpress, api, hooks, bootbox) { | ||||
| define('admin/modules/dashboard-line-graph', [ | ||||
| 	'chart.js/auto', 'translator', 'benchpress', 'api', 'hooks', 'bootbox', | ||||
| ], function ({ Chart }, translator, Benchpress, api, hooks, bootbox) { | ||||
| 	const Graph = { | ||||
| 		_current: null, | ||||
| 	}; | ||||
| @@ -13,7 +15,7 @@ define('admin/modules/dashboard-line-graph', ['Chart', 'translator', 'benchpress | ||||
|  | ||||
| 		isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); | ||||
| 		if (isMobile) { | ||||
| 			Chart.defaults.global.tooltips.enabled = false; | ||||
| 			Chart.defaults.plugins.tooltip.enabled = false; | ||||
| 		} | ||||
|  | ||||
| 		Graph.handleUpdateControls({ set }); | ||||
| @@ -26,6 +28,8 @@ define('admin/modules/dashboard-line-graph', ['Chart', 'translator', 'benchpress | ||||
| 					datasets: [ | ||||
| 						{ | ||||
| 							label: key, | ||||
| 							fill: true, | ||||
| 							tension: 0.25, | ||||
| 							backgroundColor: 'rgba(151,187,205,0.2)', | ||||
| 							borderColor: 'rgba(151,187,205,1)', | ||||
| 							pointBackgroundColor: 'rgba(151,187,205,1)', | ||||
| @@ -46,26 +50,20 @@ define('admin/modules/dashboard-line-graph', ['Chart', 'translator', 'benchpress | ||||
| 					data: data, | ||||
| 					options: { | ||||
| 						responsive: true, | ||||
| 						legend: { | ||||
| 							display: true, | ||||
| 						}, | ||||
| 						scales: { | ||||
| 							yAxes: [{ | ||||
| 								id: 'left-y-axis', | ||||
| 								ticks: { | ||||
| 									beginAtZero: true, | ||||
| 									precision: 0, | ||||
| 								}, | ||||
| 							'left-y-axis': { | ||||
| 								type: 'linear', | ||||
| 								position: 'left', | ||||
| 								scaleLabel: { | ||||
| 								beginAtZero: true, | ||||
| 								title: { | ||||
| 									display: true, | ||||
| 									labelString: key, | ||||
| 									text: key, | ||||
| 								}, | ||||
| 							}], | ||||
| 							}, | ||||
| 						}, | ||||
| 						tooltips: { | ||||
| 							mode: 'x', | ||||
| 						interaction: { | ||||
| 							intersect: false, | ||||
| 							mode: 'index', | ||||
| 						}, | ||||
| 					}, | ||||
| 				}); | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| define('forum/flags/list', [ | ||||
| 	'components', 'Chart', 'categoryFilter', | ||||
| 	'components', 'chart.js/auto', 'categoryFilter', | ||||
| 	'autocomplete', 'api', 'alerts', | ||||
| 	'userFilter', | ||||
| ], function ( | ||||
| 	components, Chart, categoryFilter, | ||||
| 	components, { Chart }, categoryFilter, | ||||
| 	autocomplete, api, alerts, | ||||
| 	userFilter | ||||
| ) { | ||||
| @@ -255,7 +255,7 @@ define('forum/flags/list', [ | ||||
| 		}); | ||||
|  | ||||
| 		if (utils.isMobile()) { | ||||
| 			Chart.defaults.global.tooltips.enabled = false; | ||||
| 			Chart.defaults.plugins.tooltip.enabled = false; | ||||
| 		} | ||||
| 		const data = { | ||||
| 			'flags:daily': { | ||||
| @@ -282,16 +282,15 @@ define('forum/flags/list', [ | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				animation: false, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				plugins: { | ||||
| 					legend: { | ||||
| 						display: false, | ||||
| 					}, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 							precision: 0, | ||||
| 						}, | ||||
| 					}], | ||||
| 					y: { | ||||
| 						beginAtZero: true, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}); | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| define('forum/ip-blacklist', ['Chart', 'benchpress', 'bootbox', 'alerts'], function (Chart, Benchpress, bootbox, alerts) { | ||||
| define('forum/ip-blacklist', [ | ||||
| 	'chart.js/auto', 'benchpress', 'bootbox', 'alerts', | ||||
| ], function ({ Chart }, Benchpress, bootbox, alerts) { | ||||
| 	const Blacklist = {}; | ||||
|  | ||||
| 	Blacklist.init = function () { | ||||
| @@ -52,7 +53,7 @@ define('forum/ip-blacklist', ['Chart', 'benchpress', 'bootbox', 'alerts'], funct | ||||
| 		}); | ||||
|  | ||||
| 		if (utils.isMobile()) { | ||||
| 			Chart.defaults.global.tooltips.enabled = false; | ||||
| 			Chart.defaults.plugins.tooltip.enabled = false; | ||||
| 		} | ||||
|  | ||||
| 		const data = { | ||||
| @@ -61,6 +62,8 @@ define('forum/ip-blacklist', ['Chart', 'benchpress', 'bootbox', 'alerts'], funct | ||||
| 				datasets: [ | ||||
| 					{ | ||||
| 						label: '', | ||||
| 						fill: 'origin', | ||||
| 						tension: 0.25, | ||||
| 						backgroundColor: 'rgba(186,139,175,0.2)', | ||||
| 						borderColor: 'rgba(186,139,175,1)', | ||||
| 						pointBackgroundColor: 'rgba(186,139,175,1)', | ||||
| @@ -88,45 +91,34 @@ define('forum/ip-blacklist', ['Chart', 'benchpress', 'bootbox', 'alerts'], funct | ||||
| 			}, | ||||
| 		}; | ||||
|  | ||||
| 		hourlyCanvas.width = $(hourlyCanvas).parent().width(); | ||||
| 		dailyCanvas.width = $(dailyCanvas).parent().width(); | ||||
| 		const chartOpts = { | ||||
| 			responsive: true, | ||||
| 			maintainAspectRatio: true, | ||||
| 			plugins: { | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				}, | ||||
| 			}, | ||||
| 			scales: { | ||||
| 				y: { | ||||
| 					position: 'left', | ||||
| 					type: 'linear', | ||||
| 					beginAtZero: true, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}; | ||||
|  | ||||
|  | ||||
| 		new Chart(hourlyCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['blacklist:hourly'], | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				animation: false, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 						}, | ||||
| 					}], | ||||
| 				}, | ||||
| 			}, | ||||
| 			options: chartOpts, | ||||
| 		}); | ||||
|  | ||||
| 		new Chart(dailyCanvas.getContext('2d'), { | ||||
| 			type: 'line', | ||||
| 			data: data['blacklist:daily'], | ||||
| 			options: { | ||||
| 				responsive: true, | ||||
| 				animation: false, | ||||
| 				legend: { | ||||
| 					display: false, | ||||
| 				}, | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							beginAtZero: true, | ||||
| 						}, | ||||
| 					}], | ||||
| 				}, | ||||
| 			}, | ||||
| 			options: chartOpts, | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
|   | ||||
| @@ -17,8 +17,10 @@ | ||||
| 		<div class="row"> | ||||
| 			<div class="col-sm-6 text-center"> | ||||
| 				<div class="card"> | ||||
| 					<div class="card-body"> | ||||
| 						<div><canvas id="not-found" height="250"></canvas></div> | ||||
| 					<div class="card-body" > | ||||
| 						<div class="position-relative" style="aspect-ratio: 2;"> | ||||
| 							<canvas id="not-found"></canvas> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="card-footer"><small> | ||||
| 						<strong>[[admin/advanced/errors:figure-x, 1]]</strong> – | ||||
| @@ -29,7 +31,9 @@ | ||||
| 			<div class="col-sm-6 text-center"> | ||||
| 				<div class="card"> | ||||
| 					<div class="card-body"> | ||||
| 						<div><canvas id="toobusy" height="250"></canvas></div> | ||||
| 						<div class="position-relative" style="aspect-ratio: 2;"> | ||||
| 							<canvas id="toobusy"></canvas> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="card-footer"><small> | ||||
| 						<strong>[[admin/advanced/errors:figure-x, 2]]</strong> – | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <div class="row dashboard px-lg-4"> | ||||
| 	<div class="col-lg-9"> | ||||
| 	<div class="col-lg-8 col-xl-9"> | ||||
| 		<!-- IMPORT admin/partials/dashboard/graph.tpl --> | ||||
| 		<!-- IMPORT admin/partials/dashboard/stats.tpl --> | ||||
|  | ||||
| @@ -8,13 +8,13 @@ | ||||
| 				<div class="card"> | ||||
| 					<div class="card-header">[[admin/dashboard:guest-registered-users]]</div> | ||||
| 					<div class="card-body"> | ||||
| 						<div class="graph-container pie-chart legend-down"> | ||||
| 						<div class="graph-container pie-chart legend-down position-relative mb-3 px-3 mx-auto" style="aspect-ratio: 1;"> | ||||
| 							<canvas id="analytics-registered"></canvas> | ||||
| 							<ul class="graph-legend border" id="analytics-legend"> | ||||
| 								<li><div class="registered"></div><span>(<span class="count"></span>) [[admin/dashboard:registered]]</span></li> | ||||
| 								<li><div class="guest"></div><span>(<span class="count"></span>) [[admin/dashboard:guest]]</span></li> | ||||
| 							</ul> | ||||
| 						</div> | ||||
| 						<ul class="graph-legend list-unstyled" id="analytics-legend"> | ||||
| 							<li><div class="registered"></div><span>(<span class="count"></span>) [[admin/dashboard:registered]]</span></li> | ||||
| 							<li><div class="guest"></div><span>(<span class="count"></span>) [[admin/dashboard:guest]]</span></li> | ||||
| 						</ul> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| @@ -23,16 +23,16 @@ | ||||
| 				<div class="card"> | ||||
| 					<div class="card-header">[[admin/dashboard:user-presence]]</div> | ||||
| 					<div class="card-body"> | ||||
| 						<div class="graph-container pie-chart legend-down"> | ||||
| 						<div class="graph-container pie-chart legend-down position-relative mb-3 px-3 mx-auto" style="aspect-ratio: 1;"> | ||||
| 							<canvas id="analytics-presence"></canvas> | ||||
| 							<ul class="graph-legend border" id="analytics-presence-legend"> | ||||
| 								<li><div class="reading-posts"></div><span>(<span class="count"></span>) [[admin/dashboard:reading-posts]]</span></li> | ||||
| 								<li><div class="on-categories"></div><span>(<span class="count"></span>) [[admin/dashboard:on-categories]]</span></li> | ||||
| 								<li><div class="browsing-topics"></div><span>(<span class="count"></span>) [[admin/dashboard:browsing-topics]]</span></li> | ||||
| 								<li><div class="recent"></div><span>(<span class="count"></span>) [[admin/dashboard:recent]]</span></li> | ||||
| 								<li><div class="unread"></div><span>(<span class="count"></span>) [[admin/dashboard:unread]]</span></li> | ||||
| 							</ul> | ||||
| 						</div> | ||||
| 						<ul class="graph-legend list-unstyled" id="analytics-presence-legend"> | ||||
| 							<li><div class="reading-posts"></div><span>(<span class="count"></span>) [[admin/dashboard:reading-posts]]</span></li> | ||||
| 							<li><div class="on-categories"></div><span>(<span class="count"></span>) [[admin/dashboard:on-categories]]</span></li> | ||||
| 							<li><div class="browsing-topics"></div><span>(<span class="count"></span>) [[admin/dashboard:browsing-topics]]</span></li> | ||||
| 							<li><div class="recent"></div><span>(<span class="count"></span>) [[admin/dashboard:recent]]</span></li> | ||||
| 							<li><div class="unread"></div><span>(<span class="count"></span>) [[admin/dashboard:unread]]</span></li> | ||||
| 						</ul> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| @@ -40,17 +40,17 @@ | ||||
| 				<div class="card"> | ||||
| 					<div class="card-header">[[admin/dashboard:high-presence-topics]]</div> | ||||
| 					<div class="card-body"> | ||||
| 						<div class="graph-container pie-chart legend-down"> | ||||
| 						<div class="graph-container pie-chart legend-down position-relative mb-3 px-3 mx-auto" style="aspect-ratio: 1;"> | ||||
| 							<canvas id="analytics-topics"></canvas> | ||||
| 							<ul class="graph-legend border" id="topics-legend"></ul> | ||||
| 						</div> | ||||
| 						<ul class="graph-legend list-unstyled" id="topics-legend"></ul> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
|  | ||||
| 	<div class="col-lg-3"> | ||||
| 	<div class="col-lg-4 col-xl-3"> | ||||
| 		<div class="card mb-3"> | ||||
| 			<div class="card-body"> | ||||
| 				<div class="text-sm shadow-sm alert {{{ if lookupFailed }}}alert-danger{{{ else }}}{{{ if upgradeAvailable }}}alert-warning{{{ else }}}{{{ if currentPrerelease }}}alert-info{{{ else }}}alert-success{{{ end }}}{{{ end }}}{{{ end }}} version-check"> | ||||
| @@ -112,7 +112,7 @@ | ||||
| 		<div class="card mb-3"> | ||||
| 			<div class="card-header">[[admin/dashboard:active-users]]</div> | ||||
| 			<div class="card-body"> | ||||
| 				<div id="active-users" class="stats row row-cols-2"></div> | ||||
| 				<div id="active-users" class="stats row row-cols-2 row-cols-md-1 row-cols-lg-2"></div> | ||||
| 			</div> | ||||
| 		</div> | ||||
|  | ||||
|   | ||||
| @@ -14,10 +14,9 @@ | ||||
| 		<div class="col-sm-6 text-center"> | ||||
| 			<div class="card"> | ||||
| 				<div class="card-body"> | ||||
| 					<div><canvas id="pageviews:hourly" height="250"></canvas></div> | ||||
| 					<p> | ||||
|  | ||||
| 					</p> | ||||
| 					<div class="position-relative" style="aspect-ratio: 2;"> | ||||
| 						<canvas id="pageviews:hourly"></canvas> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<div class="card-footer"><small>[[admin/manage/categories:analytics.pageviews-hourly]]</div> | ||||
| 			</div> | ||||
| @@ -25,10 +24,9 @@ | ||||
| 		<div class="col-sm-6 text-center"> | ||||
| 			<div class="card"> | ||||
| 				<div class="card-body"> | ||||
| 					<div><canvas id="pageviews:daily" height="250"></canvas></div> | ||||
| 					<p> | ||||
|  | ||||
| 					</p> | ||||
| 					<div class="position-relative" style="aspect-ratio: 2;"> | ||||
| 						<canvas id="pageviews:daily" height="250"></canvas> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<div class="card-footer"><small>[[admin/manage/categories:analytics.pageviews-daily]]</div> | ||||
| 			</div> | ||||
| @@ -38,10 +36,9 @@ | ||||
| 		<div class="col-sm-6 text-center"> | ||||
| 			<div class="card"> | ||||
| 				<div class="card-body"> | ||||
| 					<div><canvas id="topics:daily" height="250"></canvas></div> | ||||
| 					<p> | ||||
|  | ||||
| 					</p> | ||||
| 					<div class="position-relative" style="aspect-ratio: 2;"> | ||||
| 						<canvas id="topics:daily" height="250"></canvas> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<div class="card-footer"><small>[[admin/manage/categories:analytics.topics-daily]]</div> | ||||
| 			</div> | ||||
| @@ -49,10 +46,9 @@ | ||||
| 		<div class="col-sm-6 text-center"> | ||||
| 			<div class="card"> | ||||
| 				<div class="card-body"> | ||||
| 					<div><canvas id="posts:daily" height="250"></canvas></div> | ||||
| 					<p> | ||||
|  | ||||
| 					</p> | ||||
| 					<div class="position-relative" style="aspect-ratio: 2;"> | ||||
| 						<canvas id="posts:daily" height="250"></canvas> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<div class="card-footer"><small>[[admin/manage/categories:analytics.posts-daily]]</div> | ||||
| 			</div> | ||||
|   | ||||
| @@ -10,8 +10,8 @@ | ||||
| 		</div> | ||||
| 	</div> | ||||
| 	<div class="card-body"> | ||||
| 		<div class="graph-container" id="analytics-traffic-container"> | ||||
| 			<canvas id="analytics-traffic" width="100%" height="400"></canvas> | ||||
| 		<div class="graph-container position-relative" id="analytics-traffic-container" style="aspect-ratio: 16/9;"> | ||||
| 			<canvas id="analytics-traffic" ></canvas> | ||||
| 		</div> | ||||
| 		<hr/> | ||||
| 		<div class="row"> | ||||
|   | ||||
| @@ -40,14 +40,18 @@ | ||||
| 			<div class="col-sm-6"> | ||||
| 				<div class="card mb-3"> | ||||
| 					<div class="card-body"> | ||||
| 						<div><canvas id="blacklist:hourly" height="250"></canvas></div> | ||||
| 						<div class="position-relative" style="aspect-ratio: 2; max-height: initial;"> | ||||
| 							<canvas id="blacklist:hourly" style="max-height: initial;"></canvas> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="card-footer"><small>[[ip-blacklist:analytics.blacklist-hourly]]</small></div> | ||||
| 				</div> | ||||
|  | ||||
| 				<div class="card"> | ||||
| 					<div class="card-body"> | ||||
| 						<div><canvas id="blacklist:daily" height="250"></canvas></div> | ||||
| 						<div class="position-relative" style="aspect-ratio: 2; max-height: initial;"> | ||||
| 							<canvas id="blacklist:daily" style="max-height: initial;"></canvas> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="card-footer"><small>[[ip-blacklist:analytics.blacklist-daily]]</small></div> | ||||
| 				</div> | ||||
|   | ||||
| @@ -59,7 +59,6 @@ module.exports = { | ||||
| 			admin: path.resolve(__dirname, 'build/public/src/admin'), | ||||
| 			vendor: path.resolve(__dirname, 'public/vendor'), | ||||
| 			benchpress: path.resolve(__dirname, 'node_modules/benchpressjs'), | ||||
| 			Chart: path.resolve(__dirname, 'node_modules/chart.js'), | ||||
| 			Sortable: path.resolve(__dirname, 'node_modules/sortablejs'), | ||||
| 			cropper: path.resolve(__dirname, 'node_modules/cropperjs'), | ||||
| 			'jquery-ui/widgets': path.resolve(__dirname, 'node_modules/jquery-ui/ui/widgets'), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user