mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-26 14:09:43 -08:00
7571d45d44
If multicompany option is enabled much more important for admin is to see on dashboard list of companies instead of locations. In other way if multicompanies option is disabled then locations are displayed.
546 lines
23 KiB
PHP
Executable file
546 lines
23 KiB
PHP
Executable file
@extends('layouts/default')
|
|
{{-- Page title --}}
|
|
@section('title')
|
|
{{ trans('general.dashboard') }}
|
|
@parent
|
|
@stop
|
|
|
|
|
|
{{-- Page content --}}
|
|
@section('content')
|
|
|
|
@if ($snipeSettings->dashboard_message!='')
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="box">
|
|
<!-- /.box-header -->
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
{!! Helper::parseEscapedMarkedown($snipeSettings->dashboard_message) !!}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="row">
|
|
<!-- panel -->
|
|
<div class="col-lg-2 col-xs-6">
|
|
<a href="{{ route('hardware.index') }}">
|
|
<!-- small box -->
|
|
<div class="small-box bg-teal">
|
|
<div class="inner">
|
|
<h3>{{ number_format(\App\Models\Asset::AssetsForShow()->count()) }}</h3>
|
|
<p>{{ strtolower(trans('general.assets')) }}</p>
|
|
</div>
|
|
<div class="icon" aria-hidden="true">
|
|
<i class="fas fa-barcode" aria-hidden="true"></i>
|
|
</div>
|
|
@can('index', \App\Models\Asset::class)
|
|
<a href="{{ route('hardware.index') }}" class="small-box-footer">{{ trans('general.view_all') }} <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a>
|
|
@endcan
|
|
</div>
|
|
</a>
|
|
</div><!-- ./col -->
|
|
|
|
<div class="col-lg-2 col-xs-6">
|
|
<a href="{{ route('licenses.index') }}">
|
|
<!-- small box -->
|
|
<div class="small-box bg-maroon">
|
|
<div class="inner">
|
|
<h3>{{ number_format($counts['license']) }}</h3>
|
|
<p>{{ strtolower(trans('general.licenses')) }}</p>
|
|
</div>
|
|
<div class="icon" aria-hidden="true">
|
|
<i class="far fa-save"></i>
|
|
</div>
|
|
@can('view', \App\Models\License::class)
|
|
<a href="{{ route('licenses.index') }}" class="small-box-footer">{{ trans('general.view_all') }} <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a>
|
|
@endcan
|
|
</div>
|
|
</a>
|
|
</div><!-- ./col -->
|
|
|
|
|
|
<div class="col-lg-2 col-xs-6">
|
|
<!-- small box -->
|
|
<a href="{{ route('accessories.index') }}">
|
|
<div class="small-box bg-orange">
|
|
<div class="inner">
|
|
<h3> {{ number_format($counts['accessory']) }}</h3>
|
|
<p>{{ strtolower(trans('general.accessories')) }}</p>
|
|
</div>
|
|
<div class="icon" aria-hidden="true">
|
|
<i class="far fa-keyboard"></i>
|
|
</div>
|
|
@can('index', \App\Models\Accessory::class)
|
|
<a href="{{ route('accessories.index') }}" class="small-box-footer">{{ trans('general.view_all') }} <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a>
|
|
@endcan
|
|
</div>
|
|
</a>
|
|
</div><!-- ./col -->
|
|
|
|
<div class="col-lg-2 col-xs-6">
|
|
<!-- small box -->
|
|
|
|
<a href="{{ route('consumables.index') }}">
|
|
<div class="small-box bg-purple">
|
|
<div class="inner">
|
|
<h3> {{ number_format($counts['consumable']) }}</h3>
|
|
<p>{{ strtolower(trans('general.consumables')) }}</p>
|
|
</div>
|
|
<div class="icon" aria-hidden="true">
|
|
<i class="fas fa-tint"></i>
|
|
</div>
|
|
@can('index', \App\Models\Consumable::class)
|
|
<a href="{{ route('consumables.index') }}" class="small-box-footer">{{ trans('general.view_all') }} <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a>
|
|
@endcan
|
|
</div>
|
|
</div><!-- ./col -->
|
|
|
|
<div class="col-lg-2 col-xs-6">
|
|
<a href="{{ route('components.index') }}">
|
|
<!-- small box -->
|
|
<div class="small-box bg-yellow">
|
|
<div class="inner">
|
|
<h3>{{ number_format($counts['component']) }}</h3>
|
|
<p>{{ strtolower(trans('general.components')) }}</p>
|
|
</div>
|
|
<div class="icon" aria-hidden="true">
|
|
<i class="far fa-hdd"></i>
|
|
</div>
|
|
@can('view', \App\Models\License::class)
|
|
<a href="{{ route('components.index') }}" class="small-box-footer">{{ trans('general.view_all') }} <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a>
|
|
@endcan
|
|
</div>
|
|
</a>
|
|
</div><!-- ./col -->
|
|
|
|
<div class="col-lg-2 col-xs-6">
|
|
<a href="{{ route('users.index') }}">
|
|
<!-- small box -->
|
|
<div class="small-box bg-light-blue">
|
|
<div class="inner">
|
|
<h3>{{ number_format($counts['user']) }}</h3>
|
|
<p>{{ strtolower(trans('general.people')) }}</p>
|
|
</div>
|
|
<div class="icon" aria-hidden="true">
|
|
<i class="fas fa-users"></i>
|
|
</div>
|
|
@can('view', \App\Models\License::class)
|
|
<a href="{{ route('users.index') }}" class="small-box-footer">{{ trans('general.view_all') }} <i class="fa fa-arrow-circle-right" aria-hidden="true"></i></a>
|
|
@endcan
|
|
</div>
|
|
</a>
|
|
</div><!-- ./col -->
|
|
|
|
</div>
|
|
</div>
|
|
|
|
@if ($counts['grand_total'] == 0)
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="box">
|
|
<div class="box-header with-border">
|
|
<h2 class="box-title">{{ trans('general.dashboard_info') }}</h2>
|
|
</div>
|
|
<!-- /.box-header -->
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
|
|
<div class="progress">
|
|
<div class="progress-bar progress-bar-yellow" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%">
|
|
<span class="sr-only">{{ trans('general.60_percent_warning') }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<p><strong>{{ trans('general.dashboard_empty') }}</strong></p>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
@can('create', \App\Models\Asset::class)
|
|
<a class="btn bg-teal" style="width: 100%" href="{{ route('hardware.create') }}">{{ trans('general.new_asset') }}</a>
|
|
@endcan
|
|
</div>
|
|
<div class="col-md-3">
|
|
@can('create', \App\Models\License::class)
|
|
<a class="btn bg-maroon" style="width: 100%" href="{{ route('licenses.create') }}">{{ trans('general.new_license') }}</a>
|
|
@endcan
|
|
</div>
|
|
<div class="col-md-3">
|
|
@can('create', \App\Models\Accessory::class)
|
|
<a class="btn bg-orange" style="width: 100%" href="{{ route('accessories.create') }}">{{ trans('general.new_accessory') }}</a>
|
|
@endcan
|
|
</div>
|
|
<div class="col-md-3">
|
|
@can('create', \App\Models\Consumable::class)
|
|
<a class="btn bg-purple" style="width: 100%" href="{{ route('consumables.create') }}">{{ trans('general.new_consumable') }}</a>
|
|
@endcan
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@else
|
|
|
|
<!-- recent activity -->
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="box">
|
|
<div class="box-header with-border">
|
|
<h2 class="box-title">{{ trans('general.recent_activity') }}</h2>
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse" aria-hidden="true">
|
|
<i class="fas fa-minus" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.collapse') }}</span>
|
|
</button>
|
|
</div>
|
|
</div><!-- /.box-header -->
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="table-responsive">
|
|
|
|
<table
|
|
data-cookie-id-table="dashActivityReport"
|
|
data-height="350"
|
|
data-pagination="false"
|
|
data-id-table="dashActivityReport"
|
|
data-side-pagination="server"
|
|
data-sort-order="desc"
|
|
data-sort-name="created_at"
|
|
id="dashActivityReport"
|
|
class="table table-striped snipe-table"
|
|
data-url="{{ route('api.activity.index', ['limit' => 25]) }}">
|
|
<thead>
|
|
<tr>
|
|
<th data-field="icon" data-visible="true" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"><span class="sr-only">{{ trans('admin/hardware/table.icon') }}</span></th>
|
|
<th class="col-sm-3" data-visible="true" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
|
|
<th class="col-sm-2" data-visible="true" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
|
<th class="col-sm-2" data-visible="true" data-field="action_type">{{ trans('general.action') }}</th>
|
|
<th class="col-sm-3" data-visible="true" data-field="item" data-formatter="polymorphicItemFormatter">{{ trans('general.item') }}</th>
|
|
<th class="col-sm-2" data-visible="true" data-field="target" data-formatter="polymorphicItemFormatter">{{ trans('general.target') }}</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
|
|
|
|
|
|
</div><!-- /.responsive -->
|
|
</div><!-- /.col -->
|
|
<div class="text-center col-md-12" style="padding-top: 10px;">
|
|
<a href="{{ route('reports.activity') }}" class="btn btn-primary btn-sm" style="width: 100%">{{ trans('general.viewall') }}</a>
|
|
</div>
|
|
</div><!-- /.row -->
|
|
</div><!-- ./box-body -->
|
|
</div><!-- /.box -->
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="box box-default">
|
|
<div class="box-header with-border">
|
|
<h2 class="box-title">
|
|
{{ (\App\Models\Setting::getSettings()->dash_chart_type == 'name') ? trans('general.assets_by_status') : trans('general.assets_by_status_type') }}
|
|
</h2>
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse" aria-hidden="true">
|
|
<i class="fas fa-minus" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.collapse') }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- /.box-header -->
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="chart-responsive">
|
|
<canvas id="statusPieChart" height="260"></canvas>
|
|
</div> <!-- ./chart-responsive -->
|
|
</div> <!-- /.col -->
|
|
</div> <!-- /.row -->
|
|
</div><!-- /.box-body -->
|
|
</div> <!-- /.box -->
|
|
</div>
|
|
|
|
</div> <!--/row-->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
|
|
@if ($snipeSettings->full_multiple_companies_support=='1')
|
|
<!-- Companies -->
|
|
<div class="box box-default">
|
|
<div class="box-header with-border">
|
|
<h2 class="box-title">{{ trans('general.companies') }}</h2>
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse">
|
|
<i class="fas fa-minus" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.collapse') }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- /.box-header -->
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="table-responsive">
|
|
<table
|
|
data-cookie-id-table="dashCompanySummary"
|
|
data-height="400"
|
|
data-pagination="true"
|
|
data-side-pagination="server"
|
|
data-sort-order="desc"
|
|
data-sort-field="assets_count"
|
|
id="dashCompanySummary"
|
|
class="table table-striped snipe-table"
|
|
data-url="{{ route('api.companies.index', ['sort' => 'assets_count', 'order' => 'asc']) }}">
|
|
|
|
<thead>
|
|
<tr>
|
|
<th class="col-sm-3" data-visible="true" data-field="name" data-formatter="companiesLinkFormatter" data-sortable="true">{{ trans('general.name') }}</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="users_count" data-sortable="true">
|
|
<i class="fas fa-users" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.people') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="assets_count" data-sortable="true">
|
|
<i class="fas fa-barcode" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.asset_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="accessories_count" data-sortable="true">
|
|
<i class="far fa-keyboard" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.accessories_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="consumables_count" data-sortable="true">
|
|
<i class="fas fa-tint" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.consumables_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="components_count" data-sortable="true">
|
|
<i class="far fa-hdd" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.components_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="licenses_count" data-sortable="true">
|
|
<i class="far fa-save" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.licenses_count') }}</span>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div> <!-- /.col -->
|
|
<div class="text-center col-md-12" style="padding-top: 10px;">
|
|
<a href="{{ route('companies.index') }}" class="btn btn-primary btn-sm" style="width: 100%">{{ trans('general.viewall') }}</a>
|
|
</div>
|
|
</div> <!-- /.row -->
|
|
|
|
</div><!-- /.box-body -->
|
|
</div> <!-- /.box -->
|
|
|
|
@else
|
|
<!-- Locations -->
|
|
<div class="box box-default">
|
|
<div class="box-header with-border">
|
|
<h2 class="box-title">{{ trans('general.locations') }}</h2>
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse">
|
|
<i class="fas fa-minus" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.collapse') }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- /.box-header -->
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="table-responsive">
|
|
<table
|
|
data-cookie-id-table="dashLocationSummary"
|
|
data-height="400"
|
|
data-pagination="true"
|
|
data-side-pagination="server"
|
|
data-sort-order="desc"
|
|
data-sort-field="assets_count"
|
|
id="dashLocationSummary"
|
|
class="table table-striped snipe-table"
|
|
data-url="{{ route('api.locations.index', ['sort' => 'assets_count', 'order' => 'asc']) }}">
|
|
|
|
<thead>
|
|
<tr>
|
|
<th class="col-sm-3" data-visible="true" data-field="name" data-formatter="locationsLinkFormatter" data-sortable="true">{{ trans('general.name') }}</th>
|
|
|
|
<th class="col-sm-1" data-visible="true" data-field="assets_count" data-sortable="true">
|
|
<i class="fas fa-barcode" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.asset_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="assigned_assets_count" data-sortable="true">
|
|
|
|
{{ trans('general.assigned') }}
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="users_count" data-sortable="true">
|
|
<i class="fas fa-users" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.people') }}</span>
|
|
|
|
</th>
|
|
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div> <!-- /.col -->
|
|
<div class="text-center col-md-12" style="padding-top: 10px;">
|
|
<a href="{{ route('locations.index') }}" class="btn btn-primary btn-sm" style="width: 100%">{{ trans('general.viewall') }}</a>
|
|
</div>
|
|
</div> <!-- /.row -->
|
|
|
|
</div><!-- /.box-body -->
|
|
</div> <!-- /.box -->
|
|
|
|
@endif
|
|
|
|
</div>
|
|
<div class="col-md-6">
|
|
|
|
<!-- Categories -->
|
|
<div class="box box-default">
|
|
<div class="box-header with-border">
|
|
<h2 class="box-title">{{ trans('general.asset') }} {{ trans('general.categories') }}</h2>
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse">
|
|
<i class="fas fa-minus" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.collapse') }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- /.box-header -->
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="table-responsive">
|
|
<table
|
|
data-cookie-id-table="dashCategorySummary"
|
|
data-height="400"
|
|
data-pagination="true"
|
|
data-side-pagination="server"
|
|
data-sort-order="desc"
|
|
data-sort-field="assets_count"
|
|
id="dashCategorySummary"
|
|
class="table table-striped snipe-table"
|
|
data-url="{{ route('api.categories.index', ['sort' => 'assets_count', 'order' => 'asc']) }}">
|
|
|
|
<thead>
|
|
<tr>
|
|
<th class="col-sm-3" data-visible="true" data-field="name" data-formatter="categoriesLinkFormatter" data-sortable="true">{{ trans('general.name') }}</th>
|
|
<th class="col-sm-3" data-visible="true" data-field="category_type" data-sortable="true">
|
|
{{ trans('general.type') }}
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="assets_count" data-sortable="true">
|
|
<i class="fas fa-barcode" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.asset_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="accessories_count" data-sortable="true">
|
|
<i class="far fa-keyboard" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.accessories_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="consumables_count" data-sortable="true">
|
|
<i class="fas fa-tint" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.consumables_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="components_count" data-sortable="true">
|
|
<i class="far fa-hdd" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.components_count') }}</span>
|
|
</th>
|
|
<th class="col-sm-1" data-visible="true" data-field="licenses_count" data-sortable="true">
|
|
<i class="far fa-save" aria-hidden="true"></i>
|
|
<span class="sr-only">{{ trans('general.licenses_count') }}</span>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div> <!-- /.col -->
|
|
<div class="text-center col-md-12" style="padding-top: 10px;">
|
|
<a href="{{ route('categories.index') }}" class="btn btn-primary btn-sm" style="width: 100%">{{ trans('general.viewall') }}</a>
|
|
</div>
|
|
</div> <!-- /.row -->
|
|
|
|
</div><!-- /.box-body -->
|
|
</div> <!-- /.box -->
|
|
</div>
|
|
</div>
|
|
|
|
@endif
|
|
|
|
|
|
@stop
|
|
|
|
@section('moar_scripts')
|
|
@include ('partials.bootstrap-table', ['simple_view' => true, 'nopages' => true])
|
|
@stop
|
|
|
|
@push('js')
|
|
|
|
|
|
|
|
<script nonce="{{ csrf_token() }}">
|
|
// ---------------------------
|
|
// - ASSET STATUS CHART -
|
|
// ---------------------------
|
|
var pieChartCanvas = $("#statusPieChart").get(0).getContext("2d");
|
|
var pieChart = new Chart(pieChartCanvas);
|
|
var ctx = document.getElementById("statusPieChart");
|
|
var pieOptions = {
|
|
legend: {
|
|
position: 'top',
|
|
responsive: true,
|
|
maintainAspectRatio: true,
|
|
},
|
|
tooltips: {
|
|
callbacks: {
|
|
label: function(tooltipItem, data) {
|
|
counts = data.datasets[0].data;
|
|
total = 0;
|
|
for(var i in counts) {
|
|
total += counts[i];
|
|
}
|
|
prefix = data.labels[tooltipItem.index] || '';
|
|
return prefix+" "+Math.round(counts[tooltipItem.index]/total*100)+"%";
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
$.ajax({
|
|
type: 'GET',
|
|
url: '{{ (\App\Models\Setting::getSettings()->dash_chart_type == 'name') ? route('api.statuslabels.assets.byname') : route('api.statuslabels.assets.bytype') }}',
|
|
headers: {
|
|
"X-Requested-With": 'XMLHttpRequest',
|
|
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content')
|
|
},
|
|
dataType: 'json',
|
|
success: function (data) {
|
|
var myPieChart = new Chart(ctx,{
|
|
type : 'pie',
|
|
data : data,
|
|
options: pieOptions
|
|
});
|
|
},
|
|
error: function (data) {
|
|
// window.location.reload(true);
|
|
},
|
|
});
|
|
var last = document.getElementById('statusPieChart').clientWidth;
|
|
addEventListener('resize', function() {
|
|
var current = document.getElementById('statusPieChart').clientWidth;
|
|
if (current != last) location.reload();
|
|
last = current;
|
|
});
|
|
</script>
|
|
@endpush
|