Compare commits

...

19 commits

Author SHA1 Message Date
c0a1da23ec save 2025-04-30 21:32:48 +02:00
snipe
049a669186 Merge remote-tracking branch 'origin/develop' 2025-04-30 16:46:16 +01:00
snipe
a0358e32d7 Removed escaping
Signed-off-by: snipe <snipe@snipe.net>
2025-04-30 16:46:06 +01:00
snipe
d29f13bae9 Merge remote-tracking branch 'origin/develop' 2025-04-30 16:26:38 +01:00
snipe
c2023c5c56 Ampersand showing in Custom fields [sc-29051]
Signed-off-by: snipe <snipe@snipe.net>
2025-04-30 16:25:44 +01:00
snipe
c758355df9 Merge remote-tracking branch 'origin/develop' 2025-04-30 16:14:34 +01:00
snipe
43c310c82d
Merge pull request #16531 from akemidx/bug/sc-28715
FIXED: Purchase Cost Column Always Shown
2025-04-30 15:54:31 +01:00
snipe
79d97a83af Merge remote-tracking branch 'origin/develop' 2025-04-30 15:48:38 +01:00
snipe
939a0c44dc
Merge pull request #16826 from Godmartinz/fix_multiple_inline_label_field_options
Reworked fix for for 24mm_D label indent errror
2025-04-30 15:47:57 +01:00
snipe
85bd47c240 Merge remote-tracking branch 'origin/develop' 2025-04-30 15:35:10 +01:00
snipe
2b9cf1663b
Merge pull request #16837 from grokability/fmcs_scoping_improvements
Small improvements to scoped views
2025-04-30 15:33:53 +01:00
snipe
0a29e90701 Smal improvements to scoping displays
Signed-off-by: snipe <snipe@snipe.net>
2025-04-30 15:24:42 +01:00
snipe
d1be13e7d4 Added button text to translations
Signed-off-by: snipe <snipe@snipe.net>
2025-04-30 14:32:29 +01:00
snipe
049a777ca8 Added buttons to dashboard
Signed-off-by: snipe <snipe@snipe.net>
2025-04-30 14:32:20 +01:00
snipe
0dcaa83a3e Nicer breadcrumb
Signed-off-by: snipe <snipe@snipe.net>
2025-04-30 14:22:13 +01:00
snipe
db706269e6 Fixed validation message
Signed-off-by: snipe <snipe@snipe.net>
2025-04-30 14:22:06 +01:00
Godfrey M
2e0913bb3b remove unused method 2025-04-29 10:49:19 -07:00
Godfrey M
851ae46ea9 reworked fix for for 24mm_D label indent errior 2025-04-29 10:45:29 -07:00
akemidx
e408b902f0 removing depreciation from purchase cost (unneeded, should go elsewhere if wanted) 2025-03-18 16:38:44 -04:00
18 changed files with 90 additions and 41 deletions

View file

@ -26,6 +26,10 @@
"description": "URL where your Snipe-IT install will be available at.",
"value": "https://your-app-name.herokuapp.com"
},
"LABEL_URL": {
"description": "Labels",
"value": "https://your-app-name.herokuapp.com"
},
"APP_TIMEZONE": {
"description": "Which timezone do you want to use for your install? (http://php.net/manual/en/timezones.php)",
"value": "UTC"

View file

@ -5,6 +5,8 @@ namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Transformers\ActionlogsTransformer;
use App\Models\Actionlog;
use App\Models\Company;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
@ -18,10 +20,11 @@ class ReportsController extends Controller
*/
public function index(Request $request) : JsonResponse | array
{
$this->authorize('reports.view');
$this->authorize('activity.view');
$actionlogs = Actionlog::with('item', 'user', 'adminuser', 'target', 'location');
if ($request->filled('search')) {
$actionlogs = $actionlogs->TextSearch(e($request->input('search')));
}

View file

@ -238,8 +238,8 @@ class CustomFieldsController extends Controller
$display_in_user_view = '0';
}
$field->name = trim(e($request->get("name")));
$field->element = e($request->get("element"));
$field->name = trim($request->get("name"));
$field->element = $request->get("element");
$field->field_values = $request->get("field_values");
$field->created_by = auth()->id();
$field->help_text = $request->get("help_text");
@ -254,9 +254,9 @@ class CustomFieldsController extends Controller
$field->display_audit = $request->get("display_audit", 0);
if ($request->get('format') == 'CUSTOM REGEX') {
$field->format = e($request->get('custom_format'));
$field->format = $request->get('custom_format');
} else {
$field->format = e($request->get('format'));
$field->format = $request->get('format');
}
if ($field->element == 'checkbox' || $field->element == 'radio'){

View file

@ -485,7 +485,7 @@ class ReportsController extends Controller
$header[] = trans('admin/hardware/table.purchase_date');
}
if (($request->filled('purchase_cost')) || ($request->filled('depreciation'))) {
if ($request->filled('purchase_cost')) {
$header[] = trans('admin/hardware/table.purchase_cost');
}

View file

@ -70,27 +70,38 @@ class TZe_24mm_D extends TZe_24mm
}
foreach ($record->get('fields') as $field) {
// Write label and value on the same line
// Calculate label width with proportional character spacing
$labelWidth = $pdf->GetStringWidth($field['label'], 'freemono', '', self::LABEL_SIZE);
$charCount = strlen($field['label']);
$spacingPerChar = 0.5;
$totalSpacing = $charCount * $spacingPerChar;
$adjustedWidth = $labelWidth + $totalSpacing;
if (!empty($field['label']) && $field['label'] !== "\u{200B}") {
// Write label and value on the same line
// Calculate label width with proportional character spacing
$labelWidth = $pdf->GetStringWidth($field['label'], 'freemono', '', self::LABEL_SIZE);
$charCount = strlen($field['label']);
$spacingPerChar = 0.5;
$totalSpacing = $charCount * $spacingPerChar;
$adjustedWidth = $labelWidth + $totalSpacing;
static::writeText(
$pdf, $field['label'],
$currentX, $currentY,
'freemono', 'B', self::LABEL_SIZE, 'L',
$adjustedWidth, self::LABEL_SIZE, true, 0, $spacingPerChar
);
static::writeText(
$pdf, $field['label'],
$currentX, $currentY,
'freemono', 'B', self::LABEL_SIZE, 'L',
$adjustedWidth, self::LABEL_SIZE, true, 0, $spacingPerChar
);
static::writeText(
$pdf, $field['value'],
$currentX + $adjustedWidth + 2, $currentY,
'freemono', 'B', self::FIELD_SIZE, 'L',
$usableWidth - $adjustedWidth - 2, self::FIELD_SIZE, true, 0, 0.3
);
static::writeText(
$pdf, $field['value'],
$currentX + $adjustedWidth + 2, $currentY,
'freemono', 'B', self::FIELD_SIZE, 'L',
$usableWidth - $adjustedWidth - 2, self::FIELD_SIZE, true, 0, 0.3
);
} else {
// Label is empty, so write value only.
static::writeText(
$pdf, $field['value'],
$currentX, $currentY, // No offset
'freemono', 'B', self::FIELD_SIZE, 'L',
$usableWidth, self::FIELD_SIZE, true, 0, 0.3
);
}
$currentY += max(self::LABEL_SIZE, self::FIELD_SIZE) + self::FIELD_MARGIN;
}

View file

@ -33,7 +33,7 @@ class LocationPresenter extends Presenter
'switchable' => true,
'title' => trans('general.company'),
'visible' => false,
'formatter' => 'locationCompanyObjFilterFormatter'
'formatter' => 'companiesLinkObjFormatter'
],
[
'field' => 'name',

View file

@ -168,6 +168,15 @@ class AuthServiceProvider extends ServiceProvider
}
});
// -----------------------------------------
// Activity
// -----------------------------------------
Gate::define('activity.view', function ($user) {
if (($user->hasAccess('reports.view')) || ($user->hasAccess('admin'))) {
return true;
}
});
// -----------------------------------------
// Self
// -----------------------------------------

View file

@ -385,6 +385,7 @@ class BreadcrumbsServiceProvider extends ServiceProvider
Breadcrumbs::for('locations.edit', fn (Trail $trail, Location $location) =>
$trail->parent('locations.index', route('locations.index'))
->push($location->name, route('locations.show', $location))
->push(trans('general.breadcrumb_button_actions.edit_item', ['name' => $location->name]), route('locations.edit', $location))
);

View file

@ -142,6 +142,9 @@ class Label implements View
case 'location':
$barcode2DTarget = route('locations.show', $asset->location_id);
break;
case 'custom_url_hardware_id':
$barcode2DTarget = route('hardware.show', $asset);
break;
case 'hardware_id':
default:
$barcode2DTarget = route('hardware.show', $asset);
@ -177,10 +180,13 @@ class Label implements View
// The end result of this will be in this format:
// {labelOne} {valueOne} | {labelTwo} {valueTwo} | {labelThree} {valueThree}
$previous['value'] = trim(implode(' | ', [
implode(' ', [null, $previous['value']]),
implode(' ', [$previous['label'], $previous['value']]),
implode(' ', [$current['label'], $current['value']]),
]));
// We'll set the label to an empty string since we
// injected the label into the value field above.
$previous['label'] = '';
return $previous;
});

View file

@ -74,6 +74,7 @@ return [
*/
'url' => env('APP_URL', 'http://localhost'),
'label_url' => env('LABEL_URL', 'http://localhost'),
/*
|--------------------------------------------------------------------------

View file

@ -390,6 +390,8 @@ return [
'new_license' => 'New License',
'new_accessory' => 'New Accessory',
'new_consumable' => 'New Consumable',
'new_component' => 'New Component',
'new_user' => 'New User',
'collapse' => 'Collapse',
'assigned' => 'Assigned',
'asset_count' => 'Asset Count',

View file

@ -172,6 +172,7 @@ return [
'url' => 'The :attribute field must be a valid URL.',
'ulid' => 'The :attribute field must be a valid ULID.',
'uuid' => 'The :attribute field must be a valid UUID.',
'fmcs_location' => 'Full multiple company support and location scoping is enabled in the Admin Settings, and the selected location and selected company are not compatible.',
/*

View file

@ -172,26 +172,36 @@
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="col-md-2">
@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">
<div class="col-md-2">
@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">
<div class="col-md-2">
@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">
<div class="col-md-2">
@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 class="col-md-2">
@can('create', \App\Models\Component::class)
<a class="btn bg-yellow" style="width: 100%" href="{{ route('components.create') }}">{{ trans('general.new_component') }}</a>
@endcan
</div>
<div class="col-md-2">
@can('create', \App\Models\User::class)
<a class="btn bg-light-blue" style="width: 100%" href="{{ route('users.create') }}">{{ trans('general.new_user') }}</a>
@endcan
</div>
</div>
</div>
</div>
@ -282,7 +292,7 @@
<div class="row">
<div class="col-md-6">
@if ($snipeSettings->full_multiple_companies_support=='1')
@if ((($snipeSettings->scope_locations_fmcs!='1') && ($snipeSettings->full_multiple_companies_support=='1')))
<!-- Companies -->
<div class="box box-default">
<div class="box-header with-border">

View file

@ -217,7 +217,7 @@
$.ajax({
type: 'GET',
url: "{{ config('app.url') }}/models/" + modelid + "/custom_fields",
url: "{{ config('app.label_url') }}/models/" + modelid + "/custom_fields",
headers: {
"X-Requested-With": 'XMLHttpRequest',
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content')
@ -260,7 +260,7 @@
if (status_id != '') {
$(".status_spinner").css("display", "inline");
$.ajax({
url: "{{config('app.url') }}/api/v1/statuslabels/" + status_id + "/deployable",
url: "{{config('app.label_url') }}/api/v1/statuslabels/" + status_id + "/deployable",
headers: {
"X-Requested-With": 'XMLHttpRequest',
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content')

View file

@ -112,7 +112,7 @@ $qr_size = ($settings->alt_barcode_enabled=='1') && ($settings->label2_1d_type!=
@if ($settings->qr_code=='1')
<div class="qr_img">
<img src="{{ config('app.url') }}/hardware/{{ $asset->id }}/qr_code" class="qr_img">
<img src="{{ config('app.label_url') }}/hardware/{{ $asset->id }}/qr_code" class="qr_img">
</div>
@endif
@ -158,7 +158,7 @@ $qr_size = ($settings->alt_barcode_enabled=='1') && ($settings->label2_1d_type!=
@if ((($settings->alt_barcode_enabled=='1') && $settings->label2_1d_type!=''))
<div class="barcode_container">
<img src="{{ config('app.url') }}/hardware/{{ $asset->id }}/barcode" class="barcode">
<img src="{{ config('app.label_url') }}/hardware/{{ $asset->id }}/barcode" class="barcode">
</div>
@endif

View file

@ -276,7 +276,7 @@
function genericRowLinkFormatter(destination) {
return function (value,row) {
if (value) {
return '<a href="{{ config('app.url') }}/' + destination + '/' + row.id + '">' + value + '</a>';
return '<a href="{{ config('app.label_url') }}/' + destination + '/' + row.id + '">' + value + '</a>';
}
};
}
@ -318,7 +318,7 @@
text_help = '';
}
return '<nobr><a href="{{ config('app.url') }}/' + destination + '/' + value.id + '" data-tooltip="true" title="'+ status_meta[value.status_meta] + '"> <i class="fa ' + icon_style + ' text-' + text_color + '"></i> ' + value.name + ' ' + text_help + ' </a> </nobr>';
return '<nobr><a href="{{ config('app.label_url') }}/' + destination + '/' + value.id + '" data-tooltip="true" title="'+ status_meta[value.status_meta] + '"> <i class="fa ' + icon_style + ' text-' + text_color + '"></i> ' + value.name + ' ' + text_help + ' </a> </nobr>';
} else if ((value) && (value.name)) {
// Add some overrides for any funny urls we have
@ -328,7 +328,7 @@
var dpolymorphicItemFormatterest = 'fields/';
}
return '<nobr><a href="{{ config('app.url') }}/' + dpolymorphicItemFormatterest + dest + '/' + value.id + '">' + value.name + '</a></span>';
return '<nobr><a href="{{ config('app.label_url') }}/' + dpolymorphicItemFormatterest + dest + '/' + value.id + '">' + value.name + '</a></span>';
}
};
}
@ -341,7 +341,7 @@
function hardwareAuditFormatter(value, row) {
return '<a href="{{ config('app.url') }}/hardware/' + row.id + '/audit" class="btn btn-sm bg-yellow" data-tooltip="true" title="Audit this item">{{ trans('general.audit') }}</a>';
return '<a href="{{ config('app.label_url') }}/hardware/' + row.id + '/audit" class="btn btn-sm bg-yellow" data-tooltip="true" title="Audit this item">{{ trans('general.audit') }}</a>';
}

View file

@ -303,6 +303,7 @@
id="label2_2d_target"
:options="['hardware_id'=>'/hardware/{id} ('.trans('admin/settings/general.default').')',
'ht_tag'=>'/ht/{asset_tag}',
'custom_url_hardware_id'=>'/hardware/{id}',
'location' => '/location/{location_id}',
]"
:selected="old('label2_2d_target', $setting->label2_2d_target)"

View file

@ -91,7 +91,7 @@
function statuslabelsAssetLinkFormatter(value, row) {
if ((row) && (row.name)) {
return '<a href="{{ config('app.url') }}/hardware/?status_id=' + row.id + '"> ' + row.name + '</a>';
return '<a href="{{ config('app.label_url') }}/hardware/?status_id=' + row.id + '"> ' + row.name + '</a>';
}
}