ikinci temizlik tamamlandı
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
<table
|
||||
data-toggle="table"
|
||||
data-url="data1.json">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach($columnsList AS $column) { ?>
|
||||
<th data-field="{{$column['name']}}">{{e2($column['name'])}}</th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{{$listDatas->appends($_GET)->links()}}
|
||||
</div>
|
||||
<div class="col-md-6 ">
|
||||
<?php if(getisset("filter")) {
|
||||
|
||||
foreach($get AS $getColumn => $getValues) {
|
||||
?>
|
||||
<div class="btn btn-sm btn-outline-primary"><i class="fa fa-filter"></i> {{e2($getColumn)}} {{implode(', ', $getValues)}}</div>
|
||||
<?php
|
||||
/*
|
||||
foreach($getValues AS $getValue) {
|
||||
?>
|
||||
<div class="btn btn-sm btn-outline-primary"><i class="fa fa-times"></i> {{$getColumn}} : {{$getValue}}</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<a href="{{url('admin/types/' . $id)}}" class="btn btn-danger btn-sm float-right"><i class="fa fa-trash"></i> {{e2("Clear All Filter")}}</a>
|
||||
|
||||
<?php
|
||||
} ?>
|
||||
</div>
|
||||
</div>
|
||||
<a name="table"></a>
|
||||
<div class="table-responsive mt-10 mb-10">
|
||||
|
||||
|
||||
<script>
|
||||
$(function(){
|
||||
$("#data-table").DataTable({
|
||||
fixedHeader: {
|
||||
header: true,
|
||||
footer: true
|
||||
},
|
||||
|
||||
scrollX: true,
|
||||
|
||||
responsive: true,
|
||||
stateSave: true,
|
||||
pageLength: {{setting('row_count')}}
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<table id="data-table" style="table-layout:fixed;width:{{$tableWidth}}" class=" table table-sm table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="table-dark">
|
||||
<form action="#table" method="get">
|
||||
<input type="hidden" name="filter" value="ok">
|
||||
<?php if(isset($prependColumns)) {
|
||||
foreach($prependColumns AS $columnName => $columnArray) {
|
||||
?>
|
||||
<th data-resizable-column-id="{{str_slug($columnName)}}">{{e2($columnName)}}
|
||||
|
||||
</th>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
<?php foreach($columns AS $column) { ?>
|
||||
<th class="position-relative" data-resizable-column-id="{{str_slug($column)}}">{{e2($column)}}
|
||||
<?php if(isset($tableDifferentValues[$column])) {
|
||||
?>
|
||||
<div class="dropdown filter-list">
|
||||
<button class="btn btn-secondary btn-sm text-white float-right dropdown-toggle" type="button" id="{{str_slug($column)}}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fa fa-filter d-none"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="{{str_slug($column)}}">
|
||||
<?php foreach($tableDifferentValues[$column] AS $tableDifferentValue) {
|
||||
?>
|
||||
<label class="dropdown-item" href="#">
|
||||
<input type="checkbox"
|
||||
<?php if(getisset($column)) {
|
||||
if(in_array($tableDifferentValue, $_GET[$column])) {
|
||||
echo "checked";
|
||||
}
|
||||
} ?>
|
||||
name="{{$column}}[]" value="{{$tableDifferentValue}}"> {{$tableDifferentValue}}
|
||||
</label>
|
||||
<?php } ?>
|
||||
|
||||
<button class="btn btn-outline-primary btn-sm">{{e2("Filter")}}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</th>
|
||||
<?php } ?>
|
||||
<?php if(!isset($summaryTable)) { ?>
|
||||
<th data-resizable-column-id="opt">{{e2("Opt")}}</th>
|
||||
<?php } ?>
|
||||
</form>
|
||||
</tr>
|
||||
<?php if(!isset($summaryTable)) { ?>
|
||||
<?php $rowName = "new-tr"; ?>
|
||||
<tr class="table-warning {{$rowName}}">
|
||||
|
||||
<form action="{{url("admin/create/$tableName")}}" method="post">
|
||||
@csrf
|
||||
<?php if(isset($prependColumns)) {
|
||||
foreach($prependColumns AS $columnName => $columnArray) {
|
||||
?>
|
||||
<td>#</td>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
<td>#</td>
|
||||
<?php foreach($columnsList AS $column) { ?>
|
||||
<td>
|
||||
|
||||
@include("components.columns.{$column['type']}")
|
||||
</td>
|
||||
<?php } ?>
|
||||
<td><button class="btn btn-outline-success btn-sm"><i class="fa fa-plus"></i></button></td>
|
||||
</form>
|
||||
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php foreach($listDatas AS $listData) {
|
||||
$rowName = "row" . $listData->id;
|
||||
?>
|
||||
<tr id="t{{$listData->id}}" data-row="{{$rowName}}">
|
||||
<?php if(isset($prependColumns)) {
|
||||
foreach($prependColumns AS $columnName => $columnArray) { ?>
|
||||
<td data-resizable-column-id="{{str_slug($columnName)}}">
|
||||
@include("components.prepend-columns.{$columnArray['type']}")
|
||||
</td>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
<?php if(!in_array("id", $excepts)) {
|
||||
?>
|
||||
<td>{{$listData->id}}</td>
|
||||
<?php } ?>
|
||||
<?php foreach($columnsList AS $column) { ?>
|
||||
<td>
|
||||
<?php if(!isset($summaryTable)) {
|
||||
?>
|
||||
<?php if(isset($onlyShowColumn)) {
|
||||
$thisColumnName = $column['name'];
|
||||
?>
|
||||
{{$listData->$thisColumnName}}
|
||||
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
@include("components.columns.{$column['type']}")
|
||||
<?php
|
||||
} ?>
|
||||
|
||||
<?php } else {
|
||||
$thisColumnName = $column['name'];
|
||||
?>
|
||||
{{$listData->$thisColumnName}}
|
||||
<?php
|
||||
} ?>
|
||||
</td>
|
||||
<?php } ?>
|
||||
<?php if(!isset($summaryTable)) { ?>
|
||||
<td>
|
||||
<a href="{{url("admin/delete/$tableName/{$listData->id}")}}" ajax="#t{{$listData->id}}" {{delete_teyit()}} class="btn btn-outline-danger btn-sm"><i class="fa fa-remove"></i></a>
|
||||
</td>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
<?php
|
||||
} ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
{{$listDatas->appends($_GET)->links()}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,229 @@
|
||||
<?php if(isset($blockGroup)) {
|
||||
$blockGroupColumns = [];
|
||||
|
||||
foreach($blockGroup AS $blockTitle => $columns) {
|
||||
foreach($columns AS $column) {
|
||||
$blockGroupColumns[] = $column;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
{{$listDatas->appends($_GET)->links()}}
|
||||
</div>
|
||||
<div class="col-md-6 ">
|
||||
<?php if(getisset("filter")) {
|
||||
|
||||
foreach($get AS $getColumn => $getValues) {
|
||||
?>
|
||||
<div class="btn btn-sm btn-outline-primary"><i class="fa fa-filter"></i> {{e2($getColumn)}} {{implode(', ', $getValues)}}</div>
|
||||
<?php
|
||||
/*
|
||||
foreach($getValues AS $getValue) {
|
||||
?>
|
||||
<div class="btn btn-sm btn-outline-primary"><i class="fa fa-times"></i> {{$getColumn}} : {{$getValue}}</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<a href="{{url('admin/types/' . $id)}}" class="btn btn-danger btn-sm float-right"><i class="fa fa-trash"></i> {{e2("Clear All Filter")}}</a>
|
||||
|
||||
<?php
|
||||
} ?>
|
||||
</div>
|
||||
</div>
|
||||
<a name="table"></a>
|
||||
<div class="table-responsive mt-10 mb-10">
|
||||
<table style="table-layout:fixed;width:{{$tableWidth}}" class=" table table-sm table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr class="table-light">
|
||||
<form action="#table" method="get">
|
||||
<input type="hidden" name="filter" value="ok">
|
||||
<?php if(isset($prependColumns)) {
|
||||
foreach($prependColumns AS $columnName => $columnArray) {
|
||||
?>
|
||||
<th data-resizable-column-id="{{str_slug($columnName)}}">{{e2($columnName)}}
|
||||
|
||||
</th>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
<th>{{e2("ID")}}</th>
|
||||
<?php
|
||||
|
||||
foreach($columnsList AS $column) {
|
||||
$column = $column['name'];
|
||||
$show = true;
|
||||
if(isset($blockGroupColumns)) {
|
||||
if(!in_array($column, $blockGroupColumns)) $show=false;
|
||||
}
|
||||
if($show) {
|
||||
|
||||
?>
|
||||
<th class="position-relative" data-resizable-column-id="{{str_slug($column)}}">{{e2($column)}}
|
||||
<?php if(isset($tableDifferentValues[$column])) {
|
||||
?>
|
||||
<div class="dropdown filter-list">
|
||||
<button class="btn btn-secondary btn-sm text-dark float-right dropdown-toggle" type="button" id="{{str_slug($column)}}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fa fa-filter d-none"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="{{str_slug($column)}}">
|
||||
<input type="text" placeholder="{{e2("Search")}}" class="form-control search">
|
||||
<div class="dropdown-sublist">
|
||||
<?php foreach($tableDifferentValues[$column] AS $tableDifferentValue) {
|
||||
?>
|
||||
<label class="dropdown-item" href="#">
|
||||
<input type="checkbox"
|
||||
<?php if(getisset($column)) {
|
||||
if(in_array($tableDifferentValue, $_GET[$column])) {
|
||||
echo "checked";
|
||||
}
|
||||
} ?>
|
||||
name="{{$column}}[]" value="{{$tableDifferentValue}}"> {{$tableDifferentValue}}
|
||||
</label>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-outline-primary btn-sm">{{e2("Filter")}}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</th>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php if(!isset($summaryTable)) { ?>
|
||||
<th data-resizable-column-id="opt">{{e2("Opt")}}</th>
|
||||
<?php } ?>
|
||||
</form>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<?php if(!isset($summaryTable)) { ?>
|
||||
<?php $rowName = "new-tr"; ?>
|
||||
<tr class="table-warning {{$rowName}}">
|
||||
|
||||
<form action="{{url("admin/create/$tableName")}}" method="post">
|
||||
@csrf
|
||||
<?php if(isset($prependColumns)) {
|
||||
foreach($prependColumns AS $columnName => $columnArray) {
|
||||
?>
|
||||
<td>#</td>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
<td>#</td>
|
||||
<?php foreach($columnsList AS $column) {
|
||||
$show = true;
|
||||
if(isset($blockGroupColumns)) {
|
||||
if(!in_array($column['name'], $blockGroupColumns)) $show=false;
|
||||
}
|
||||
if($show) {
|
||||
|
||||
?>
|
||||
<td>
|
||||
|
||||
@include("components.columns.{$column['type']}")
|
||||
</td>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<td><button class="btn btn-outline-success btn-sm"><i class="fa fa-plus"></i></button></td>
|
||||
</form>
|
||||
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tbody>
|
||||
<?php foreach($listDatas AS $listData) {
|
||||
$rowName = "row" . $listData->id;
|
||||
?>
|
||||
<tr id="t{{$listData->id}}" data-row="{{$rowName}}">
|
||||
<?php if(isset($prependColumns)) {
|
||||
foreach($prependColumns AS $columnName => $columnArray) { ?>
|
||||
<td data-resizable-column-id="{{str_slug($columnName)}}">
|
||||
@include("components.prepend-columns.{$columnArray['type']}")
|
||||
</td>
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
<?php if(!in_array("id", $excepts)) {
|
||||
?>
|
||||
<td class="id">{{$listData->id}}</td>
|
||||
<?php } ?>
|
||||
<?php foreach($columnsList AS $column) {
|
||||
|
||||
$show = true;
|
||||
if(isset($blockGroupColumns)) {
|
||||
if(!in_array($column['name'], $blockGroupColumns)) $show=false;
|
||||
}
|
||||
if($show) {
|
||||
|
||||
?>
|
||||
<td>
|
||||
<?php if(!isset($summaryTable)) {
|
||||
?>
|
||||
<?php if(isset($onlyShowColumn)) {
|
||||
$thisColumnName = $column['name'];
|
||||
?>
|
||||
{{$listData->$thisColumnName}}
|
||||
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
@include("components.columns.{$column['type']}")
|
||||
<?php
|
||||
} ?>
|
||||
|
||||
<?php } else {
|
||||
$thisColumnName = $column['name'];
|
||||
?>
|
||||
{{$listData->$thisColumnName}}
|
||||
<?php
|
||||
} ?>
|
||||
</td>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php if(!isset($summaryTable)) { ?>
|
||||
<td>
|
||||
<a href="{{url("admin/delete/$tableName/{$listData->id}")}}" ajax="#t{{$listData->id}}" {{delete_teyit()}} class="btn btn-outline-danger btn-sm"><i class="fa fa-remove"></i></a>
|
||||
</td>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
<?php
|
||||
} ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
{{$listDatas->appends($_GET)->links()}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
$(".filter-list .search").on("keyup", function(){
|
||||
var bu = $(this);
|
||||
var parent = bu.parent().parent();
|
||||
var value = $(this).val().toLowerCase();
|
||||
parent.find('.dropdown-sublist .dropdown-item').filter(function() {
|
||||
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
|
||||
});
|
||||
|
||||
});
|
||||
$("table tbody .id").on("dblclick", function(){
|
||||
var id = $(this).text();
|
||||
location.href="?{!! http_build_query($_GET) !!}&detail=" + id;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,197 @@
|
||||
|
||||
<style>
|
||||
thead {
|
||||
background: #fff;
|
||||
}
|
||||
tbody td:hover {
|
||||
outline: solid 1px #33dbf9;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<table class="table table-bordered table-striped table-vcenter data-tables table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<?php foreach($columnsList AS $column) { ?>
|
||||
<th class="text-center"
|
||||
data-name="{{$column['name']}}"
|
||||
data-type="{{$column['type']}}"
|
||||
data-relation="{{json_encode_tr($column['relation'])}}"
|
||||
>{{e2($column['name'])}}</th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<?php foreach($columns AS $column) { ?>
|
||||
<th class="text-center"></th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
|
||||
<script src="{{url("assets/admin/data-tables/fixed-header/js/dataTables.fixedHeader.min.js")}}"></script>
|
||||
<script src="{{url("assets/admin/data-tables/editor.js")}}"></script>
|
||||
|
||||
<?php // dump($columnsList) ?>
|
||||
|
||||
<script>
|
||||
var editor;
|
||||
$(document).ready(function(){
|
||||
/*
|
||||
window.setTimeout(function(){
|
||||
editor = new $.fn.dataTable.Editor( {
|
||||
ajax: "../php/staff.php",
|
||||
table: "#edit",
|
||||
fields: [ {
|
||||
label: "First name:",
|
||||
name: "first_name"
|
||||
}, {
|
||||
label: "Last name:",
|
||||
name: "last_name"
|
||||
}, {
|
||||
label: "Position:",
|
||||
name: "position"
|
||||
}, {
|
||||
label: "Office:",
|
||||
name: "office"
|
||||
}, {
|
||||
label: "Extension:",
|
||||
name: "extn"
|
||||
}, {
|
||||
label: "Start date:",
|
||||
name: "start_date",
|
||||
type: "datetime"
|
||||
}, {
|
||||
label: "Salary:",
|
||||
name: "salary"
|
||||
}
|
||||
]
|
||||
} );
|
||||
},2000);
|
||||
*/
|
||||
|
||||
var table = $('.data-tables').DataTable({
|
||||
ajax: '{{url("admin/to-json/". $tableName)}}',
|
||||
|
||||
fixedHeader: {
|
||||
header: true,
|
||||
footer: true
|
||||
},
|
||||
scrollY: "50vh",
|
||||
scrollX: true,
|
||||
/*
|
||||
dom: 'Bfrtip',
|
||||
buttons: [
|
||||
{
|
||||
text: '{{e2("Clear State")}}',
|
||||
action: function ( e, dt, node, config ) {
|
||||
table.state.clear();
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
],
|
||||
*/
|
||||
responsive: true,
|
||||
// "scrollX": true,
|
||||
stateSave: true,
|
||||
initComplete: function () {
|
||||
this.api()
|
||||
.columns()
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $('<select class="form-control"><option value=""></option></select>')
|
||||
.appendTo($(column.footer()).empty())
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append('<option value="' + d + '">' + d + '</option>');
|
||||
});
|
||||
|
||||
});
|
||||
// select.select2();
|
||||
},
|
||||
});
|
||||
|
||||
table.on("dblclick", 'tr td:first-child', function(){
|
||||
var id = $(this).text();
|
||||
location.href="?detail=" + id;
|
||||
});
|
||||
table.on( 'mouseover', 'tbody td:not(:first-child):not(.edited)', function (e) {
|
||||
init($(this));
|
||||
});
|
||||
|
||||
/*
|
||||
table.on( 'dblclick', 'tbody td:not(:first-child):not(.edited)', function (e) {
|
||||
|
||||
var that = $(this);
|
||||
var index = that.index();
|
||||
var column = $(".data-tables").find("th:eq("+index+")");
|
||||
var type = column.attr("data-type");
|
||||
var name = column.attr("data-name");
|
||||
var id = that.parent().find("td:eq(0)").text();
|
||||
var relation = JSON.parse(column.attr("data-relation"));
|
||||
|
||||
that.addClass("edited");
|
||||
|
||||
$.post('?ajax=click-edit', {
|
||||
'_token' : "{{csrf_token()}}",
|
||||
'id' : id,
|
||||
'type' : type,
|
||||
'name' : name,
|
||||
'table_name' : "{{$tableName}}",
|
||||
// 'relation' : JSON.stringify(relation),
|
||||
}, function(d) {
|
||||
that.html(d);
|
||||
|
||||
});
|
||||
|
||||
|
||||
} );
|
||||
*/
|
||||
table.on( 'dblclick', 'tbody td:not(:first-child):not(.edited)', function (e) {
|
||||
|
||||
var that = $(this);
|
||||
var index = that.index();
|
||||
var column = $(".data-tables").find("th:eq("+index+")");
|
||||
var type = column.attr("data-type");
|
||||
var name = column.attr("data-name");
|
||||
var id = that.parent().find("td:eq(0)").text();
|
||||
var relation = JSON.parse(column.attr("data-relation"));
|
||||
|
||||
that.addClass("edited");
|
||||
// editor.inline( this );
|
||||
|
||||
} );
|
||||
|
||||
|
||||
$(".dt-button").addClass("btn");
|
||||
$(".dt-button").addClass("btn-primary");
|
||||
|
||||
var clearStateButton = $('<div class="btn-block-option" id="clear-state" title="{{e2("Clear Table State")}}"><i class="fa fa-refresh"></i></div>');
|
||||
|
||||
$(".block-options").append(clearStateButton);
|
||||
|
||||
$(".block-options").on("click", "#clear-state", function() {
|
||||
console.log("ok");
|
||||
table.state.clear();
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php $path = "components.table.datagrid";
|
||||
|
||||
|
||||
$u = u();
|
||||
$inspectionHistoryActive = $inspectionHistoryActive ?? false;
|
||||
|
||||
// Resolve module slug/id if not passed directly
|
||||
if(!isset($moduleSlug)) {
|
||||
$moduleSlug = isset($c) ? $c->slug : (isset($type) && is_object($type) ? $type->slug : null);
|
||||
}
|
||||
if(!isset($moduleId)) {
|
||||
$moduleId = isset($c) ? $c->id : (isset($type) && is_object($type) ? $type->id : null);
|
||||
}
|
||||
|
||||
if(function_exists('getInspectionHistoryConfig') && $moduleSlug) {
|
||||
$inspectionConfig = getInspectionHistoryConfig($moduleSlug);
|
||||
if ($inspectionConfig && ($inspectionConfig['active'] ?? false)) {
|
||||
$inspectionHistoryActive = true;
|
||||
|
||||
$inspectionRowIds = \App\Models\InspectionHistory::where('table_name', $tableName)
|
||||
->distinct()
|
||||
->pluck('record_id')
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
$selectedColumns = $columns;
|
||||
if(isset($_SESSION['select-columns'][$tableName])) {
|
||||
$selectedColumns = $_SESSION['select-columns'][$tableName];
|
||||
}
|
||||
|
||||
if(isset($blockGroup)) {
|
||||
$blockGroupColumns = [];
|
||||
$blockGroupMap = [];
|
||||
foreach($blockGroup AS $blockTitle => $columns) {
|
||||
$translatedTitle = e2($blockTitle);
|
||||
foreach($columns AS $column) {
|
||||
$blockGroupColumns[] = $column;
|
||||
$blockGroupMap[$column] = $translatedTitle;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$absoluteReadableModules = [
|
||||
'spool-area-release',
|
||||
'weldlog-employer-view'
|
||||
];
|
||||
$enableMechanicalControls = isset($enableMechanicalControls) ? (bool) $enableMechanicalControls : false;
|
||||
$showMechanicalNdtPlaceholder = isset($showMechanicalNdtPlaceholder) ? (bool) $showMechanicalNdtPlaceholder : false;
|
||||
$mechanicalNdtFields = isset($mechanicalNdtFields) && is_array($mechanicalNdtFields) ? $mechanicalNdtFields : [
|
||||
'ndt','rt_scope','ut_scope','mt_scope','pt_scope','pmi_scope','ht_scope','pwht','pwht_field'
|
||||
];
|
||||
$weldedSummaryFilter = isset($excludeMechanicalFromSummaries) && $excludeMechanicalFromSummaries;
|
||||
$shouldLoadMechanicalTypes = $enableMechanicalControls || $weldedSummaryFilter || $showMechanicalNdtPlaceholder;
|
||||
$mechanicalJointTypes = $shouldLoadMechanicalTypes ? get_mechanical_joint_types() : [];
|
||||
if (!empty($mechanicalJointTypesOverride) && is_array($mechanicalJointTypesOverride)) {
|
||||
$mechanicalJointTypes = array_values(array_unique(array_merge($mechanicalJointTypes, $mechanicalJointTypesOverride)));
|
||||
}
|
||||
if ($shouldLoadMechanicalTypes) {
|
||||
if (isset($alwaysSelectColumns) && is_array($alwaysSelectColumns)) {
|
||||
$alwaysSelectColumns = array_values(array_unique(array_merge($alwaysSelectColumns, ['type_of_welds'])));
|
||||
} else {
|
||||
$alwaysSelectColumns = ['type_of_welds'];
|
||||
}
|
||||
}
|
||||
if($tableName == "nde_matrices") {
|
||||
$alwaysSelectColumns = ['type_of_joint'];
|
||||
}
|
||||
$mechanicalDisabledFields = $enableMechanicalControls ? [
|
||||
'welder_1','welder_2','real_welder_1','real_welder_2',
|
||||
'wps_no','wps_approval_date','welding_method',
|
||||
'rt_report','rt_result','rt_request_date','rt_test_date',
|
||||
'ut_report','ut_result','ut_request_date','ut_test_date','ut_type',
|
||||
'mt_report','mt_result','mt_request_date','mt_test_date',
|
||||
'pt_report','pt_result','pt_request_date','pt_test_date',
|
||||
'vt_report','vt_result','vt_request_date','vt_test_date',
|
||||
'pmi_report','pmi_result','pmi_request_date','pmi_test_date',
|
||||
'pwht','pwht_date','pwht_result','no_of_pwht_report','diagram_number_pwht',
|
||||
'ht_report','ht_request_date','ht_test_date','ht_result',
|
||||
'ferrite_result','ferrite_request_date','ferrite_request_no','date_of_ferrite_check',
|
||||
'spool_ndt_check','spool_ndt_check_no','ndt_release_no','ndt_release_check','ndt_release_date',
|
||||
'paint_release_no','paint_release_date','register_paint_no','register_date','clearance_no','clearance_date'
|
||||
] : [];
|
||||
if (!empty($mechanicalDisabledFieldsOverride) && is_array($mechanicalDisabledFieldsOverride)) {
|
||||
$mechanicalDisabledFields = array_values(array_unique(array_merge($mechanicalDisabledFields, $mechanicalDisabledFieldsOverride)));
|
||||
}
|
||||
$mechanicalDisabledPrefixes = $enableMechanicalControls ? [
|
||||
'welder_',
|
||||
'real_welder_',
|
||||
'certificate_no_',
|
||||
'wpq_',
|
||||
'test_laboratory_',
|
||||
'vt_',
|
||||
'rt_',
|
||||
'ut_',
|
||||
'mt_',
|
||||
'pt_',
|
||||
'pmi_',
|
||||
'pwht',
|
||||
'ht_',
|
||||
'ferrite_',
|
||||
'ndt_',
|
||||
'welding_materials_',
|
||||
'spool_ndt_',
|
||||
'spool_paint_',
|
||||
'paint_release_',
|
||||
'register_paint_',
|
||||
'clearance_'
|
||||
] : [];
|
||||
if (!empty($mechanicalDisabledPrefixesOverride) && is_array($mechanicalDisabledPrefixesOverride)) {
|
||||
$mechanicalDisabledPrefixes = array_values(array_unique(array_merge($mechanicalDisabledPrefixes, $mechanicalDisabledPrefixesOverride)));
|
||||
}
|
||||
$mechanicalEditableWhitelist = $enableMechanicalControls ? ['fitter_name','fit_up_date','welding_date','remarks'] : [];
|
||||
if (!empty($mechanicalEditableWhitelistOverride) && is_array($mechanicalEditableWhitelistOverride)) {
|
||||
$mechanicalEditableWhitelist = array_values(array_unique(array_merge($mechanicalEditableWhitelist, $mechanicalEditableWhitelistOverride)));
|
||||
}
|
||||
?>
|
||||
|
||||
@include($path . '.partials.css-styles')
|
||||
|
||||
@include($path . '.js.fuse-store')
|
||||
|
||||
<script>
|
||||
window.jsPDF = window.jspdf.jsPDF;
|
||||
$(function() {
|
||||
@include($path . '.partials.js-init')
|
||||
@include($path . '.partials.js-utils')
|
||||
@include($path . '.partials.js-validation')
|
||||
@include($path . '.partials.js-lookups')
|
||||
|
||||
@include($path . '.partials.js-variables')
|
||||
@include($path . '.partials.js-helpers')
|
||||
|
||||
@include($path . '.partials.config.js-datagrid')
|
||||
|
||||
@include($path . '.partials.js-extra-handlers')
|
||||
});
|
||||
</script>
|
||||
|
||||
@include($path . '.partials.html-markup')
|
||||
|
||||
@include($path . '.partials.js-popup')
|
||||
@include($path . '.excel-import')
|
||||
@include($path . '.fuzzy-autocomplete', ["tableName" => $tableName])
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$acTable = $column['relation']['table'];
|
||||
$acColumn = $column['relation']['column'];
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "string",
|
||||
<?php if(in_array($column['name'], required_fields())) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
lookup: {
|
||||
dataSource : new DevExpress.data.ODataStore({
|
||||
url: '{{autocomplete_url($acTable, $acColumn)}}',
|
||||
key: 'id',
|
||||
}),
|
||||
<?php
|
||||
if(isset($column['relation']['pattern'])) {
|
||||
|
||||
|
||||
$patternString = $column['relation']['pattern'];
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
foreach($variables AS $variable) {
|
||||
$patternString = str_replace($variable, "data.".$variable, $patternString);
|
||||
}
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
?>
|
||||
valueExpr : function(data) {
|
||||
if(data) {
|
||||
return `{{$patternString}}`;
|
||||
}
|
||||
},
|
||||
displayExpr : function(data) {
|
||||
if(data) {
|
||||
return `{{$patternString}}`;
|
||||
}
|
||||
},
|
||||
<?php } else {
|
||||
?>
|
||||
valueExpr : "{{$column['relation']['column']}}",
|
||||
displayExpr : "{{$column['relation']['column']}}",
|
||||
<?php
|
||||
} ?>
|
||||
|
||||
onSelectionChanged : function(e) {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
editorOptions: {
|
||||
searchEnabled: true,
|
||||
searchMode: 'contains',
|
||||
searchTimeout: 200,
|
||||
minSearchLength: 0,
|
||||
showClearButton: true
|
||||
},
|
||||
setCellValue(rowData, value, data, options) {
|
||||
var dataGrid = $("#dataGrid").dxDataGrid("instance");
|
||||
var exceptValue = ['undefined', 'null'];
|
||||
var rowIndex = localStorage.getItem("rowIndex");
|
||||
console.log("autocomplete rowData");
|
||||
console.log(rowData);
|
||||
console.log(value);
|
||||
console.log(data);
|
||||
console.log(options);
|
||||
<?php $url = url("admin/detail/{$column['relation']['table']}/{$column['relation']['column']}?value="); ?>
|
||||
rowData.{{$column['name']}} = value;
|
||||
let thisRowData = rowData;
|
||||
|
||||
|
||||
$.getJSON("{{$url}}" + value, function(selectedRow) {
|
||||
console.log("selectedRow");
|
||||
console.log(selectedRow);
|
||||
<?php if(isset($column['relation']['affected'])) {
|
||||
|
||||
foreach($column['relation']['affected'] AS $affectColumn => $affectedValue) {
|
||||
|
||||
$patternString = $affectedValue;
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
foreach($variables AS $variable) {
|
||||
$patternString = str_replace($variable, "selectedRow.".$variable, $patternString);
|
||||
}
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
if($patternString != "all") {
|
||||
?>
|
||||
if(!exceptValue.includes(`{{$patternString}}`)) {
|
||||
dataGrid.cellValue(rowIndex, "{{$affectColumn}}", `{{$patternString}}`);
|
||||
}
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
}
|
||||
} ?>
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
width : {{isset($column['relation']['width']) ? $column['relation']['width'] : 200}},
|
||||
|
||||
},
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$acTable = $column['relation']['table'];
|
||||
$acColumn = $column['relation']['column'];
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "string",
|
||||
dataUrl: "{{autocomplete_url($acTable,$acColumn)}}",
|
||||
rowDetailUrl: "{{row_detail_url($acTable,$acColumn)}}?value=",
|
||||
valueExpr : "{{$acColumn}}",
|
||||
affectedCols : <?php echo json_encode_tr($column['relation']['affected']); ?>,
|
||||
<?php if(in_array($column['name'], required_fields())) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
width : {{isset($column['relation']['width']) ? $column['relation']['width'] : 200}},
|
||||
|
||||
},
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
alignment: "left",
|
||||
dataType: "number",
|
||||
validationRules: [{
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
@@ -0,0 +1,31 @@
|
||||
<style>
|
||||
/* Sadece DataGrid navigasyon butonları için özel stiller */
|
||||
#leftButton button, #rightButton button {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
background-color: rgba(255, 0, 0, 0.5);
|
||||
border-color: rgba(255, 0, 0, 0.5);
|
||||
color: white;
|
||||
border: 1px solid;
|
||||
transition: all 0.5s;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
#leftButton button:hover, #rightButton button:hover {
|
||||
background-color: rgba(255, 0, 0, 0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.datagrid-navigation-button {
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
/* DataGrid Scroll Bar CSS'leri - Ayrı dosyadan dahil ediliyor */
|
||||
</style>
|
||||
@@ -0,0 +1,149 @@
|
||||
<style>
|
||||
/* DataGrid Yatay Scroll Bar Kalınlaştırma - Direkt DataGrid Hedefleme */
|
||||
|
||||
/* Ana DataGrid Container */
|
||||
#dataGrid,
|
||||
.dx-datagrid,
|
||||
.dx-datagrid-rowsview,
|
||||
.dx-datagrid-content,
|
||||
.dx-scrollable-content {
|
||||
scrollbar-width: thick !important; /* Firefox için */
|
||||
scrollbar-color: #6c757d #f1f1f1 !important; /* Firefox için - gri */
|
||||
}
|
||||
|
||||
/* DataGrid wrapper'ı içindeki tüm scrollable elementler */
|
||||
#dataGrid *,
|
||||
.dx-datagrid * {
|
||||
scrollbar-width: thick !important;
|
||||
scrollbar-color: #6c757d #f1f1f1 !important; /* Firefox için - gri */
|
||||
}
|
||||
|
||||
/* Webkit Tabanlı Tarayıcılar için (Chrome, Safari, Edge) */
|
||||
#dataGrid .dx-scrollable-container::-webkit-scrollbar,
|
||||
#dataGrid .dx-scrollable::-webkit-scrollbar,
|
||||
.dx-datagrid .dx-scrollable-container::-webkit-scrollbar,
|
||||
.dx-datagrid .dx-scrollable::-webkit-scrollbar {
|
||||
height: 20px !important; /* Yatay scroll bar kalınlığı */
|
||||
width: 20px !important; /* Dikey scroll bar kalınlığı */
|
||||
}
|
||||
|
||||
/* Scroll Bar Track (Arkaplan) */
|
||||
#dataGrid .dx-scrollable-container::-webkit-scrollbar-track,
|
||||
#dataGrid .dx-scrollable::-webkit-scrollbar-track,
|
||||
.dx-datagrid .dx-scrollable-container::-webkit-scrollbar-track,
|
||||
.dx-datagrid .dx-scrollable::-webkit-scrollbar-track {
|
||||
background: linear-gradient(90deg, #f8f9fa 0%, #e9ecef 100%) !important;
|
||||
border-radius: 10px !important;
|
||||
border: 2px solid #dee2e6 !important;
|
||||
box-shadow: inset 0 0 5px rgba(0,0,0,0.1) !important;
|
||||
}
|
||||
|
||||
/* Scroll Bar Thumb (Hareket Eden Kısım) */
|
||||
#dataGrid .dx-scrollable-container::-webkit-scrollbar-thumb,
|
||||
#dataGrid .dx-scrollable::-webkit-scrollbar-thumb,
|
||||
.dx-datagrid .dx-scrollable-container::-webkit-scrollbar-thumb,
|
||||
.dx-datagrid .dx-scrollable::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(45deg, #6c757d 0%, #5a6268 50%, #495057 100%) !important; /* Gri gradient */
|
||||
border-radius: 10px !important;
|
||||
border: 2px solid #fff !important;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.3) !important;
|
||||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
/* Scroll Bar Hover Durumu */
|
||||
#dataGrid .dx-scrollable-container::-webkit-scrollbar-thumb:hover,
|
||||
#dataGrid .dx-scrollable::-webkit-scrollbar-thumb:hover,
|
||||
.dx-datagrid .dx-scrollable-container::-webkit-scrollbar-thumb:hover,
|
||||
.dx-datagrid .dx-scrollable::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(45deg, #dc3545 0%, #c82333 50%, #bd2130 100%) !important;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.4) !important;
|
||||
/* transform kaldırıldı - scroll bar'da sorun yaratıyordu */
|
||||
}
|
||||
|
||||
/* Scroll Bar Corner */
|
||||
#dataGrid .dx-scrollable-container::-webkit-scrollbar-corner,
|
||||
#dataGrid .dx-scrollable::-webkit-scrollbar-corner,
|
||||
.dx-datagrid .dx-scrollable-container::-webkit-scrollbar-corner,
|
||||
.dx-datagrid .dx-scrollable::-webkit-scrollbar-corner {
|
||||
background: #f8f9fa !important;
|
||||
border-radius: 5px !important;
|
||||
}
|
||||
|
||||
/* DevExtreme Özel Scroll Bar Sınıfları */
|
||||
.dx-scrollbar-horizontal,
|
||||
.dx-scrollable-scrollbar.dx-scrollbar-horizontal {
|
||||
height: 22px !important;
|
||||
background: linear-gradient(90deg, #f8f9fa 0%, #e9ecef 100%) !important;
|
||||
border-top: 1px solid #9d9d9d !important; /* Gri border */
|
||||
border-radius: 0 0 10px 10px !important;
|
||||
}
|
||||
|
||||
.dx-scrollbar-horizontal .dx-scrollable-scroll,
|
||||
.dx-scrollable-scrollbar.dx-scrollbar-horizontal .dx-scrollable-scroll {
|
||||
background: linear-gradient(45deg, #6c757d 0%, #5a6268 100%) !important; /* Gri gradient */
|
||||
border-radius: 8px !important;
|
||||
height: 14px !important;
|
||||
margin: 3px !important;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.3) !important;
|
||||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
.dx-scrollbar-horizontal .dx-scrollable-scroll:hover,
|
||||
.dx-scrollable-scrollbar.dx-scrollbar-horizontal .dx-scrollable-scroll:hover {
|
||||
background: linear-gradient(45deg, #dc3545 0%, #c82333 100%) !important;
|
||||
/* scaleY kaldırıldı - scroll bar'da titreme yaratıyordu */
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.4) !important;
|
||||
opacity: 0.9 !important; /* Bunun yerine hafif opacity değişimi */
|
||||
}
|
||||
|
||||
/* DataGrid'in tüm scroll elemanları için */
|
||||
.dx-datagrid-headers,
|
||||
.dx-datagrid-rowsview,
|
||||
.dx-datagrid-content {
|
||||
scrollbar-width: thick !important;
|
||||
scrollbar-color: #6c757d #f1f1f1 !important;
|
||||
}
|
||||
|
||||
/* DataGrid için özel scrollbar container'ları */
|
||||
.dx-datagrid .dx-datagrid-scroll-container::-webkit-scrollbar {
|
||||
height: 20px !important;
|
||||
width: 20px !important;
|
||||
}
|
||||
|
||||
.dx-datagrid .dx-datagrid-scroll-container::-webkit-scrollbar-track {
|
||||
background: linear-gradient(90deg, #f8f9fa 0%, #e9ecef 100%) !important;
|
||||
border-radius: 10px !important;
|
||||
border: 2px solid #dee2e6 !important;
|
||||
}
|
||||
|
||||
.dx-datagrid .dx-datagrid-scroll-container::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(45deg, #6c757d 0%, #5a6268 100%) !important; /* Gri gradient */
|
||||
border-radius: 10px !important;
|
||||
border: 2px solid #fff !important;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.3) !important;
|
||||
}
|
||||
|
||||
.dx-datagrid .dx-datagrid-scroll-container::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(45deg, #dc3545 0%, #c82333 100%) !important;
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.4) !important;
|
||||
opacity: 0.9 !important; /* Stable hover efekti */
|
||||
}
|
||||
|
||||
/* SORUNUN KAYNAĞI: DevExtreme'nin gri background'unu temizle */
|
||||
.dx-scrollable-scroll-content {
|
||||
background-color: unset !important;
|
||||
background: unset !important;
|
||||
box-shadow: unset !important;
|
||||
-webkit-box-shadow: unset !important;
|
||||
}
|
||||
|
||||
/* Scroll content'indeki tüm arka plan renklerini temizle */
|
||||
#dataGrid .dx-scrollable-scroll-content,
|
||||
.dx-datagrid .dx-scrollable-scroll-content,
|
||||
.dx-scrollable-scroll-content {
|
||||
background-color: transparent !important;
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "date",
|
||||
format: "dd/MM/yyyy",
|
||||
width: {{isset($column['relation']['width']) ? $column['relation']['width'] : 150}},
|
||||
validationRules: [{
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
filterValue: null, // Filter by null value by default
|
||||
calculateFilterExpression: function(filterValue, selectedFilterOperation) {
|
||||
if (filterValue === null || filterValue == "") {
|
||||
return [[this.dataField, "=", null], "or", [this.dataField, "=", ""]];
|
||||
}
|
||||
return this.defaultCalculateFilterExpression.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "date",
|
||||
<?php if(in_array($column['name'], $requiredFields)) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "number",
|
||||
alignment: "left",
|
||||
validationRules: [{
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
@@ -0,0 +1,132 @@
|
||||
try {
|
||||
localStorage.setItem("rowIndex", e.row.rowIndex);
|
||||
localStorage.setItem("colIndex", e.index);
|
||||
localStorage.setItem("dataField", e.row.dataField);
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
var exceptValue = ['undefined', 'null', null, undefined];
|
||||
var options = e.editorOptions;
|
||||
|
||||
if (e.parentType == 'dataRow' && e.editorName == 'dxTextBox') {
|
||||
|
||||
|
||||
if(e.dataField.indexOf("_result") !== -1) {
|
||||
e.editorName = 'dxSelectBox';
|
||||
e.editorOptions.dataSource = <?php echo json_encode_tr(
|
||||
db("results")
|
||||
->get()
|
||||
->pluck("title")
|
||||
->toArray()
|
||||
) ?>;
|
||||
|
||||
} else {
|
||||
options.onValueChanged = function(selectData) {
|
||||
<?php $except = [
|
||||
'languages',
|
||||
'subcontractor',
|
||||
'work-permit-personel-list',
|
||||
]; ?>
|
||||
|
||||
@if(!in_array($id, $except))
|
||||
e.setValue(selectData.value.trim().toUpperCase());
|
||||
@else
|
||||
e.setValue(selectData.value.trim());
|
||||
@endif
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(e.dataType == "date" ) {
|
||||
e.editorName = 'dxDateBox';
|
||||
e.displayFormat = 'dd/MM/yyyy';
|
||||
e.dataType = 'date';
|
||||
e.editorOptions.format = 'dd/MM/yyyy';
|
||||
e.editorOptions.useMaskBehavior = true;
|
||||
}
|
||||
if(e.dataType == "autocomplete") {
|
||||
e.editorName = "dxAutocomplete";
|
||||
e.editorOptions.dataSource = new DevExpress.data.ODataStore({
|
||||
url: e.dataUrl,
|
||||
key: 'id',
|
||||
});
|
||||
e.editorOptions.valueExpr = e.valueExpr;
|
||||
e.editorOptions.minSearchLength = 1;
|
||||
|
||||
var affectedCols = e.affectedCols;
|
||||
|
||||
|
||||
options.onValueChanged = function(selectData) {
|
||||
e.setValue(selectData.value);
|
||||
$.getJSON(e.rowDetailUrl + selectData.value, function(responseJSON) {
|
||||
console.log("responseJSON");
|
||||
console.log(responseJSON);
|
||||
console.log(affectedCols);
|
||||
for (const [key, value] of Object.entries(affectedCols)) {
|
||||
var value2 = value.replace("{", "${responseJSON.");
|
||||
value2 = eval("`" + value2 + "`");
|
||||
if(exceptValue.includes(value2)) {
|
||||
value2 = "";
|
||||
}
|
||||
dataGrid.cellValue(e.row.rowIndex, key, value2);
|
||||
}
|
||||
|
||||
/*
|
||||
affectedCols.forEach(function(item, index) {
|
||||
console.log(item);
|
||||
console.log(index);
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
if(!exceptValue.includes(``)) {
|
||||
dataGrid.cellValue(rowIndex, "", ``);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (e.parentType != "dataRow") return;
|
||||
|
||||
var dataRow = e.row.data;
|
||||
if(typeof editorPreparing === 'function') {
|
||||
|
||||
// Eğer dataField yoksa işlem yapma
|
||||
if (!e.dataField) {
|
||||
return;
|
||||
}
|
||||
|
||||
editorPreparing(e, dataRow);
|
||||
}
|
||||
e.editorOptions.onKeyDown = function(pressKey) {
|
||||
if(pressKey.event.originalEvent.key == "F2") {
|
||||
const value = $("#dataGrid").dxDataGrid("instance").cellValue(1, e.dataField);
|
||||
console.log(value);
|
||||
e.setValue(value);
|
||||
e.component.option('value', value);
|
||||
var event = new KeyboardEvent('keydown', { key: 'Tab' });
|
||||
document.dispatchEvent(event);
|
||||
/*
|
||||
const nextEditor = $("#dataGrid").dxDataGrid("instance").getEditor(0, 5);
|
||||
if (nextEditor) {
|
||||
nextEditor.focus();
|
||||
nextEditor.open();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,188 @@
|
||||
<input type="file" id="excel-import-input" accept=".xlsx, .xls" style="display:none;">
|
||||
<script>
|
||||
// Excel column mapping (if defined in blade file)
|
||||
var excelColumnMapping = @json($excelColumnMapping ?? []);
|
||||
|
||||
$(function() {
|
||||
$("#excel-import-input").on("change", async function() {
|
||||
if(this.files && this.files[0]) {
|
||||
const file = this.files[0];
|
||||
const reader = new FileReader();
|
||||
|
||||
Swal.fire({
|
||||
title: '{{e2("Reading Excel...")}}',
|
||||
text: '{{e2("Please wait while the file is being processed locally.")}}',
|
||||
allowOutsideClick: false,
|
||||
didOpen: () => {
|
||||
Swal.showLoading();
|
||||
}
|
||||
});
|
||||
|
||||
reader.onload = async function(e) {
|
||||
try {
|
||||
const buffer = e.target.result;
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(buffer);
|
||||
|
||||
// İlk sayfayı al
|
||||
const worksheet = workbook.worksheets[0];
|
||||
const data = [];
|
||||
const headers = [];
|
||||
|
||||
// 1. Satırdan başlıkları al
|
||||
worksheet.getRow(1).eachCell((cell, colNumber) => {
|
||||
// Başlıkları trim yapalım
|
||||
let headerValue = cell.value ? String(cell.value).trim() : null;
|
||||
// Apply column mapping if exists
|
||||
if (headerValue && excelColumnMapping[headerValue]) {
|
||||
headerValue = excelColumnMapping[headerValue];
|
||||
}
|
||||
headers[colNumber] = headerValue;
|
||||
});
|
||||
|
||||
// Satırları oku
|
||||
worksheet.eachRow((row, rowNumber) => {
|
||||
if (rowNumber === 1) return; // Başlık satırını atla
|
||||
|
||||
const rowData = {};
|
||||
let hasData = false;
|
||||
let isTotalRow = false; // Toplam satırı kontrolü
|
||||
|
||||
// Sadece başlığı olan sütunları oku
|
||||
headers.forEach((header, colNumber) => {
|
||||
if (header) {
|
||||
const cell = row.getCell(colNumber);
|
||||
let cellValue = cell.value;
|
||||
|
||||
// Rich text, formula, hyperlink kontrolü
|
||||
if (typeof cellValue === 'object' && cellValue !== null) {
|
||||
if (cellValue.hasOwnProperty('result')) {
|
||||
cellValue = cellValue.result;
|
||||
} else if (cellValue.hasOwnProperty('text')) { // Hyperlink
|
||||
cellValue = cellValue.text;
|
||||
} else if(cellValue.hasOwnProperty('richText')) {
|
||||
cellValue = cellValue.richText.map(r => r.text).join('');
|
||||
}
|
||||
}
|
||||
|
||||
// ID sütunu kontrolü - "Total" veya "Sum" gibi değerler varsa bu satırı alma
|
||||
if (header.toLowerCase() === 'id' && cellValue) {
|
||||
const valStr = String(cellValue).toLowerCase();
|
||||
if (valStr.includes('total') || valStr.includes('sum') || valStr.includes(':')) {
|
||||
isTotalRow = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Boş hücreleri undefined/null bırakmak yerine boş string veya null atayabiliriz
|
||||
// Ancak DevExtreme store genelde undefined alanları güncellemez, bu yüzden veri varsa ekleyelim
|
||||
if (cellValue !== null && cellValue !== undefined) {
|
||||
rowData[header] = cellValue;
|
||||
hasData = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(hasData && !isTotalRow) {
|
||||
data.push(rowData);
|
||||
}
|
||||
});
|
||||
|
||||
Swal.close();
|
||||
|
||||
if (data.length === 0) {
|
||||
Swal.fire('{{e2("Warning")}}', '{{e2("No data found in Excel file.")}}', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
// İçe aktarım onayı
|
||||
Swal.fire({
|
||||
title: '{{e2("Import Confirmation")}}',
|
||||
text: data.length + ' {{e2("rows found. Do you want to proceed?")}}',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '{{e2("Yes, import")}}',
|
||||
cancelButtonText: '{{e2("Cancel")}}'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
processExcelData(data);
|
||||
} else {
|
||||
$("#excel-import-input").val('');
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error("Excel read error:", error);
|
||||
Swal.close();
|
||||
Swal.fire('{{e2("Error")}}', '{{e2("Failed to read Excel file. Please ensure it is a valid XLSX file.")}}', 'error');
|
||||
$("#excel-import-input").val('');
|
||||
}
|
||||
};
|
||||
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
});
|
||||
|
||||
async function processExcelData(data) {
|
||||
const dataGrid = $("#dataGrid").dxDataGrid("instance");
|
||||
const store = dataGrid.getDataSource().store();
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
let updatedCount = 0;
|
||||
let insertedCount = 0;
|
||||
|
||||
Swal.fire({
|
||||
title: '{{e2("Importing Data...")}}',
|
||||
html: '0 / ' + data.length,
|
||||
allowOutsideClick: false,
|
||||
didOpen: () => {
|
||||
Swal.showLoading();
|
||||
}
|
||||
});
|
||||
|
||||
// Batch processing
|
||||
const batchSize = 10; // API yükünü azaltmak için küçük partiler
|
||||
|
||||
for (let i = 0; i < data.length; i += batchSize) {
|
||||
const batch = data.slice(i, i + batchSize);
|
||||
const promises = batch.map(async (item) => {
|
||||
try {
|
||||
// ID kontrolü - varsa güncelle, yoksa ekle
|
||||
if (item.hasOwnProperty('id') && item.id) {
|
||||
// Update
|
||||
await store.update(item.id, item);
|
||||
updatedCount++;
|
||||
} else {
|
||||
// Insert
|
||||
await store.insert(item);
|
||||
insertedCount++;
|
||||
}
|
||||
successCount++;
|
||||
} catch (e) {
|
||||
console.error("Import error for item:", item, e);
|
||||
errorCount++;
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
// İlerlemeyi güncelle
|
||||
const processed = Math.min(i + batchSize, data.length);
|
||||
Swal.getHtmlContainer().textContent = `${processed} / ${data.length} (Updated: ${updatedCount}, Inserted: ${insertedCount})`;
|
||||
}
|
||||
|
||||
$("#excel-import-input").val(''); // Inputu temizle
|
||||
dataGrid.refresh();
|
||||
|
||||
Swal.fire({
|
||||
icon: successCount > 0 ? 'success' : 'warning',
|
||||
title: '{{e2("Import Completed")}}',
|
||||
html: `
|
||||
{{e2("Total Processed")}}: ${successCount}<br>
|
||||
{{e2("Updated")}}: ${updatedCount}<br>
|
||||
{{e2("Inserted")}}: ${insertedCount}<br>
|
||||
{{e2("Failed")}}: ${errorCount}
|
||||
`
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = $column['relation']['caption'] ?? $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
|
||||
?>
|
||||
alignment: "left",
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "number",
|
||||
validationRules: [{
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
@@ -0,0 +1,183 @@
|
||||
<style>
|
||||
.fuzzy-autocomplete-dropdown {
|
||||
position: absolute;
|
||||
z-index: 10001;
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
max-height: 250px;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
display: none;
|
||||
min-width: 200px;
|
||||
}
|
||||
.fuzzy-autocomplete-item {
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 13px;
|
||||
}
|
||||
.fuzzy-autocomplete-item:hover {
|
||||
background: #e8f4fc;
|
||||
}
|
||||
.fuzzy-autocomplete-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="fuzzyAutocompleteDropdown" class="fuzzy-autocomplete-dropdown"></div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var $dropdown = $('#fuzzyAutocompleteDropdown');
|
||||
var searchTimeout = null;
|
||||
var currentInput = null;
|
||||
var currentField = null;
|
||||
var baseUrl = '{{ route("fuzzy-autocomplete", ["tableName" => $tableName]) }}/';
|
||||
|
||||
// Hide dropdown when clicking outside
|
||||
$(document).on('click', function(e) {
|
||||
if (!$(e.target).closest('.fuzzy-autocomplete-dropdown, .dx-texteditor-input').length) {
|
||||
$dropdown.hide();
|
||||
}
|
||||
});
|
||||
|
||||
// Position dropdown relative to input
|
||||
function positionDropdown($input) {
|
||||
var inputRect = $input[0].getBoundingClientRect();
|
||||
|
||||
$dropdown.css({
|
||||
position: 'fixed',
|
||||
top: inputRect.bottom + 2,
|
||||
left: inputRect.left,
|
||||
width: Math.max(inputRect.width, 280)
|
||||
});
|
||||
}
|
||||
|
||||
// Check if input is a plain text editor (not select, dropdown, tagbox, etc.)
|
||||
function isPlainTextEditor($input) {
|
||||
var $editor = $input.closest('.dx-texteditor');
|
||||
if (!$editor.length) return false;
|
||||
|
||||
// Skip if it's a dropdown-based editor
|
||||
if ($editor.hasClass('dx-selectbox') ||
|
||||
$editor.hasClass('dx-tagbox') ||
|
||||
$editor.hasClass('dx-autocomplete') ||
|
||||
$editor.hasClass('dx-dropdowneditor') ||
|
||||
$editor.hasClass('dx-lookup') ||
|
||||
$editor.closest('.dx-overlay-wrapper').length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only work with plain dxTextBox
|
||||
return $editor.hasClass('dx-textbox');
|
||||
}
|
||||
|
||||
// Listen for input events on DataGrid text editors (only plain text inputs)
|
||||
$(document).on('input', '#dataGrid .dx-textbox .dx-texteditor-input', function(e) {
|
||||
var $input = $(this);
|
||||
var value = $input.val();
|
||||
|
||||
// Double check it's a plain text editor
|
||||
if (!isPlainTextEditor($input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the column/field name
|
||||
var $cell = $input.closest('td');
|
||||
var columnIndex = $cell.index();
|
||||
var grid = $('#dataGrid').dxDataGrid('instance');
|
||||
var columns = grid.getVisibleColumns();
|
||||
|
||||
if (columns[columnIndex]) {
|
||||
currentField = columns[columnIndex].dataField;
|
||||
}
|
||||
|
||||
if (!currentField || !value || value.length < 1) {
|
||||
$dropdown.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
currentInput = $input;
|
||||
|
||||
// Debounce the search
|
||||
clearTimeout(searchTimeout);
|
||||
searchTimeout = setTimeout(function() {
|
||||
var url = baseUrl + currentField;
|
||||
|
||||
$.getJSON(url, { search: value, limit: 10 })
|
||||
.done(function(data) {
|
||||
if (!data || !data.length) {
|
||||
$dropdown.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '';
|
||||
data.forEach(function(item) {
|
||||
var displayText = item.display || item.value || item;
|
||||
var valueText = item.value || item;
|
||||
|
||||
html += '<div class="fuzzy-autocomplete-item" data-value="' + valueText + '">' + displayText + '</div>';
|
||||
});
|
||||
|
||||
$dropdown.html(html);
|
||||
positionDropdown(currentInput);
|
||||
$dropdown.show();
|
||||
})
|
||||
.fail(function() {
|
||||
$dropdown.hide();
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// Handle suggestion click
|
||||
$(document).on('mousedown', '.fuzzy-autocomplete-item', function(e) {
|
||||
e.preventDefault();
|
||||
var selectedValue = $(this).data('value');
|
||||
|
||||
if (currentInput) {
|
||||
currentInput.val(selectedValue);
|
||||
currentInput.trigger('change');
|
||||
currentInput.focus();
|
||||
|
||||
// Trigger DevExtreme value change
|
||||
try {
|
||||
var $editor = currentInput.closest('.dx-texteditor');
|
||||
if ($editor.length && $editor.dxTextBox) {
|
||||
var editor = $editor.dxTextBox('instance');
|
||||
if (editor) {
|
||||
editor.option('value', selectedValue);
|
||||
}
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
|
||||
$dropdown.hide();
|
||||
});
|
||||
|
||||
// Hide on blur with delay
|
||||
$(document).on('blur', '#dataGrid .dx-textbox .dx-texteditor-input', function() {
|
||||
setTimeout(function() {
|
||||
$dropdown.hide();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
// Hide on scroll
|
||||
$(document).on('scroll', function() {
|
||||
$dropdown.hide();
|
||||
});
|
||||
|
||||
$('#dataGrid').on('scroll', '.dx-scrollable-container', function() {
|
||||
$dropdown.hide();
|
||||
});
|
||||
|
||||
// Hide on escape key
|
||||
$(document).on('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
$dropdown.hide();
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "string",
|
||||
<?php if(in_array($column['name'], $requiredFields)) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } ?>,
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
alignment: "left",
|
||||
dataType: "number",
|
||||
validationRules: [{
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
<script>
|
||||
function createFuseSearchStore(data, keys, options) {
|
||||
options = options || {};
|
||||
var threshold = options.threshold !== undefined ? options.threshold : 0.4;
|
||||
|
||||
return new DevExpress.data.CustomStore({
|
||||
load: function(loadOptions) {
|
||||
if (loadOptions.searchValue) {
|
||||
var fuseOptions = {
|
||||
threshold: threshold
|
||||
};
|
||||
if (keys && keys.length > 0) {
|
||||
fuseOptions.keys = keys;
|
||||
}
|
||||
|
||||
var fuse = new Fuse(data, fuseOptions);
|
||||
var result = fuse.search(loadOptions.searchValue).map(function(result) {
|
||||
return result.item;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
byKey: function(key) {
|
||||
return new Promise(function(resolve) {
|
||||
resolve(key);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,19 @@
|
||||
if(typeof initSetCellValue === 'function') {
|
||||
rowData.{{$column['name']}} = value;
|
||||
var datas = {
|
||||
'rowData' : rowData,
|
||||
'value' : value,
|
||||
'data' : data,
|
||||
'options' : options,
|
||||
'columnName' : "{{$column['name']}}",
|
||||
'columnType' : "{{$column['type']}}",
|
||||
};
|
||||
initSetCellValue(datas);
|
||||
|
||||
// After setCellValue, update rowData with any changes made by setCellValue
|
||||
if (datas.rowData) {
|
||||
Object.keys(datas.rowData).forEach(function(key) {
|
||||
rowData[key] = datas.rowData[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
{{-- Auto-calculate calibration_due_date when calibration_date or calibration_frequency changes --}}
|
||||
function setCellValue(datas) {
|
||||
console.log('[CalibrationLogs] setCellValue called', datas);
|
||||
if (!datas || typeof datas !== 'object') {
|
||||
console.log('[CalibrationLogs] Invalid datas object');
|
||||
return;
|
||||
}
|
||||
|
||||
// DevExtreme wrapper: datas.rowData contains changed fields, datas.data contains full row
|
||||
// We need to merge them to get complete row data with latest changes
|
||||
var row = {};
|
||||
|
||||
// Start with full row data from datas.data
|
||||
if (datas.data && typeof datas.data === 'object') {
|
||||
row = Object.assign({}, datas.data);
|
||||
console.log('[CalibrationLogs] datas.data:', datas.data);
|
||||
}
|
||||
|
||||
// Override with changed fields from rowData (to get latest values)
|
||||
if (datas.rowData && typeof datas.rowData === 'object') {
|
||||
row = Object.assign({}, row, datas.rowData);
|
||||
console.log('[CalibrationLogs] datas.rowData:', datas.rowData);
|
||||
}
|
||||
|
||||
// Fallback: if still no data, use datas directly
|
||||
if (Object.keys(row).length === 0) {
|
||||
row = datas;
|
||||
}
|
||||
|
||||
// If still missing critical fields, try to get from datagrid instance
|
||||
if ((!row.calibration_date || !row.calibration_frequency) && typeof dataGrid !== 'undefined') {
|
||||
try {
|
||||
// Get currently editing row from datagrid
|
||||
var editingRow = dataGrid.getVisibleRows().find(function(r) {
|
||||
return r.isEditing || r.isNewRow;
|
||||
});
|
||||
|
||||
if (editingRow && editingRow.data) {
|
||||
console.log('[CalibrationLogs] Found editing row:', editingRow.data);
|
||||
row = Object.assign({}, editingRow.data, row);
|
||||
} else {
|
||||
// Try to get row by key (id)
|
||||
if (row.id) {
|
||||
var rowByKey = dataGrid.getVisibleRows().find(function(r) {
|
||||
return r.data && r.data.id === row.id;
|
||||
});
|
||||
if (rowByKey && rowByKey.data) {
|
||||
console.log('[CalibrationLogs] Found row by key:', rowByKey.data);
|
||||
row = Object.assign({}, rowByKey.data, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
console.log('[CalibrationLogs] Could not get row from datagrid:', e);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[CalibrationLogs] Final row data:', row);
|
||||
|
||||
// Always set quantity to 1
|
||||
if (!row.quantity || row.quantity === '' || row.quantity === null) {
|
||||
row.quantity = 1;
|
||||
}
|
||||
|
||||
function parseGridDate(value) {
|
||||
if (!value) return null;
|
||||
|
||||
// If already a Date object, return a copy
|
||||
if (value instanceof Date && !isNaN(value.getTime())) {
|
||||
return new Date(value.getTime());
|
||||
}
|
||||
|
||||
if (typeof value !== 'string') return null;
|
||||
|
||||
var s = value.trim();
|
||||
if (!s.length) return null;
|
||||
|
||||
// DD.MM.YYYY format
|
||||
if (s.indexOf('.') !== -1) {
|
||||
var p = s.split('.');
|
||||
if (p.length === 3) {
|
||||
var d = parseInt(p[0], 10);
|
||||
var m = parseInt(p[1], 10);
|
||||
var y = parseInt(p[2], 10);
|
||||
if (!isNaN(d) && !isNaN(m) && !isNaN(y)) {
|
||||
return new Date(y, m - 1, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DD/MM/YYYY format (e.g., 20/01/2026)
|
||||
if (s.indexOf('/') !== -1) {
|
||||
var p2 = s.split('/');
|
||||
if (p2.length === 3) {
|
||||
var a = parseInt(p2[0], 10);
|
||||
var b = parseInt(p2[1], 10);
|
||||
var c = parseInt(p2[2], 10);
|
||||
if (!isNaN(a) && !isNaN(b) && !isNaN(c)) {
|
||||
// If first part is 4 digits -> YYYY/MM/DD
|
||||
if (p2[0].length === 4) {
|
||||
return new Date(a, b - 1, c);
|
||||
}
|
||||
// else DD/MM/YYYY
|
||||
return new Date(c, b - 1, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ISO format (YYYY-MM-DD) or other formats supported by Date()
|
||||
var d2 = new Date(s);
|
||||
if (!isNaN(d2.getTime())) return d2;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var calibrationDate = row.calibration_date;
|
||||
var calibrationFrequency = row.calibration_frequency;
|
||||
|
||||
console.log('[CalibrationLogs] calibrationDate:', calibrationDate, 'calibrationFrequency:', calibrationFrequency);
|
||||
|
||||
// If both calibration_date and calibration_frequency have values, calculate due date
|
||||
if (calibrationDate && calibrationFrequency) {
|
||||
var date = parseGridDate(calibrationDate);
|
||||
console.log('[CalibrationLogs] Parsed date:', date);
|
||||
|
||||
// Calculate due date by adding frequency (days)
|
||||
if (date && !isNaN(date.getTime())) {
|
||||
var frequency = parseInt(calibrationFrequency, 10);
|
||||
console.log('[CalibrationLogs] Frequency (days):', frequency);
|
||||
if (!isNaN(frequency) && frequency > 0) {
|
||||
// Add days, not months
|
||||
date.setDate(date.getDate() + frequency);
|
||||
|
||||
// Format as YYYY-MM-DD (safe for backend save)
|
||||
var year = date.getFullYear();
|
||||
var month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
var day = String(date.getDate()).padStart(2, '0');
|
||||
var dueDate = year + '-' + month + '-' + day;
|
||||
|
||||
// Update row data - this will be picked up by DevExtreme automatically
|
||||
row.calibration_due_date = dueDate;
|
||||
|
||||
// Update in datas.rowData so it gets saved and displayed
|
||||
if (datas.rowData) {
|
||||
datas.rowData.calibration_due_date = dueDate;
|
||||
}
|
||||
|
||||
// Also update in datas.data for consistency
|
||||
if (datas.data) {
|
||||
datas.data.calibration_due_date = dueDate;
|
||||
}
|
||||
|
||||
console.log('[CalibrationLogs] Calculated due_date:', dueDate);
|
||||
} else {
|
||||
console.log('[CalibrationLogs] Invalid frequency value');
|
||||
}
|
||||
} else {
|
||||
console.log('[CalibrationLogs] Failed to parse date');
|
||||
}
|
||||
} else {
|
||||
console.log('[CalibrationLogs] Missing calibration_date or calibration_frequency');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
var material_group_test_pieces = <?php echo json_encode_tr($material_group_test_pieces_data) ?>;
|
||||
if(datas.columnName == "outside_diameter") {
|
||||
|
||||
}
|
||||
if(datas.columnName == "type_grade_1") {
|
||||
type_grade_1_data.forEach(function(){
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
if(datas.columnName == "p_no_from") {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "string",
|
||||
allowEditing: false,
|
||||
validationRules: [{
|
||||
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
cellTemplate: function(container, options) {
|
||||
$('<button>')
|
||||
.addClass('btn btn-outline-primary btn-xs')
|
||||
.text('{{e2("Show data")}}')
|
||||
.on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
showJsonPopup(options.value, options.data);
|
||||
})
|
||||
.appendTo(container);
|
||||
},
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
|
||||
},
|
||||
@@ -0,0 +1,53 @@
|
||||
@php
|
||||
$linkConfig = isset($column['relation']) && is_array($column['relation']) ? $column['relation'] : [];
|
||||
$allowEdit = isset($linkConfig['allowEditing']) && $linkConfig['allowEditing'];
|
||||
$placeholder = isset($linkConfig['placeholder']) ? addslashes($linkConfig['placeholder']) : '';
|
||||
$captionName = isset($linkConfig['caption']) ? $linkConfig['caption'] : $column['name'];
|
||||
@endphp
|
||||
{
|
||||
dataField: "{{$column['name']}}",
|
||||
caption: "{{e2($captionName)}}",
|
||||
allowEditing: {{ $allowEdit ? 'true' : 'false' }},
|
||||
allowFiltering: true,
|
||||
allowSorting: true,
|
||||
allowExporting: false,
|
||||
headerFilter: {
|
||||
dataSource: [
|
||||
{
|
||||
text: "{{e2('With File')}}",
|
||||
value: [["{{$column['name']}}", "<>", null], "and", ["{{$column['name']}}", "<>", ""]]
|
||||
},
|
||||
{
|
||||
text: "{{e2('Without File')}}",
|
||||
value: [["{{$column['name']}}", "=", null], "or", ["{{$column['name']}}", "=", ""]]
|
||||
}
|
||||
]
|
||||
},
|
||||
cellTemplate: function (container, options) {
|
||||
var val = options.data.{{$column['name']}};
|
||||
if(val) {
|
||||
var url = '{{url("/")}}/' + val + "?{{rand()}}";
|
||||
$('<a href="javascript:void(0)"><i class="fa fa-file-pdf"></i></a>')
|
||||
.on('click', function() {
|
||||
openPdfModal(url, '{{e2($captionName)}}');
|
||||
})
|
||||
.appendTo(container);
|
||||
}
|
||||
}@if($allowEdit),
|
||||
editCellTemplate: function(cellElement, cellInfo) {
|
||||
var $input = $('<input type="text" class="form-control" />');
|
||||
$input.val(cellInfo.value || "");
|
||||
@if(!empty($placeholder))
|
||||
$input.attr("placeholder", "{{$placeholder}}");
|
||||
@endif
|
||||
$input.on("input change", function() {
|
||||
cellInfo.setValue(this.value);
|
||||
});
|
||||
$input.appendTo(cellElement);
|
||||
setTimeout(function() {
|
||||
$input.focus();
|
||||
$input.select();
|
||||
}, 50);
|
||||
}
|
||||
@endif
|
||||
},
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
// Tablo adını column relation'dan al, yoksa global $tableName kullan
|
||||
$currentTableName = $tableName;
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
|
||||
validationRules: [{
|
||||
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
width: {{isset($column['relation']['width']) ? $column['relation']['width'] : 200}},
|
||||
cellTemplate: function (container, options) {
|
||||
var content = $("<div>");
|
||||
|
||||
// Detail button
|
||||
$("<div>")
|
||||
.dxButton({
|
||||
icon: "fa fa-eye",
|
||||
stylingMode: "contained",
|
||||
type: "normal",
|
||||
elementAttr: {
|
||||
class: "ml-2 float-right btn-secondary"
|
||||
},
|
||||
onClick: function() {
|
||||
// Modal content is being filled
|
||||
$("#modal-popin .block-content").html("");
|
||||
$("#modal-popin .modal-footer").removeClass("d-none");
|
||||
|
||||
// Check table parameter
|
||||
var tableName = "{{ $currentTableName }}";
|
||||
if (!tableName) {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
text: 'Table name not found'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Load editing form via AJAX
|
||||
$.get("{{ url('admin-ajax/long-text-edit') }}", {
|
||||
table: tableName,
|
||||
id: options.data.id,
|
||||
column: "{{($column['name'])}}",
|
||||
_token: "{{ csrf_token() }}"
|
||||
}, function(response) {
|
||||
$("#modal-popin .block-content").html(response);
|
||||
});
|
||||
|
||||
// Modal is opening
|
||||
$("#modal-popin").modal();
|
||||
}
|
||||
})
|
||||
.appendTo(content);
|
||||
|
||||
// Short text display
|
||||
$("<div>")
|
||||
.text(options.data.{{($column['name'])}} ? options.data.{{($column['name'])}}.substring(0, 30) + "..." : "")
|
||||
.appendTo(content);
|
||||
|
||||
|
||||
|
||||
content.appendTo(container);
|
||||
}
|
||||
|
||||
},
|
||||
@@ -0,0 +1,169 @@
|
||||
{
|
||||
dataField: "{{ $column['name'] }}",
|
||||
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption'])
|
||||
? $column['relation']['caption']
|
||||
: $column['name'];
|
||||
|
||||
$staticValues = $column['relation']['values'] ?? [];
|
||||
if ($staticValues instanceof \Illuminate\Support\Collection) {
|
||||
$staticValues = $staticValues->toArray();
|
||||
}
|
||||
|
||||
$dbValues = [];
|
||||
|
||||
if (isset($tableDifferentValues) && isset($tableDifferentValues[$column['name']])) {
|
||||
$dbValues = $tableDifferentValues[$column['name']];
|
||||
if ($dbValues instanceof \Illuminate\Support\Collection) {
|
||||
$dbValues = $dbValues->toArray();
|
||||
}
|
||||
} elseif (isset($tableName)) {
|
||||
try {
|
||||
$dbValues = db($tableName)
|
||||
->whereNotNull($column['name'])
|
||||
->where($column['name'], '!=', '')
|
||||
->distinct()
|
||||
->pluck($column['name'])
|
||||
->filter()
|
||||
->values()
|
||||
->toArray();
|
||||
} catch (\Exception $e) {
|
||||
$dbValues = [];
|
||||
}
|
||||
}
|
||||
|
||||
$allValues = array_values(
|
||||
array_unique(
|
||||
array_merge($staticValues, $dbValues)
|
||||
)
|
||||
);
|
||||
|
||||
$allValues = array_filter($allValues, function ($v) {
|
||||
return $v !== null && $v !== '';
|
||||
});
|
||||
|
||||
$allValues = array_values($allValues);
|
||||
|
||||
$jsColumnName = preg_replace('/[^a-zA-Z0-9_]/', '_', $column['name']);
|
||||
?>
|
||||
|
||||
caption: "{{ e2($captionName) }}",
|
||||
dataType: "string",
|
||||
|
||||
<?php if (in_array($column['name'], $requiredFields)) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
|
||||
lookup: {
|
||||
dataSource: (function () {
|
||||
if (!window.manuelSelectStores) window.manuelSelectStores = {};
|
||||
if (!window.manuelSelectCustomValues) window.manuelSelectCustomValues = {};
|
||||
if (!window.manuelSelectOriginalValues) window.manuelSelectOriginalValues = {};
|
||||
|
||||
if (!window.manuelSelectStores['{{ $jsColumnName }}']) {
|
||||
|
||||
var originalData = [
|
||||
<?php foreach ($allValues as $value) { ?>
|
||||
'{{ addslashes($value) }}',
|
||||
<?php } ?>
|
||||
];
|
||||
|
||||
window.manuelSelectOriginalValues['{{ $jsColumnName }}'] = originalData.slice();
|
||||
window.manuelSelectCustomValues['{{ $jsColumnName }}'] = new Set();
|
||||
|
||||
window.manuelSelectStores['{{ $jsColumnName }}'] =
|
||||
new DevExpress.data.ArrayStore({
|
||||
data: originalData
|
||||
});
|
||||
}
|
||||
|
||||
return window.manuelSelectStores['{{ $jsColumnName }}'];
|
||||
})(),
|
||||
|
||||
allowClearing: true
|
||||
},
|
||||
|
||||
editorOptions: {
|
||||
searchEnabled: true,
|
||||
searchMode: 'contains',
|
||||
searchTimeout: 200,
|
||||
minSearchLength: 0,
|
||||
showClearButton: true,
|
||||
acceptCustomValue: true,
|
||||
|
||||
onCustomItemCreating: function (e) {
|
||||
if (!e.text) {
|
||||
e.customItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var newValue = e.text.trim();
|
||||
|
||||
if (newValue) {
|
||||
var store = window.manuelSelectStores &&
|
||||
window.manuelSelectStores['{{ $jsColumnName }}'];
|
||||
|
||||
var customSet = window.manuelSelectCustomValues &&
|
||||
window.manuelSelectCustomValues['{{ $jsColumnName }}'];
|
||||
|
||||
var originalValues = window.manuelSelectOriginalValues &&
|
||||
window.manuelSelectOriginalValues['{{ $jsColumnName }}'];
|
||||
|
||||
if (store && customSet && originalValues) {
|
||||
store.load().done(function (data) {
|
||||
if (data.indexOf(newValue) === -1) {
|
||||
store.insert(newValue);
|
||||
customSet.add(newValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
e.customItem = newValue;
|
||||
}
|
||||
},
|
||||
|
||||
@if(isset($column['relation']['default']))
|
||||
value: "{{ $column['relation']['default'] }}",
|
||||
|
||||
calculateCellValue: function (rowData) {
|
||||
return rowData.status || "{{ $column['relation']['default'] }}";
|
||||
},
|
||||
@endif
|
||||
|
||||
setCellValue(rowData, value, oldRowData, options) {
|
||||
|
||||
var oldValue = oldRowData['{{ $column['name'] }}'];
|
||||
var newValue = value;
|
||||
|
||||
if (oldValue && oldValue !== newValue) {
|
||||
|
||||
var store = window.manuelSelectStores &&
|
||||
window.manuelSelectStores['{{ $jsColumnName }}'];
|
||||
|
||||
var customSet = window.manuelSelectCustomValues &&
|
||||
window.manuelSelectCustomValues['{{ $jsColumnName }}'];
|
||||
|
||||
if (store && customSet && customSet.has(oldValue)) {
|
||||
store.remove(oldValue);
|
||||
customSet.delete(oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
@if(isset($column['relation']['default']))
|
||||
if (newValue === "" || newValue === null) {
|
||||
newValue = "{{ $column['relation']['default'] }}";
|
||||
}
|
||||
@endif
|
||||
|
||||
var data = oldRowData;
|
||||
value = newValue;
|
||||
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
@@ -0,0 +1,94 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
<?php if(in_array($column['name'], $requiredFields)) {
|
||||
$validationRules = "[{
|
||||
type : 'required'
|
||||
}]";
|
||||
|
||||
} else {
|
||||
$validationRules = "'null'";
|
||||
}
|
||||
?>
|
||||
validationRules: <?php echo $validationRules ?>,
|
||||
width: {{isset($column['relation']['width']) ? $column['relation']['width'] : 200}},
|
||||
dataType: "string",
|
||||
allowSorting: true,
|
||||
allowExporting: true,
|
||||
allowFiltering: true,
|
||||
editCellTemplate: {{$column['name']}}_tagBoxEditorTemplate,
|
||||
lookup: {
|
||||
dataSource : {{$column['name']}}_data,
|
||||
<?php
|
||||
$patternString = $column['relation']['pattern'];
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
$seperator = isset($column['relation']['seperator']) ? $column['relation']['seperator'] : ",";
|
||||
foreach($variables AS $variable) {
|
||||
$patternString = str_replace($variable, "data.".$variable, $patternString);
|
||||
}
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
?>
|
||||
|
||||
valueExpr : function(data) {
|
||||
if(data) {
|
||||
return `{{$patternString}}`;
|
||||
}
|
||||
},
|
||||
displayExpr : function(data) {
|
||||
if(data) {
|
||||
return `{{$patternString}}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
|
||||
},
|
||||
|
||||
cellTemplate(container, options) {
|
||||
const noBreakSpace = '\u00A0';
|
||||
var cellValue = options.value != null ? options.value.split('{{$seperator}}') : [];
|
||||
try {
|
||||
const text = (cellValue).map((element) => options.column.lookup.calculateCellValue(element)).join('{{$seperator}}');
|
||||
container.text(text || noBreakSpace).attr('title', text);
|
||||
} catch(err) {
|
||||
// console.log(err);
|
||||
// console.log("{{$column['name']}}");
|
||||
// console.log(options.value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
calculateFilterExpression(filterValue, selectedFilterOperation, target) {
|
||||
if (target === 'search' && typeof (filterValue) === 'string') {
|
||||
console.log("calculateFilterExpression search");
|
||||
try {
|
||||
return [this.dataField, 'contains', filterValue];
|
||||
} catch (err) {
|
||||
// console.log("calculateFilterExpression search");
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return [this.dataField, 'contains', filterValue];
|
||||
/*
|
||||
return function (data) {
|
||||
console.log("calculateFilterExpression");
|
||||
try {
|
||||
return (data.{{$column['name']}} || []).indexOf(filterValue) !== -1;
|
||||
} catch (err) {
|
||||
// console.log("calculateFilterExpression");
|
||||
console.log(err);
|
||||
}
|
||||
};
|
||||
*/
|
||||
},
|
||||
|
||||
},
|
||||
@@ -0,0 +1,120 @@
|
||||
{
|
||||
dataField: "id",
|
||||
width: 80,
|
||||
allowEditing: false,
|
||||
allowFiltering: true,
|
||||
allowSorting: true,
|
||||
},
|
||||
|
||||
<?php if (!isset($summaryTable)) {
|
||||
?>
|
||||
@include("$path.partials.js-buttons")
|
||||
<?php } ?>
|
||||
@if (isset($inspectionHistoryActive) && $inspectionHistoryActive) {
|
||||
caption: "Insp.",
|
||||
width: 50,
|
||||
alignment: "center",
|
||||
allowFiltering: false,
|
||||
allowSorting: false,
|
||||
allowHeaderFiltering: false,
|
||||
cellTemplate: function(container, options) {
|
||||
var rowId = options.data.id;
|
||||
// Fix type mismatch (string vs int)
|
||||
var hasInspection = inspectionRowIds && inspectionRowIds.some(function (id) { return id == rowId; });
|
||||
|
||||
var iconClass = hasInspection ? "text-primary" : "text-muted";
|
||||
var iconHtml = '<i class="fa fa-image ' + iconClass + '" style="font-size: 16px; cursor: pointer;"></i>';
|
||||
|
||||
$("<div>")
|
||||
.html(iconHtml)
|
||||
.addClass("text-center")
|
||||
.attr("title", hasInspection ? "{{e2('View Inspection History')}}" : "{{e2('No Inspection History')}}")
|
||||
.on("click", function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
var tableName = "{{ $tableName }}";
|
||||
var moduleSlug = "{{ $moduleSlug ?? '' }}";
|
||||
|
||||
if (!tableName || !rowId) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Missing table or row ID.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
$('#modal-popin').modal();
|
||||
$('#modal-popin .block-title').html("Inspection History - Row #" + rowId);
|
||||
$('#modal-popin .block-content').html('<div class="text-center p-3"><i class="fa fa-spinner fa-spin fa-2x"></i><br>{{e2("Loading...")}}</div>');
|
||||
$('#modal-popin .modal-footer').addClass("d-none");
|
||||
|
||||
$.ajax({
|
||||
url: `?ajax=inspection-history`,
|
||||
method: 'GET',
|
||||
data: {
|
||||
table: tableName,
|
||||
row_id: rowId,
|
||||
module_slug: moduleSlug
|
||||
},
|
||||
success: function (response) {
|
||||
$('#modal-popin .block-content').html(response);
|
||||
},
|
||||
error: function () {
|
||||
$('#modal-popin .block-content').html('<div class="alert alert-danger">{{e2("Error: Inspection history could not be loaded.")}}</div>');
|
||||
}
|
||||
});
|
||||
})
|
||||
.appendTo(container);
|
||||
}
|
||||
},
|
||||
@endif
|
||||
<?php if (isset($prependColumns)) {
|
||||
foreach($prependColumns AS $name => $prependColumn) { ?>
|
||||
@include("components.table.datagrid.prepend.".$prependColumn['type'])
|
||||
<?php }
|
||||
} ?>
|
||||
<?php if (isset($blockGroup)) { ?>
|
||||
<?php foreach($blockGroup AS $caption => $columnDatas) { ?>
|
||||
{
|
||||
caption: "<?php echo e2($caption) ?>",
|
||||
columns: [
|
||||
<?php
|
||||
$addedBlockGroup = [];
|
||||
foreach($columnsList AS $column) {
|
||||
if(is_array($column) && isset($column['name']) && in_array($column['name'], $columnDatas)) {
|
||||
|
||||
if(in_array($column['name'], $selectedColumns)) {
|
||||
$show = true;
|
||||
if(isset($blockGroupColumns)) {
|
||||
if(!in_array($column['name'], $blockGroupColumns)) $show = false;
|
||||
}
|
||||
if ($show && isset($column['type'])) { ?>
|
||||
@include("components.table.datagrid.".$column['type'])
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
],
|
||||
},
|
||||
<?php } ?>
|
||||
<?php } else { ?>
|
||||
<?php
|
||||
$addedBlockGroup = [];
|
||||
foreach($columnsList AS $column) {
|
||||
|
||||
if (is_array($column) && isset($column['name']) && in_array($column['name'], $selectedColumns)) {
|
||||
$show = true;
|
||||
if (isset($blockGroupColumns)) {
|
||||
if (!in_array($column['name'], $blockGroupColumns)) $show = false;
|
||||
}
|
||||
if ($show && isset($column['type'])) { ?>
|
||||
@include("components.table.datagrid.".$column['type'])
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php } ?>
|
||||
@@ -0,0 +1,425 @@
|
||||
var dataGrid = $("#dataGrid").dxDataGrid({
|
||||
columnChooser: {
|
||||
enabled: true,
|
||||
mode: columnChooserModes[1].key,
|
||||
position: {
|
||||
my: 'right top',
|
||||
at: 'right bottom',
|
||||
of: '.dx-datagrid-column-chooser-button',
|
||||
},
|
||||
search: {
|
||||
enabled: true,
|
||||
editorOptions: { placeholder: 'Search column' },
|
||||
},
|
||||
selection: {
|
||||
mode: "multiple",
|
||||
recursive: true,
|
||||
selectByClick: true,
|
||||
allowSelectAll: true,
|
||||
},
|
||||
|
||||
},
|
||||
@include("$path.partials.config.options.js-state-storing")
|
||||
|
||||
@include("$path.partials.js-excel")
|
||||
@include("$path.partials.config.options.js-toolbar")
|
||||
|
||||
onCellPrepared: function (e) {
|
||||
@include("$path.partials.events.js-on-cell-prepared")
|
||||
},
|
||||
|
||||
selection: {
|
||||
mode: 'multiple',
|
||||
deferred: false,
|
||||
selectAllMode: 'allPages',
|
||||
allowSelectAll: true,
|
||||
showCheckBoxesMode: 'always'
|
||||
},
|
||||
|
||||
onSelectionChanged(selectedItems) {
|
||||
// const selectionRow = selectedItems.selectedRowsData[0];
|
||||
|
||||
console.log(selectedItems);
|
||||
|
||||
// Remove clicked class from all rows
|
||||
$("#dataGrid .dx-row").removeClass("dx-row-clicked");
|
||||
|
||||
// Add clicked class to selected row
|
||||
if(selectedItems.selectedRowsData && selectedItems.selectedRowsData.length > 0) {
|
||||
var selectedRowKey = selectedItems.selectedRowKeys[0];
|
||||
var rowIndex = dataGrid.getRowIndexByKey(selectedRowKey);
|
||||
if (rowIndex >= 0) {
|
||||
var rowElement = dataGrid.getRowElement(rowIndex);
|
||||
if (rowElement && rowElement.length) {
|
||||
$(rowElement).addClass("dx-row-clicked");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
keyboardNavigation: {
|
||||
enterKeyAction: 'moveFocus',
|
||||
enterKeyDirection: 'row',
|
||||
editOnKeyPress: true,
|
||||
},
|
||||
groupPanel: { visible: false }, // Grouping disabled temporarily
|
||||
|
||||
|
||||
dataSource: dataSource,
|
||||
allowColumnResizing: true,
|
||||
columnResizingMode: "widget",
|
||||
columnAutoWidth: true, // Hücre içeriğine göre genişlik
|
||||
columnMinWidth: 60, // Kısa metinler için fazla boşluk kalmasın
|
||||
renderAsync: true, // Asenkron render performansı artırır
|
||||
allowColumnReordering: true,
|
||||
showColumnLines: true,
|
||||
filterRow: {
|
||||
visible: true,
|
||||
applyFilter: 'auto',
|
||||
},
|
||||
filterPanel: { visible: true },
|
||||
searchPanel: { visible: true },
|
||||
columnFixing: {
|
||||
enabled: true
|
||||
},
|
||||
@include("$path.partials.config.options.js-editing")
|
||||
|
||||
paging: {
|
||||
@if (isset($id) && $id === 'weldlog-employer-view')
|
||||
enabled: false,
|
||||
pageSize: 50,
|
||||
@else
|
||||
pageSize: {{ setting('row_count') }},
|
||||
@endif
|
||||
},
|
||||
headerFilter: {
|
||||
visible: true,
|
||||
search: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
|
||||
customizeColumns: function(columns) {
|
||||
@include("$path.partials.events.js-customize-columns")
|
||||
},
|
||||
|
||||
loadPanel: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
showBorders: true,
|
||||
//!isset($noRemoteOperations) true
|
||||
@if (!isset($noRemoteOperations))
|
||||
remoteOperations: {
|
||||
filtering: true,
|
||||
paging: true,
|
||||
sorting: true,
|
||||
groupPaging: true,
|
||||
grouping: true,
|
||||
summary: true
|
||||
},
|
||||
|
||||
@include("$path.partials.config.options.js-scrolling")
|
||||
|
||||
height: "80vh",
|
||||
@endif
|
||||
|
||||
onEditorPreparing(e) {
|
||||
|
||||
@include("$path.events.js-editor-preparing")
|
||||
|
||||
applyMechanicalEditorState(e);
|
||||
},
|
||||
onRowPrepared: function(e) {
|
||||
// Total footer - sticky Total cell
|
||||
if (e.rowType === 'totalFooter') {
|
||||
// Find TD containing "Total" text
|
||||
$(e.rowElement).find('td').each(function () {
|
||||
if ($(this).text().indexOf('Total') !== -1) {
|
||||
$(this).css({
|
||||
'position': 'sticky',
|
||||
'left': '0',
|
||||
'z-index': '11',
|
||||
'background-color': '#e9ecef',
|
||||
'overflow': 'visible',
|
||||
});
|
||||
$(this).find('.dx-datagrid-summary-item').css({
|
||||
'overflow': 'visible',
|
||||
'white-space': 'nowrap',
|
||||
'text-overflow': 'clip',
|
||||
'min-width': '300px'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (e.rowType === 'data') {
|
||||
if (isMechanicalJointRow(e.data)) {
|
||||
$(e.rowElement).addClass('mechanical-row');
|
||||
} else {
|
||||
$(e.rowElement).removeClass('mechanical-row');
|
||||
}
|
||||
}
|
||||
},
|
||||
onCustomizeLoadOptions: function(loadOptions) {
|
||||
@include("$path.partials.events.js-on-customize-load-options")
|
||||
},
|
||||
onContentReady: function(e) {
|
||||
@include("$path.partials.events.js-on-content-ready")
|
||||
},
|
||||
onEditingStart(e) {
|
||||
var focusedSelector = $("td.dx-focused");
|
||||
var rowIndex = dataGrid.option("focusedRowIndex");
|
||||
var colIndex = dataGrid.option("focusedColumnIndex");
|
||||
try {
|
||||
var dataField = e.column.dataField;
|
||||
var allEntries = JSON.parse(localStorage.getItem("originalData" + rowIndex + colIndex)) || [];
|
||||
allEntries.push(e.data[dataField]);
|
||||
localStorage.setItem("originalData" + rowIndex + colIndex, JSON.stringify(allEntries));
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
onCellValueChanged(e) {
|
||||
if (typeof cellValueChanged === 'function') {
|
||||
cellValueChanged(e);
|
||||
}
|
||||
handleMechanicalCellChange(e);
|
||||
},
|
||||
onInitNewRow(e) {
|
||||
console.log("new row");
|
||||
console.log(e);
|
||||
console.log(selectedData);
|
||||
if (selectedData) {
|
||||
e.data = selectedData;
|
||||
selectedData = null;
|
||||
}
|
||||
},
|
||||
onRowInserting(e) {
|
||||
//logEvent('RowInserting');
|
||||
console.log(e);
|
||||
},
|
||||
|
||||
onRowInserted() {
|
||||
// logEvent('RowInserted');
|
||||
},
|
||||
onRowUpdating() {
|
||||
},
|
||||
onRowUpdated() {
|
||||
// logEvent('RowUpdated');
|
||||
},
|
||||
onRowRemoving() {
|
||||
// logEvent('RowRemoving');
|
||||
},
|
||||
onRowRemoved() {
|
||||
// logEvent('RowRemoved');
|
||||
},
|
||||
onSaving() {
|
||||
console.log("saving start");
|
||||
|
||||
// Prevent multiple save operations
|
||||
if (progressTracker.isActive) {
|
||||
return false; // Cancel save operation
|
||||
}
|
||||
|
||||
// Start progress tracking for batch operations
|
||||
var changeCount = 0;
|
||||
try {
|
||||
var changes = dataGrid.option('editing').changes || [];
|
||||
changeCount = changes.length;
|
||||
} catch (e) {
|
||||
changeCount = 1; // Fallback
|
||||
}
|
||||
|
||||
if (changeCount > 0) {
|
||||
progressTracker.start(changeCount);
|
||||
}
|
||||
},
|
||||
onInitialized: function(e) {
|
||||
if (typeof initialized === 'function') {
|
||||
initialized();
|
||||
}
|
||||
$("#dataGrid td").on("click", function () {
|
||||
logEvent("#dataGrid td");
|
||||
});
|
||||
},
|
||||
onRowClick: function(e) {
|
||||
|
||||
// Remove clicked class from all rows
|
||||
$("#dataGrid .dx-row").removeClass("dx-row-clicked");
|
||||
|
||||
// Add clicked class to selected row
|
||||
if (e.rowType === "data" && e.rowElement) {
|
||||
$(e.rowElement).addClass("dx-row-clicked");
|
||||
|
||||
// Select the row
|
||||
if (e.data && e.data.id !== undefined) {
|
||||
e.component.selectRows([e.data.id], true);
|
||||
}
|
||||
}
|
||||
},
|
||||
onSaved(e) {
|
||||
//logEvent('Saving Success');
|
||||
|
||||
// Complete progress when batch operations are done
|
||||
if (progressTracker.isActive) {
|
||||
progressTracker.completed = progressTracker.total;
|
||||
progressTracker.complete();
|
||||
}
|
||||
},
|
||||
onEditCanceling() {
|
||||
// logEvent('EditCanceling');
|
||||
},
|
||||
onEditCanceled() {
|
||||
// logEvent('EditCanceled');
|
||||
},
|
||||
onFocusedRowChanging(e) {
|
||||
// console.log(e);
|
||||
},
|
||||
|
||||
|
||||
sorting: {
|
||||
mode: "multiple" // or "multiple" | "none"
|
||||
},
|
||||
|
||||
columns: [
|
||||
@include("$path.partials.config.js-columns")
|
||||
],
|
||||
|
||||
summary: {
|
||||
@include("$path.partials.config.js-summary")
|
||||
},
|
||||
|
||||
calculateCustomSummary: function(options) {
|
||||
handleMechanicalCustomSummary(options);
|
||||
},
|
||||
onOptionChanged(e) {
|
||||
if (e.name === 'editing') {
|
||||
const editRowKey = e.component.option('editing.editRowKey');
|
||||
let changes = e.component.option('editing.changes');
|
||||
|
||||
$('#editRowKey').text(editRowKey === null ? 'null' : editRowKey);
|
||||
|
||||
changes = changes.map((change) => ({
|
||||
type: change.type,
|
||||
key: change.type !== 'insert' ? change.key : undefined,
|
||||
data: change.data,
|
||||
}));
|
||||
|
||||
//console.log(changes);
|
||||
}
|
||||
},
|
||||
onCellHoverChanged: function(e) {
|
||||
|
||||
},
|
||||
onCellClick(e) {
|
||||
if (e.rowType == "data") {
|
||||
localStorage.setItem("rowIndex", e.rowIndex);
|
||||
localStorage.setItem("columnIndex", e.columnIndex);
|
||||
localStorage.setItem("cellValue", e.value);
|
||||
} else {
|
||||
localStorage.removeItem("rowIndex");
|
||||
localStorage.removeItem("columnIndex");
|
||||
localStorage.removeItem("cellValue");
|
||||
}
|
||||
|
||||
var copyButton = $("#copyButton");
|
||||
|
||||
if (e.rowType === "data") {
|
||||
// Hücre üzerine gelindiğinde butonu göster
|
||||
var cellElement = $(e.cellElement);
|
||||
var cellOffset = cellElement.offset();
|
||||
|
||||
} else {
|
||||
// Hücreden ayrıldığında butonu gizle
|
||||
copyButton.hide();
|
||||
}
|
||||
///e.component.editCell(e.rowIndex, e.columnIndex);
|
||||
|
||||
},
|
||||
onRowValidating(e) {
|
||||
@include("$path.partials.events.js-on-row-validating")
|
||||
},
|
||||
onFocusedCellChanging: function (e) {
|
||||
e.isHighlighted = true;
|
||||
|
||||
try {
|
||||
var dataRow = e['rows'][e.newRowIndex]['data'];
|
||||
if (typeof focusedCellChanging === 'function') {
|
||||
focusedCellChanging(e, dataRow);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
},
|
||||
onKeyDown: function(e) {
|
||||
//devextreme datagrid shortcut
|
||||
// Klavyeden bir tuşa basıldığında
|
||||
console.log(e);
|
||||
var keyCode = e.event.keyCode;
|
||||
var col = eval(localStorage.getItem("columnIndex"));
|
||||
var row = eval(localStorage.getItem("rowIndex"));
|
||||
|
||||
if (e.event.ctrlKey && e.event.which == 46) {
|
||||
|
||||
//ctrl delete clear value
|
||||
console.log("clear value");
|
||||
console.log(e);
|
||||
|
||||
e.component.cellValue(row, col, null);
|
||||
}
|
||||
|
||||
if (e.event.ctrlKey && e.event.which == 67) {
|
||||
|
||||
//ctrl c
|
||||
console.log("ctrl c");
|
||||
var copyData = e.component.cellValue(row, col);
|
||||
console.log(copyData);
|
||||
localStorage.setItem("copy_value", copyData);
|
||||
}
|
||||
if (e.event.ctrlKey && e.event.which == 86) {
|
||||
|
||||
//ctrl v
|
||||
if (row != 0) {
|
||||
console.log("ctrl v");
|
||||
e.component.editCell(row, col);
|
||||
|
||||
e.component.cellValue(row, col, localStorage.getItem("copy_value"));
|
||||
e.component.closeEditCell();
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
onFocusedCellChanged: function (e) {
|
||||
console.log("onFocusedCellChanged");
|
||||
console.log(e);
|
||||
if (typeof e.row === 'undefined') {
|
||||
|
||||
} else {
|
||||
var dataRow = e.row.data;
|
||||
localStorage.setItem("selectedRowData", JSON.stringify(dataRow));
|
||||
localStorage.setItem("columnIndex", e.columnIndex);
|
||||
localStorage.setItem("rowIndex", e.rowIndex);
|
||||
console.log(dataRow);
|
||||
if (typeof FocusedCellChanged === 'function') {
|
||||
FocusedCellChanged(e, dataRow);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
@include("$path.partials.js-right-menu")
|
||||
|
||||
@if (isset($dataGridOptions)) {!! $dataGridOptions !!}
|
||||
@endif
|
||||
|
||||
onValueChanged: function(e) {
|
||||
if (typeof onValueChanged === 'function') {
|
||||
onValueChanged(e);
|
||||
}
|
||||
},
|
||||
}).dxDataGrid("instance");
|
||||
@@ -0,0 +1,175 @@
|
||||
totalItems: [
|
||||
@if (!isset($disableTotalSummary) || !$disableTotalSummary)
|
||||
@php
|
||||
// Add total summary: count on 'id', sum/avg on whitelisted columns
|
||||
$totalSummaryCount = 0;
|
||||
$maxTotalSummaries = 400;
|
||||
|
||||
// Always add Total count on 'id' first
|
||||
$totalSummaryCount++;
|
||||
@endphp
|
||||
{
|
||||
column: "id",
|
||||
summaryType: "count",
|
||||
displayFormat: "Total: {0}",
|
||||
alignment: "left",
|
||||
width: 300,
|
||||
},
|
||||
@php
|
||||
|
||||
// Define whitelist columns for SUM/AVG
|
||||
if (isset($limitedSummaryColumns)) {
|
||||
// Limited summary for large tables (e.g., Weldlog with 63K rows)
|
||||
$sumColumns = $limitedSummaryColumns;
|
||||
} else {
|
||||
// Full 30+ columns for normal tables
|
||||
$sumColumns = ['quantity', 'dia_inch_1', 'dn_1', 'odmm_1',
|
||||
'diainch_2', 'dn_2', 'odmm_2', 'weight',
|
||||
'pipe_dia', 'unit_weight', 'nps_1', 'nps_2', 'diamm',
|
||||
'requested_quantity', 'received_quantity',
|
||||
'min_dia', 'max_dia', 'min_dia2', 'max_dia2', 'max_thick', 'max_thick2',
|
||||
'qualitication_outside_diameter_min', 'qualitication_outside_diameter_max',
|
||||
'min_outside_diameter', 'max_outside_diameter',
|
||||
'outside_diameter_1', 'outside_diameter_2',
|
||||
'diameter', 'dia_min', 'dia_max'];
|
||||
}
|
||||
|
||||
// Loop through columns and add sum/avg (skip count, already added)
|
||||
foreach($columnsList as $column) {
|
||||
if (is_array($column) && isset($column['name']) && in_array($column['name'], $selectedColumns) && $totalSummaryCount < $maxTotalSummaries) {
|
||||
$summaryType = null;
|
||||
|
||||
// Only whitelisted columns get sum
|
||||
if (in_array($column['name'], $sumColumns)) {
|
||||
$summaryType = 'sum';
|
||||
}
|
||||
|
||||
if ($summaryType) {
|
||||
$totalSummaryCount++;
|
||||
@endphp
|
||||
{
|
||||
column: "{{ $column['name'] }}",
|
||||
selector: "{{ $column['name'] }}",
|
||||
summaryType: "sum",
|
||||
@if ($weldedSummaryFilter) weldedOnly: true, @endif
|
||||
valueFormat: {
|
||||
type: "fixedPoint",
|
||||
precision: 2
|
||||
},
|
||||
displayFormat: "SUM: {0}",
|
||||
alignment: "left"
|
||||
},
|
||||
@php
|
||||
// Add AVG for SUM columns
|
||||
if ($summaryType === 'sum' && $totalSummaryCount < $maxTotalSummaries) {
|
||||
$totalSummaryCount++;
|
||||
@endphp
|
||||
{
|
||||
column: "{{ $column['name'] }}",
|
||||
selector: "{{ $column['name'] }}",
|
||||
summaryType: "avg",
|
||||
@if ($weldedSummaryFilter) weldedOnly: true, @endif
|
||||
valueFormat: {
|
||||
type: "fixedPoint",
|
||||
precision: 2
|
||||
},
|
||||
displayFormat: "AVG: {0}",
|
||||
alignment: "left"
|
||||
},
|
||||
@php
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
@endif
|
||||
]
|
||||
@if (!isset($disableGroupSummary) || !$disableGroupSummary)
|
||||
, groupItems: [
|
||||
@php
|
||||
// Add group summary: count on first column, sum on all numeric columns
|
||||
$summaryCount = 0;
|
||||
// Limit summaries for large tables to prevent memory exhaustion
|
||||
$maxSummaries = (isset($disableTotalSummary) && $disableTotalSummary) ? 20 : 400;
|
||||
$firstCountAdded = false;
|
||||
|
||||
foreach($columnsList as $column) {
|
||||
if(is_array($column) && isset($column['name']) && in_array($column['name'], $selectedColumns) && $summaryCount < $maxSummaries) {
|
||||
$summaryType = null;
|
||||
|
||||
// Allowed SUM columns list
|
||||
if(isset($limitedSummaryColumns)) {
|
||||
// Limited summary for large tables (e.g., Weldlog with 63K rows)
|
||||
$sumColumns = $limitedSummaryColumns;
|
||||
} else {
|
||||
// Full 30+ columns for normal tables
|
||||
$sumColumns =['quantity', 'dia_inch_1', 'dn_1', 'odmm_1',
|
||||
'diainch_2', 'dn_2', 'odmm_2', 'weight',
|
||||
'pipe_dia', 'unit_weight', 'nps_1', 'nps_2', 'diamm',
|
||||
'requested_quantity', 'received_quantity',
|
||||
'min_dia', 'max_dia', 'min_dia2', 'max_dia2', 'max_thick', 'max_thick2',
|
||||
'qualitication_outside_diameter_min', 'qualitication_outside_diameter_max',
|
||||
'min_outside_diameter', 'max_outside_diameter',
|
||||
'outside_diameter_1', 'outside_diameter_2',
|
||||
'diameter', 'dia_min', 'dia_max'];
|
||||
}
|
||||
|
||||
// First column gets count
|
||||
if (!$firstCountAdded) {
|
||||
$summaryType = 'count';
|
||||
$firstCountAdded = true;
|
||||
}
|
||||
// Only allowed columns get sum
|
||||
elseif(in_array($column['name'], $sumColumns)) {
|
||||
$summaryType = 'sum';
|
||||
}
|
||||
|
||||
if ($summaryType) {
|
||||
$summaryCount++;
|
||||
@endphp
|
||||
{
|
||||
column: "{{ $column['name'] }}",
|
||||
selector: "{{ $column['name'] }}",
|
||||
summaryType: "{{ $summaryType }}",
|
||||
@if ($summaryType === 'sum' && $weldedSummaryFilter)
|
||||
weldedOnly: true,
|
||||
@endif
|
||||
@if ($summaryType === 'count')
|
||||
displayFormat: "Count: {0}",
|
||||
showInGroupFooter: false
|
||||
@else
|
||||
valueFormat: {
|
||||
type: "fixedPoint",
|
||||
precision: 2
|
||||
},
|
||||
displayFormat: "SUM: {0}",
|
||||
alignByColumn: true,
|
||||
showInGroupFooter: true
|
||||
@endif
|
||||
},
|
||||
@php
|
||||
// Add AVG for SUM columns
|
||||
if ($summaryType === 'sum' && $summaryCount < $maxSummaries) {
|
||||
$summaryCount++;
|
||||
@endphp
|
||||
{
|
||||
column: "{{ $column['name'] }}",
|
||||
selector: "{{ $column['name'] }}",
|
||||
summaryType: "avg",
|
||||
@if ($weldedSummaryFilter) weldedOnly: true, @endif
|
||||
valueFormat: {
|
||||
type: "fixedPoint",
|
||||
precision: 2
|
||||
},
|
||||
displayFormat: "AVG: {0}",
|
||||
alignByColumn: true,
|
||||
showInGroupFooter: true
|
||||
},
|
||||
@php
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
]
|
||||
@endif
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
if(!in_array($id, $absoluteReadableModules)) {
|
||||
?>
|
||||
<?php if(!isset($summaryTable)) {
|
||||
?>
|
||||
editing: {
|
||||
|
||||
<?php if(isset($onlyAdmin) && $onlyAdmin) { ?>
|
||||
allowUpdating: true,
|
||||
allowAdding: true,
|
||||
allowDeleting: true,
|
||||
<?php } else { ?>
|
||||
<?php if(isAuth($id, "modify")) { ?>
|
||||
allowUpdating: true,
|
||||
<?php } ?>
|
||||
<?php if(isAuth($id, "write")) { ?>
|
||||
allowAdding: true,
|
||||
<?php } ?>
|
||||
<?php if(isAuth($id, "full_control")) { ?>
|
||||
allowDeleting: true,
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
startEditAction: 'click',
|
||||
|
||||
refreshMode: 'repaint',
|
||||
mode: 'batch', // 'batch' | 'cell' | 'form' | 'popup',
|
||||
|
||||
|
||||
},
|
||||
<?php } ?>
|
||||
|
||||
<?php } ?>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
scrolling: {
|
||||
<?php if(isset($id) && $id === 'weldlog-employer-view') { ?>
|
||||
mode: 'infinite',
|
||||
rowRenderingMode: 'infinite',
|
||||
columnRenderingMode: 'standard', // 'infinite' seçimleri kaybettiriyordu, horizontal scroll sırasında checkbox resetleniyordu
|
||||
showScrollbar: 'always',
|
||||
useNative: false
|
||||
<?php } else { ?>
|
||||
mode: 'infinite', // Infinite yerine virtual DOM kullanımı
|
||||
rowRenderingMode: 'infinite',
|
||||
columnRenderingMode: 'standard', // 'infinite' seçimleri kaybettiriyordu, horizontal scroll sırasında checkbox resetleniyordu
|
||||
useNative: false,
|
||||
showScrollbar: 'always',
|
||||
preloadEnabled: true // Akıcı kaydırma için önden yükleme
|
||||
<?php } ?>
|
||||
},
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
stateStoring: {
|
||||
enabled: true,
|
||||
type: "localStorage",
|
||||
storageKey: storageKey,
|
||||
customSave: function(state) {
|
||||
const filteredState = {
|
||||
columns: state.columns
|
||||
};
|
||||
localStorage.setItem(storageKey, JSON.stringify(filteredState));
|
||||
},
|
||||
customLoad: function() {
|
||||
const saved = localStorage.getItem(storageKey);
|
||||
if (saved) {
|
||||
const state = JSON.parse(saved);
|
||||
<?php if(!isset($id) || $id !== 'weldlog-employer-view') { ?>
|
||||
if (state) {
|
||||
var staleFields = ['wps_joint_type_ru', 'joint_release_rfi_no', 'joint_release_rfi_date', 'joint_release_document_no', 'joint_release_document_date', 'rt_release_rfi_no', 'rt_release_rfi_date', 'ut_release_rfi_no', 'ut_release_rfi_date', 'pt_release_rfi_no', 'pt_release_rfi_date', 'mt_release_rfi_no', 'mt_release_rfi_date', 'pmi_release_rfi_no', 'pmi_release_rfi_date', 'vt_release_rfi_no', 'vt_release_rfi_date', 'pwht_release_rfi_no', 'pwht_release_rfi_date', 'ht_release_rfi_no', 'ht_release_rfi_date', 'ferrite_release_rfi_no', 'ferrite_release_rfi_date'];
|
||||
// Remove from columns
|
||||
if (state.columns && Array.isArray(state.columns)) {
|
||||
state.columns = state.columns.filter(function(col) {
|
||||
return !col || staleFields.indexOf(col.dataField) === -1;
|
||||
});
|
||||
}
|
||||
// Remove from filterValue (DevExtreme state key)
|
||||
if (state.filterValue && Array.isArray(state.filterValue)) {
|
||||
for (var si = 0; si < staleFields.length; si++) {
|
||||
state.filterValue = cleanFilterFromField(state.filterValue, staleFields[si]);
|
||||
}
|
||||
if (state.filterValue && state.filterValue.length === 0) {
|
||||
state.filterValue = null;
|
||||
}
|
||||
}
|
||||
// Remove from filter (legacy key)
|
||||
if (state.filter && Array.isArray(state.filter)) {
|
||||
for (var si = 0; si < staleFields.length; si++) {
|
||||
state.filter = cleanFilterFromField(state.filter, staleFields[si]);
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php } ?>
|
||||
return state;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
toolbar: {
|
||||
items: [
|
||||
@include("$path.partials.js-toolbar")
|
||||
@include("$path.partials.js-excel-import")
|
||||
]
|
||||
},
|
||||
|
||||
onToolbarPreparing: function(e) {
|
||||
e.toolbarOptions.items.push({
|
||||
location: 'after',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'refresh',
|
||||
text: 'Reset View',
|
||||
hint: 'Görünümü sıfırla',
|
||||
onClick: function () {
|
||||
localStorage.removeItem(storageKey);
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -0,0 +1,203 @@
|
||||
<style>
|
||||
/* ===== Dropdown/Popup Z-Index Fix ===== */
|
||||
/* Fix for dxTagBox and dxSelectBox popup positioning - renders above datagrid */
|
||||
.dx-overlay-wrapper {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.dx-popup-wrapper,
|
||||
.dx-dropdowneditor-overlay {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
/* Ensure popup content renders above datagrid */
|
||||
.dx-overlay-content {
|
||||
z-index: 10000 !important;
|
||||
}
|
||||
|
||||
/* TagBox/SelectBox dropdown list styling */
|
||||
.dx-list.dx-list-select-decorator-enabled {
|
||||
max-height: 400px !important;
|
||||
}
|
||||
|
||||
/* ===== TagBox Editor Row Height Fix ===== */
|
||||
/* Prevent row height from changing during TagBox editing */
|
||||
.dx-datagrid-rowsview .dx-data-row td {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
/* Keep TagBox editor contained within cell */
|
||||
.dx-datagrid .dx-tagbox {
|
||||
max-height: 34px !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.dx-datagrid .dx-tagbox .dx-texteditor-container {
|
||||
max-height: 32px !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.dx-datagrid .dx-tagbox .dx-tag-container {
|
||||
max-height: 28px !important;
|
||||
overflow: hidden !important;
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
/* Single line tag display in edit mode */
|
||||
.dx-datagrid .dx-tagbox .dx-tag {
|
||||
margin: 2px !important;
|
||||
max-width: 100px !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
}
|
||||
|
||||
/* ===== Disabled State ===== */
|
||||
.datagrid-disabled {
|
||||
opacity: 0.6;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
.datagrid-disabled .dx-datagrid {
|
||||
filter: grayscale(20%);
|
||||
}
|
||||
|
||||
/* Group Summary Styling */
|
||||
.dx-datagrid-group-footer {
|
||||
font-weight: 600;
|
||||
border-top: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
/* Total Footer Styling - Sticky */
|
||||
.dx-datagrid-total-footer {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
font-weight: 600;
|
||||
border-top: 2px solid #495057;
|
||||
}
|
||||
|
||||
.dx-datagrid-total-footer td {
|
||||
padding-top: 10px !important;
|
||||
padding-bottom: 10px !important;
|
||||
vertical-align: middle !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-summary-item {
|
||||
font-weight: 600;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* Force total summary visibility for the first few columns (usually ID/Count) */
|
||||
.dx-datagrid-total-footer td[style*="sticky"] .dx-datagrid-summary-item,
|
||||
.dx-datagrid-total-footer td[aria-colindex="1"] .dx-datagrid-summary-item,
|
||||
.dx-datagrid-total-footer td[aria-colindex="2"] .dx-datagrid-summary-item,
|
||||
.dx-datagrid-total-footer td[aria-colindex="3"] .dx-datagrid-summary-item {
|
||||
overflow: visible !important;
|
||||
white-space: nowrap !important;
|
||||
text-overflow: clip !important;
|
||||
display: inline-block !important;
|
||||
min-width: 300px !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-total-footer .dx-datagrid-summary-item.dx-datagrid-text-content {
|
||||
overflow: visible !important;
|
||||
text-overflow: clip !important;
|
||||
}
|
||||
.mechanical-row {
|
||||
background-color: #f5f5f5 !important;
|
||||
}
|
||||
|
||||
/* Selected Row Highlighting */
|
||||
.dx-datagrid-rowsview .dx-row.dx-selection {
|
||||
background-color: #e3f2fd !important;
|
||||
border-left: 4px solid #2196f3 !important;
|
||||
border-bottom: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-rowsview .dx-row.dx-selection:hover {
|
||||
background-color: #bbdefb !important;
|
||||
border-bottom: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-rowsview .dx-row.dx-selection td {
|
||||
background-color: transparent !important;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* Clicked Row Highlighting - More Visible */
|
||||
.dx-datagrid-rowsview .dx-row.dx-row-clicked {
|
||||
background-color: #fff3cd !important;
|
||||
border-left: 4px solid #ffc107 !important;
|
||||
border-bottom: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-rowsview .dx-row.dx-row-clicked:hover {
|
||||
background-color: #ffe69c !important;
|
||||
border-bottom: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-rowsview .dx-row.dx-row-clicked td {
|
||||
background-color: transparent !important;
|
||||
border-bottom: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-rowsview .dx-row.dx-state-focused,
|
||||
.dx-datagrid-rowsview .dx-row.dx-selection.dx-state-focused {
|
||||
border-bottom: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.dx-datagrid-rowsview .dx-row.dx-state-focused td,
|
||||
.dx-datagrid-rowsview .dx-row.dx-selection.dx-state-focused td {
|
||||
border-bottom: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
/* ===== Scrollbar Visibility Fix (Windows) ===== */
|
||||
/* Force visible scrollbars for DevExtreme scrollable containers */
|
||||
.dx-scrollbar-horizontal.dx-scrollbar-hoverable,
|
||||
.dx-scrollbar-vertical.dx-scrollbar-hoverable {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
/* Make scrollbar thumb more visible/thicker */
|
||||
.dx-scrollbar-hoverable .dx-scrollable-scroll {
|
||||
display: block !important;
|
||||
background-color: rgba(0, 0, 0, 0.4) !important;
|
||||
min-height: 30px !important; /* Visual aid */
|
||||
}
|
||||
|
||||
/* Ensure popup lists have scroll capability exposed */
|
||||
.dx-popup-content .dx-list .dx-scrollable-container {
|
||||
overflow-y: auto !important; /* Fallback for native scrolling if simulation fails */
|
||||
}
|
||||
|
||||
/* Webkit Scrollbar Styling (Chrome/Edge on Windows) */
|
||||
/* Only apply to elements that use native scrolling */
|
||||
.dx-popup-content ::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
.dx-popup-content ::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
.dx-popup-content ::-webkit-scrollbar-thumb {
|
||||
background: #888;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.dx-popup-content ::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
/* Ensure the last row is not hidden by the forced horizontal scrollbar */
|
||||
.dx-datagrid-rowsview .dx-scrollable-content {
|
||||
padding-bottom: 35px !important;
|
||||
}
|
||||
</style>
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
// Adjust column widths for specific field names
|
||||
columns.forEach(function(column) {
|
||||
if (column.dataField) {
|
||||
var fieldName = column.dataField.toLowerCase();
|
||||
if (fieldName.indexOf('drawing') !== -1 ||
|
||||
fieldName.indexOf('report') !== -1 ||
|
||||
fieldName.indexOf('number') !== -1 ||
|
||||
fieldName.indexOf('certificate') !== -1 ||
|
||||
fieldName.indexOf('description') !== -1 ||
|
||||
fieldName.indexOf('remark') !== -1) {
|
||||
if (column.width) {
|
||||
column.width = undefined;
|
||||
}
|
||||
column.minWidth = column.minWidth || 100;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
<?php if(isset($id) && $id === 'weldlog-employer-view') { ?>
|
||||
if (typeof wpsJointTypeRuMapping !== 'undefined' && wpsJointTypeRuMapping && Object.keys(wpsJointTypeRuMapping).length > 0) {
|
||||
if (typeof window.jointTypeToWpsMapping === 'undefined') {
|
||||
window.jointTypeToWpsMapping = {};
|
||||
for (var wpsNo in wpsJointTypeRuMapping) {
|
||||
var jointType = wpsJointTypeRuMapping[wpsNo];
|
||||
if (jointType) {
|
||||
if (!window.jointTypeToWpsMapping[jointType]) {
|
||||
window.jointTypeToWpsMapping[jointType] = [];
|
||||
}
|
||||
window.jointTypeToWpsMapping[jointType].push(wpsNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var columnExists = false;
|
||||
for (var i = 0; i < columns.length; i++) {
|
||||
if (columns[i].dataField === 'wps_joint_type_ru') {
|
||||
columnExists = true;
|
||||
break;
|
||||
}
|
||||
if (columns[i].columns && Array.isArray(columns[i].columns)) {
|
||||
for (var j = 0; j < columns[i].columns.length; j++) {
|
||||
if (columns[i].columns[j].dataField === 'wps_joint_type_ru') {
|
||||
columnExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (columnExists) break;
|
||||
}
|
||||
|
||||
if (!columnExists) {
|
||||
var uniqueJointTypes = {};
|
||||
for (var wpsNo in wpsJointTypeRuMapping) {
|
||||
var jointType = wpsJointTypeRuMapping[wpsNo];
|
||||
if (jointType) {
|
||||
uniqueJointTypes[jointType] = true;
|
||||
}
|
||||
}
|
||||
var allJointTypeValues = Object.keys(uniqueJointTypes).sort();
|
||||
var wpsJointTypeColumn = {
|
||||
dataField: 'wps_joint_type_ru',
|
||||
caption: 'Joint Type RU',
|
||||
visible: true,
|
||||
allowSorting: false,
|
||||
allowFiltering: true,
|
||||
minWidth: 120,
|
||||
calculateCellValue: function(rowData) {
|
||||
var wpsNo = rowData ? rowData.wps_no : null;
|
||||
if (wpsNo && typeof wpsJointTypeRuMapping !== 'undefined' && wpsJointTypeRuMapping[wpsNo]) {
|
||||
return wpsJointTypeRuMapping[wpsNo];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
calculateFilterExpression: function(filterValue, selectedFilterOperation) {
|
||||
if (!filterValue || (Array.isArray(filterValue) && filterValue.length === 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof window.jointTypeToWpsMapping === 'undefined' || !window.jointTypeToWpsMapping) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var selectedValues = Array.isArray(filterValue) ? filterValue : [filterValue];
|
||||
var wpsNumbers = [];
|
||||
|
||||
for (var i = 0; i < selectedValues.length; i++) {
|
||||
var jointType = selectedValues[i];
|
||||
if (window.jointTypeToWpsMapping[jointType]) {
|
||||
wpsNumbers = wpsNumbers.concat(window.jointTypeToWpsMapping[jointType]);
|
||||
}
|
||||
}
|
||||
|
||||
wpsNumbers = wpsNumbers.filter(function(value, index, self) {
|
||||
return self.indexOf(value) === index;
|
||||
});
|
||||
|
||||
if (wpsNumbers.length > 0) {
|
||||
if (wpsNumbers.length === 1) {
|
||||
return ['wps_no', selectedFilterOperation || '=', wpsNumbers[0]];
|
||||
} else if (wpsNumbers.length <= 5) {
|
||||
var orFilters = [];
|
||||
for (var j = 0; j < wpsNumbers.length; j++) {
|
||||
if (j > 0) {
|
||||
orFilters.push('or');
|
||||
}
|
||||
orFilters.push(['wps_no', selectedFilterOperation || '=', wpsNumbers[j]]);
|
||||
}
|
||||
return orFilters;
|
||||
} else {
|
||||
return ['wps_no', 'in', wpsNumbers];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
headerFilter: {
|
||||
dataSource: (typeof existingJointTypes !== 'undefined' && existingJointTypes && existingJointTypes.length > 0)
|
||||
? existingJointTypes.map(function(value) {
|
||||
return { text: value, value: value };
|
||||
})
|
||||
: allJointTypeValues.map(function(value) {
|
||||
return { text: value, value: value };
|
||||
}),
|
||||
allowSelectAll: true
|
||||
}
|
||||
};
|
||||
|
||||
// Find "Information about the welding" group and insert after type_of_welds
|
||||
var foundTypeOfWelds = false;
|
||||
for (var i = 0; i < columns.length; i++) {
|
||||
if (columns[i].caption === 'Information about the welding' && columns[i].columns && Array.isArray(columns[i].columns)) {
|
||||
var weldingColumns = columns[i].columns;
|
||||
for (var j = 0; j < weldingColumns.length; j++) {
|
||||
if (weldingColumns[j].dataField === 'type_of_welds') {
|
||||
// Insert wps_joint_type_ru after type_of_welds
|
||||
weldingColumns.splice(j + 1, 0, wpsJointTypeColumn);
|
||||
foundTypeOfWelds = true;
|
||||
// Add color for wps_joint_type_ru (same as "Information about the welding" group)
|
||||
if (typeof cellColors !== 'undefined') {
|
||||
cellColors['wps_joint_type_ru'] = cellColors['Information about the welding'] || cellColors['type_of_welds'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundTypeOfWelds) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: if type_of_welds not found, add to end of columns
|
||||
if (!foundTypeOfWelds) {
|
||||
columns.push(wpsJointTypeColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php } ?>
|
||||
|
||||
// Process columns (including nested columns in groups)
|
||||
function processColumn(column) {
|
||||
// Skip calculated fields that don't exist in database
|
||||
if (column.dataField === 'wps_joint_type_ru') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (column.dataField && !column.lookup && column.dataType !== 'date' && column.dataType !== 'datetime') {
|
||||
// Skip columns that already have a custom static headerFilter dataSource (e.g. link-search)
|
||||
if (column.headerFilter && column.headerFilter.dataSource && Array.isArray(column.headerFilter.dataSource)) {
|
||||
return;
|
||||
}
|
||||
var columnDataField = column.dataField; // Capture in closure
|
||||
|
||||
column.headerFilter = column.headerFilter || {};
|
||||
|
||||
column.headerFilter.dataSource = new DevExpress.data.CustomStore({
|
||||
key: "value",
|
||||
load: function(loadOptions) {
|
||||
var deferred = $.Deferred();
|
||||
var gridInstance = $("#dataGrid").dxDataGrid("instance");
|
||||
// Use cached filter from main data load (more reliable than getCombinedFilter with remoteOperations)
|
||||
var allFilters = window.__lastDataGridFilter || gridInstance.getCombinedFilter();
|
||||
|
||||
// Remove filter for the current column so headerFilter shows
|
||||
// all possible values while respecting other active filters
|
||||
function removeColumnFilter(filter, fieldName) {
|
||||
if (!filter || !Array.isArray(filter)) return null;
|
||||
// Simple filter: ["field", "op", "value"]
|
||||
if (filter.length >= 2 && typeof filter[0] === 'string' && filter[0] === fieldName) {
|
||||
return null;
|
||||
}
|
||||
// Composite filter: [condition, "and"/"or", condition, ...]
|
||||
if (filter.length >= 3 && Array.isArray(filter[0])) {
|
||||
var conditions = [];
|
||||
var operator = null;
|
||||
for (var i = 0; i < filter.length; i++) {
|
||||
if (typeof filter[i] === 'string') {
|
||||
operator = filter[i];
|
||||
} else if (Array.isArray(filter[i])) {
|
||||
var cleaned = removeColumnFilter(filter[i], fieldName);
|
||||
if (cleaned !== null) {
|
||||
conditions.push(cleaned);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (conditions.length === 0) return null;
|
||||
if (conditions.length === 1) return conditions[0];
|
||||
var result = [conditions[0]];
|
||||
for (var j = 1; j < conditions.length; j++) {
|
||||
result.push(operator || 'and');
|
||||
result.push(conditions[j]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
var cleanFilter = null;
|
||||
if (allFilters && Array.isArray(allFilters)) {
|
||||
cleanFilter = removeColumnFilter(allFilters, columnDataField);
|
||||
}
|
||||
|
||||
if (loadOptions && loadOptions.searchValue) {
|
||||
var searchFilter = [columnDataField, "contains", loadOptions.searchValue];
|
||||
if (cleanFilter) {
|
||||
cleanFilter = [cleanFilter, "and", searchFilter];
|
||||
} else {
|
||||
cleanFilter = searchFilter;
|
||||
}
|
||||
}
|
||||
|
||||
// Make backend request for distinct values
|
||||
$.ajax({
|
||||
url: '{{url("admin/devextreme?table=". $tableName)}}',
|
||||
dataType: 'json',
|
||||
method: 'GET',
|
||||
data: {
|
||||
filter: cleanFilter ? JSON.stringify(cleanFilter) : null,
|
||||
distinctColumn: columnDataField
|
||||
},
|
||||
success: function(result) {
|
||||
console.log("Header filter response for", columnDataField, ":", result);
|
||||
var items = [];
|
||||
|
||||
// Check for error
|
||||
if (result.error) {
|
||||
console.error("Header filter error:", result.error);
|
||||
deferred.reject(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.data && Array.isArray(result.data)) {
|
||||
// Backend already returns formatted items: [{value: "...", text: "..."}]
|
||||
items = result.data;
|
||||
console.log("Header filter: Parsed", items.length, "items from result.data");
|
||||
|
||||
// Check if items are in correct format
|
||||
if (items.length > 0) {
|
||||
console.log("First item sample:", items[0]);
|
||||
}
|
||||
} else {
|
||||
console.warn("Header filter: result.data is not an array", result);
|
||||
// Try to extract from different response format
|
||||
if (result && typeof result === 'object') {
|
||||
console.warn("Response structure:", Object.keys(result));
|
||||
}
|
||||
}
|
||||
|
||||
// Add blanks option if exists
|
||||
if (result.hasBlanks) {
|
||||
items.push({ value: null, text: '(Blanks)' });
|
||||
}
|
||||
|
||||
console.log("Header filter resolved with", items.length, "items for column", columnDataField);
|
||||
deferred.resolve(items);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Header filter AJAX error:", status, error, xhr.responseText);
|
||||
deferred.reject(error);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
columns.forEach(function(column) {
|
||||
// If this is a column group (has columns array), process nested columns
|
||||
if (column.columns && Array.isArray(column.columns)) {
|
||||
column.columns.forEach(function(nestedColumn) {
|
||||
processColumn(nestedColumn);
|
||||
});
|
||||
} else {
|
||||
// If this is a regular column (has dataField), process it
|
||||
processColumn(column);
|
||||
}
|
||||
});
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
<?php if(isset($blockGroup)) {
|
||||
?>
|
||||
|
||||
if(e.rowType === 'header') {
|
||||
|
||||
e.cellElement.css("backgroundColor", cellColors[e.column.dataField]);
|
||||
e.cellElement.css("backgroundColor", cellColors[e.column.caption]);
|
||||
e.cellElement.css("text-align", "center");
|
||||
e.cellElement.css("border", "solid 1px #a1a1a1");
|
||||
|
||||
e.cellElement.attr("title", description[e.column.dataField]);
|
||||
}
|
||||
|
||||
// Style footer summary cells with same colors as headers
|
||||
if((e.rowType === 'totalFooter' || e.rowType === 'groupFooter') && e.summaryItems && e.summaryItems.length > 0) {
|
||||
var bgColor = cellColors[e.column.dataField] || cellColors[e.column.caption];
|
||||
if(bgColor) {
|
||||
e.cellElement.css("backgroundColor", bgColor);
|
||||
e.cellElement.css("border", "2px solid #999");
|
||||
e.cellElement.css("border-radius", "3px");
|
||||
}
|
||||
}
|
||||
<?php } ?>
|
||||
if(mechanicalPlaceholderEnabled && e.rowType === 'data' && mechanicalPlaceholderFields.indexOf(e.column.dataField) !== -1) {
|
||||
if(isMechanicalJointRow(e.data)) {
|
||||
e.cellElement.text(mechanicalPlaceholderText);
|
||||
e.cellElement.addClass('text-muted font-italic');
|
||||
}
|
||||
}
|
||||
|
||||
// Add value hints as tooltips for data cells
|
||||
if(e.rowType === 'data' && e.value && hintColumns.length > 0 && hintColumns.includes(e.column.dataField)) {
|
||||
var cellValue = String(e.value).trim();
|
||||
if(valueHints[cellValue]) {
|
||||
e.cellElement.attr("title", valueHints[cellValue]);
|
||||
}
|
||||
}
|
||||
|
||||
// Calibration Due Date Warning
|
||||
if(e.rowType === 'data' && e.column.dataField === 'calibration_due_date' && e.data.status === 'In use') {
|
||||
var dateStr = e.value;
|
||||
if(dateStr) {
|
||||
var today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
var dueDate = null;
|
||||
|
||||
if (typeof dateStr === 'string') {
|
||||
if (dateStr.includes('.')) {
|
||||
var parts = dateStr.split('.');
|
||||
if (parts.length === 3) {
|
||||
dueDate = new Date(parts[2], parts[1] - 1, parts[0]);
|
||||
}
|
||||
} else {
|
||||
dueDate = new Date(dateStr);
|
||||
}
|
||||
} else if (dateStr instanceof Date) {
|
||||
dueDate = dateStr;
|
||||
}
|
||||
|
||||
if (dueDate && !isNaN(dueDate.getTime())) {
|
||||
dueDate.setHours(0, 0, 0, 0);
|
||||
var diffMs = dueDate - today;
|
||||
var diffDays = Math.round(diffMs / (1000 * 60 * 60 * 24));
|
||||
|
||||
var iconColor = 'text-info';
|
||||
var titleText = 'In Use';
|
||||
var iconClass = 'fa-exclamation-circle'; // Default to exclamation as requested
|
||||
|
||||
if (diffDays < 0) {
|
||||
iconColor = 'text-danger';
|
||||
titleText = 'Expired';
|
||||
} else if (diffDays <= 20) {
|
||||
iconColor = 'text-warning';
|
||||
titleText = 'Due Soon';
|
||||
} else {
|
||||
// Valid future dates
|
||||
// User specifically requested exclamation for cases where coloring is not applied
|
||||
iconColor = 'text-info';
|
||||
titleText = 'Calibration Valid';
|
||||
}
|
||||
|
||||
e.cellElement.append(' <i class="fa ' + iconClass + ' ' + iconColor + '" title="' + titleText + '" style="margin-left: 5px;"></i>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
if(typeof contentReady === 'function') {
|
||||
contentReady(e);
|
||||
}
|
||||
applyMechanicalRowStyles(e.component);
|
||||
applyFocusIdToGrid(e.component);
|
||||
|
||||
// Clear selection ONLY on initial page load, not on scroll (which also triggers onContentReady)
|
||||
if (!window._datagridInitialLoadComplete) {
|
||||
window._datagridInitialLoadComplete = true;
|
||||
if (!focusIdParam) {
|
||||
e.component.clearSelection();
|
||||
$("#dataGrid .dx-row").removeClass("dx-row-clicked");
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
try {
|
||||
/*
|
||||
* updateDimensions ve repaint sürekli repaint döngüsüne neden olduğu için kaldırıldı.
|
||||
* columnAutoWidth: true ayarı otomatik boyutlandırma için yeterlidir.
|
||||
*/
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
<?php if(isset($id) && $id === 'weldlog-employer-view') { ?>
|
||||
setTimeout(function() {
|
||||
var gridInstance = e.component;
|
||||
if (!gridInstance) return;
|
||||
|
||||
// Ensure reverse mapping exists for filtering (needed for onCustomizeLoadOptions)
|
||||
if (typeof wpsJointTypeRuMapping !== 'undefined' && wpsJointTypeRuMapping && Object.keys(wpsJointTypeRuMapping).length > 0) {
|
||||
if (typeof window.jointTypeToWpsMapping === 'undefined') {
|
||||
window.jointTypeToWpsMapping = {};
|
||||
for (var wpsNo in wpsJointTypeRuMapping) {
|
||||
var jointType = wpsJointTypeRuMapping[wpsNo];
|
||||
if (jointType) {
|
||||
if (!window.jointTypeToWpsMapping[jointType]) {
|
||||
window.jointTypeToWpsMapping[jointType] = [];
|
||||
}
|
||||
window.jointTypeToWpsMapping[jointType].push(wpsNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var allColumns = gridInstance.option('columns') || [];
|
||||
|
||||
if (typeof wpsJointTypeRuMapping !== 'undefined' && wpsJointTypeRuMapping && Object.keys(wpsJointTypeRuMapping).length > 0) {
|
||||
var hasWpsColumn = false;
|
||||
var weldingGroup = null;
|
||||
var typeOfWeldsIndex = -1;
|
||||
|
||||
// Find "Information about the welding" group and check if wps_joint_type_ru already exists
|
||||
for (var i = 0; i < allColumns.length; i++) {
|
||||
if (allColumns[i].caption === 'Information about the welding' && allColumns[i].columns) {
|
||||
weldingGroup = allColumns[i];
|
||||
for (var j = 0; j < weldingGroup.columns.length; j++) {
|
||||
if (weldingGroup.columns[j].dataField === 'wps_joint_type_ru') {
|
||||
hasWpsColumn = true;
|
||||
break;
|
||||
}
|
||||
if (weldingGroup.columns[j].dataField === 'type_of_welds') {
|
||||
typeOfWeldsIndex = j;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasWpsColumn && weldingGroup) {
|
||||
var uniqueJointTypes = {};
|
||||
for (var wpsNo in wpsJointTypeRuMapping) {
|
||||
var jointType = wpsJointTypeRuMapping[wpsNo];
|
||||
if (jointType) {
|
||||
uniqueJointTypes[jointType] = true;
|
||||
}
|
||||
}
|
||||
var allJointTypeValues = Object.keys(uniqueJointTypes).sort();
|
||||
var wpsJointTypeColumn = {
|
||||
dataField: 'wps_joint_type_ru',
|
||||
caption: 'Joint Type RU',
|
||||
visible: true,
|
||||
allowSorting: false,
|
||||
allowFiltering: true,
|
||||
minWidth: 120,
|
||||
calculateCellValue: function(rowData) {
|
||||
var wpsNo = rowData ? rowData.wps_no : null;
|
||||
if (wpsNo && typeof wpsJointTypeRuMapping !== 'undefined' && wpsJointTypeRuMapping[wpsNo]) {
|
||||
return wpsJointTypeRuMapping[wpsNo];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
calculateFilterExpression: function(filterValue, selectedFilterOperation) {
|
||||
if (!filterValue || (Array.isArray(filterValue) && filterValue.length === 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof window.jointTypeToWpsMapping === 'undefined' || !window.jointTypeToWpsMapping) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var selectedValues = Array.isArray(filterValue) ? filterValue : [filterValue];
|
||||
var wpsNumbers = [];
|
||||
|
||||
for (var i = 0; i < selectedValues.length; i++) {
|
||||
var jointType = selectedValues[i];
|
||||
if (window.jointTypeToWpsMapping[jointType]) {
|
||||
wpsNumbers = wpsNumbers.concat(window.jointTypeToWpsMapping[jointType]);
|
||||
}
|
||||
}
|
||||
|
||||
wpsNumbers = wpsNumbers.filter(function(value, index, self) {
|
||||
return self.indexOf(value) === index;
|
||||
});
|
||||
|
||||
if (wpsNumbers.length > 0) {
|
||||
if (wpsNumbers.length === 1) {
|
||||
return ['wps_no', selectedFilterOperation || '=', wpsNumbers[0]];
|
||||
} else if (wpsNumbers.length <= 5) {
|
||||
var orFilters = [];
|
||||
for (var j = 0; j < wpsNumbers.length; j++) {
|
||||
if (j > 0) {
|
||||
orFilters.push('or');
|
||||
}
|
||||
orFilters.push(['wps_no', selectedFilterOperation || '=', wpsNumbers[j]]);
|
||||
}
|
||||
return orFilters;
|
||||
} else {
|
||||
return ['wps_no', 'in', wpsNumbers];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
headerFilter: {
|
||||
dataSource: (typeof existingJointTypes !== 'undefined' && existingJointTypes && existingJointTypes.length > 0)
|
||||
? existingJointTypes.map(function(value) {
|
||||
return { text: value, value: value };
|
||||
})
|
||||
: allJointTypeValues.map(function(value) {
|
||||
return { text: value, value: value };
|
||||
}),
|
||||
allowSelectAll: true
|
||||
}
|
||||
};
|
||||
|
||||
// Insert after type_of_welds in the welding group
|
||||
if (weldingGroup && weldingGroup.columns) {
|
||||
if (typeOfWeldsIndex >= 0) {
|
||||
weldingGroup.columns.splice(typeOfWeldsIndex + 1, 0, wpsJointTypeColumn);
|
||||
} else {
|
||||
weldingGroup.columns.push(wpsJointTypeColumn);
|
||||
}
|
||||
// Add color for wps_joint_type_ru (same as "Information about the welding" group)
|
||||
if (typeof cellColors !== 'undefined') {
|
||||
cellColors['wps_joint_type_ru'] = cellColors['Information about the welding'] || cellColors['type_of_welds'];
|
||||
}
|
||||
gridInstance.option('columns', allColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
<?php } ?>
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
if (loadOptions.filter) {
|
||||
var filter = loadOptions.filter;
|
||||
|
||||
function processFilter(filterArray) {
|
||||
if (!Array.isArray(filterArray)) {
|
||||
return filterArray;
|
||||
}
|
||||
|
||||
if (filterArray.length >= 3 && filterArray[0] === 'wps_joint_type_ru') {
|
||||
<?php if(isset($id) && $id === 'weldlog-employer-view') { ?>
|
||||
if (typeof window.jointTypeToWpsMapping !== 'undefined' && window.jointTypeToWpsMapping) {
|
||||
var jointTypeValue = filterArray[2];
|
||||
var wpsNumbers = window.jointTypeToWpsMapping[jointTypeValue];
|
||||
if (wpsNumbers && wpsNumbers.length > 0) {
|
||||
// Remove duplicates
|
||||
wpsNumbers = wpsNumbers.filter(function(value, index, self) {
|
||||
return self.indexOf(value) === index;
|
||||
});
|
||||
|
||||
if (wpsNumbers.length === 1) {
|
||||
return ['wps_no', filterArray[1], wpsNumbers[0]];
|
||||
} else if (wpsNumbers.length <= 5) {
|
||||
var orFilters = [];
|
||||
for (var i = 0; i < wpsNumbers.length; i++) {
|
||||
if (i > 0) {
|
||||
orFilters.push('or');
|
||||
}
|
||||
orFilters.push(['wps_no', filterArray[1], wpsNumbers[i]]);
|
||||
}
|
||||
return orFilters;
|
||||
} else {
|
||||
return ['wps_no', 'in', wpsNumbers];
|
||||
}
|
||||
}
|
||||
return ['wps_no', '=', '__NONE__'];
|
||||
}
|
||||
<?php } else { ?>
|
||||
return null;
|
||||
<?php } ?>
|
||||
}
|
||||
|
||||
var processed = filterArray.map(function(item) {
|
||||
return processFilter(item);
|
||||
}).filter(function(item) {
|
||||
return item !== null;
|
||||
});
|
||||
|
||||
if (processed.length === 0) {
|
||||
return null;
|
||||
} else if (processed.length === 1) {
|
||||
return processed[0];
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
|
||||
var processedFilter = processFilter(filter);
|
||||
if (processedFilter !== null) {
|
||||
loadOptions.filter = processedFilter;
|
||||
} else {
|
||||
loadOptions.filter = null;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
console.log("onRowValidating");
|
||||
console.log(e);
|
||||
|
||||
if(!e.isValid) {
|
||||
// Hataları toplayalım
|
||||
const errorMessages = e.brokenRules.map(rule => {
|
||||
const fieldName = rule.column.caption || rule.column.dataField;
|
||||
return `<li class="list-group-item"><strong>${fieldName}</strong>: ${rule.message}</li>`;
|
||||
}).join("");
|
||||
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: '{{e2("Validation Error")}}',
|
||||
html: `<p>{{e2("There are fields with incorrect values in the table, please correct them:")}}</p><ul class="list-group">${errorMessages}</ul>`,
|
||||
confirmButtonText: '{{e2("OK")}}'
|
||||
});
|
||||
|
||||
}
|
||||
if(typeof initRowValidating === 'function') {
|
||||
initRowValidating(e);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<div id="add-row-tooltip" class="d-none">
|
||||
<strong>
|
||||
{{e2("Shortcuts")}} <br>
|
||||
CTRL + <br>
|
||||
ALT + N
|
||||
</strong>
|
||||
|
||||
</div>
|
||||
<div id="save-tooltip" class="d-none">
|
||||
<strong>
|
||||
{{e2("Shortcuts")}} <br>
|
||||
CTRL + S
|
||||
</strong>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="undo-tooltip" class="d-none">
|
||||
<strong>
|
||||
{{e2("Shortcuts")}} <br>
|
||||
CTRL + Z
|
||||
</strong>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="dx-viewport" style="position: relative;">
|
||||
<div id="leftButton" class="datagrid-navigation-button" style="display: none; z-index:100; position: absolute; left: 10px; top: 50%; transform: translateY(-50%);">
|
||||
<button><i class="fa fa-chevron-left fa-2x"></i></button>
|
||||
</div>
|
||||
<div id="rightButton" class="datagrid-navigation-button" style="display: none; z-index:100; position: absolute; right: 10px; top: 50%; transform: translateY(-50%);">
|
||||
<button><i class="fa fa-chevron-right fa-2x"></i></button>
|
||||
</div>
|
||||
<!-- Progress Bar -->
|
||||
<div id="dataGridProgress" style="display: none; margin-bottom: 15px; padding: 10px; background: #f8f9fa; border-radius: 5px; border: 1px solid #dee2e6;">
|
||||
<div id="dataGridProgressText" style="margin-bottom: 8px; font-weight: 500; color: #495057;">Processing...</div>
|
||||
<div id="dataGridProgressBar"></div>
|
||||
</div>
|
||||
|
||||
<div id="dataGrid" style="position:relative"></div>
|
||||
|
||||
<!-- DataGrid disable overlay -->
|
||||
<div id="dataGridOverlay" style="display: none; position: absolute; top: 60px; left: 0; width: 100%; height: calc(100% - 60px); background: rgba(255,255,255,0.4); z-index: 9999; cursor: not-allowed;">
|
||||
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center;">
|
||||
<i class="fa fa-spinner fa-spin fa-2x" style="color: #007bff;"></i>
|
||||
<div style="margin-top: 10px; font-weight: 500; color: #495057;">Operations in progress...</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Kopyalama butonu için yer tutucu -->
|
||||
<div id="copyButton" style="display: none; position: absolute; cursor: pointer;">
|
||||
<img src="https://img.icons8.com/ios-filled/50/000000/copy.png" style="width: 20px; height: 20px;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php $cssPath = "components.table.datagrid.css"; ?>
|
||||
@include("$cssPath.buttons")
|
||||
@include("$cssPath.scroll-bar")
|
||||
|
||||
<?php if(isset($id) && $id === 'weldlog-employer-view') { ?>
|
||||
<style>
|
||||
/* Minimal adjustments for weldlog-employer-view - let DevExtreme handle most styling */
|
||||
/* Only add minimal fixes if absolutely necessary */
|
||||
</style>
|
||||
<?php } ?>
|
||||
|
||||
@if(isset($blockGroup) && !empty($blockGroup))
|
||||
<div class="datagrid-column-nav" style="margin-top: 10px; display: flex; gap: 10px; overflow-x: auto; padding-bottom: 5px;">
|
||||
@foreach($blockGroup as $groupName => $columnsData)
|
||||
@php
|
||||
$targetColumn = is_array($columnsData) ? ($columnsData[0] ?? null) : null;
|
||||
@endphp
|
||||
@if($targetColumn)
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-outline-secondary"
|
||||
onclick="scrollToColumn('{{ $targetColumn }}', this)">
|
||||
{{ e2($groupName) }}
|
||||
</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
type: 'buttons',
|
||||
fixed: true,
|
||||
fixedPosition: "left",
|
||||
maxWidth: 30,
|
||||
minWidth: 30,
|
||||
buttons: [
|
||||
@if (isAuth($id, "full_control") || (isset($onlyAdmin) && $onlyAdmin))
|
||||
"delete",
|
||||
@endif
|
||||
@if ($id == "deleted-joints")
|
||||
@if (isAuth($id, "write")) {
|
||||
hint: '{{e2("Restore")}}',
|
||||
icon: 'chevrondoubleleft',
|
||||
visible(e) {
|
||||
return !e.row.isEditing;
|
||||
},
|
||||
|
||||
onClick(e) {
|
||||
|
||||
var rowData = e.row;
|
||||
console.log(rowData);
|
||||
if (confirm("{{e2("This line will be restored directly.Do you confirm ? ")}}")) {
|
||||
$.get("?ajax=weldlog-restore", {
|
||||
id: e.row.data.id
|
||||
}, function () {
|
||||
location.reload()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
@endif
|
||||
@if (isAuth($id, "write")) {
|
||||
hint: '{{e2("Clean Restore")}}',
|
||||
icon: 'redo',
|
||||
visible(e) {
|
||||
return !e.row.isEditing;
|
||||
},
|
||||
|
||||
onClick(e) {
|
||||
|
||||
var rowData = e.row;
|
||||
console.log(rowData);
|
||||
if (confirm("{{e2("Do you confirm that this row will be restored cleanly ? ")}}")) {
|
||||
$.get("?ajax=weldlog-restore-clean", {
|
||||
id: e.row.data.id
|
||||
}, function () {
|
||||
location.reload()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
@endif
|
||||
@endif
|
||||
/*
|
||||
{
|
||||
hint: 'Clone',
|
||||
icon: 'copy',
|
||||
visible(e) {
|
||||
return !e.row.isEditing;
|
||||
},
|
||||
|
||||
onClick(e) {
|
||||
|
||||
var rowData = e.row.values;
|
||||
console.log(rowData);
|
||||
|
||||
rowData.forEach(function(value, index) {
|
||||
try {
|
||||
if(typeof dataGrid.cellValue(0, index) === "undefined") {
|
||||
dataGrid.cellValue(0, index, value);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
*/
|
||||
|
||||
],
|
||||
},
|
||||
@@ -0,0 +1,281 @@
|
||||
// Progress tracking variables
|
||||
var progressTracker = {
|
||||
total: 0,
|
||||
completed: 0,
|
||||
isActive: false,
|
||||
|
||||
start: function(total) {
|
||||
this.total = total;
|
||||
this.completed = 0;
|
||||
this.isActive = true;
|
||||
this.showProgress();
|
||||
|
||||
// Disable DataGrid during operations
|
||||
try {
|
||||
if (typeof dataGrid !== 'undefined') {
|
||||
dataGrid.option('disabled', true);
|
||||
$("#dataGrid").addClass('datagrid-disabled');
|
||||
}
|
||||
} catch(e) {
|
||||
console.log('DataGrid disable error:', e);
|
||||
}
|
||||
},
|
||||
|
||||
increment: function() {
|
||||
this.completed++;
|
||||
this.updateProgress();
|
||||
if (this.completed >= this.total) {
|
||||
this.complete();
|
||||
}
|
||||
},
|
||||
|
||||
complete: function() {
|
||||
this.isActive = false;
|
||||
|
||||
// Re-enable DataGrid after operations
|
||||
try {
|
||||
if (typeof dataGrid !== 'undefined') {
|
||||
dataGrid.option('disabled', false);
|
||||
$("#dataGrid").removeClass('datagrid-disabled');
|
||||
}
|
||||
} catch(e) {
|
||||
console.log('DataGrid enable error:', e);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
$("#dataGridProgress").hide();
|
||||
$("#dataGridOverlay").hide();
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
showProgress: function() {
|
||||
$("#dataGridProgress").show();
|
||||
$("#dataGridOverlay").show();
|
||||
this.updateProgress();
|
||||
},
|
||||
|
||||
updateProgress: function() {
|
||||
var percentage = Math.round((this.completed / this.total) * 100);
|
||||
$("#dataGridProgressBar").dxProgressBar("option", "value", percentage);
|
||||
$("#dataGridProgressText").text(`Processing: ${this.completed}/${this.total} (${percentage}%)`);
|
||||
}
|
||||
};
|
||||
|
||||
var dataSource = new DevExpress.data.CustomStore({
|
||||
key: "id",
|
||||
load(loadOptions) {
|
||||
const deferred = $.Deferred();
|
||||
const args = {};
|
||||
|
||||
[
|
||||
'skip',
|
||||
'take',
|
||||
'requireTotalCount',
|
||||
'requireGroupCount',
|
||||
'sort',
|
||||
'filter',
|
||||
'totalSummary',
|
||||
'group',
|
||||
'groupSummary',
|
||||
].forEach((i) => {
|
||||
if (i in loadOptions && isNotEmpty(loadOptions[i])) {
|
||||
args[i] = JSON.stringify(loadOptions[i]);
|
||||
}
|
||||
});
|
||||
|
||||
args['module'] = "{{$id}}";
|
||||
<?php if(isset($weldedSummaryFilter) && $weldedSummaryFilter) { ?>
|
||||
args['excludeMechanicalSummary'] = 1;
|
||||
<?php } ?>
|
||||
<?php
|
||||
$getcolumns = "";
|
||||
if(isset($blockGroupColumns)) {
|
||||
|
||||
if(isset($_SESSION['select-columns'][$tableName])) {
|
||||
$blockGroupColumns = $_SESSION['select-columns'][$tableName];
|
||||
}
|
||||
|
||||
if(isset($alwaysSelectColumns) && is_array($alwaysSelectColumns)) {
|
||||
foreach($alwaysSelectColumns as $forcedColumn) {
|
||||
if(!in_array($forcedColumn, $blockGroupColumns)) {
|
||||
$blockGroupColumns[] = $forcedColumn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!in_array("id",$blockGroupColumns)) {
|
||||
$blockGroupColumns[] = 'id';
|
||||
}
|
||||
|
||||
$getcolumns = "&select=" . json_encode_tr($blockGroupColumns);
|
||||
}
|
||||
?>
|
||||
$.ajax({
|
||||
url: '{{url("admin/devextreme?table=". $tableName)}}<?php echo $getcolumns ?>',
|
||||
dataType: 'json',
|
||||
method: 'GET',
|
||||
data: args,
|
||||
success(result) {
|
||||
deferred.resolve(result.data, {
|
||||
totalCount: result.totalCount,
|
||||
summary: result.summary,
|
||||
groupCount: result.groupCount,
|
||||
});
|
||||
},
|
||||
error(e) {
|
||||
console.log("Data Loading Error");
|
||||
console.log(e);
|
||||
deferred.reject('{{e2("Data Loading Error")}}');
|
||||
},
|
||||
//timeout: 20000,
|
||||
});
|
||||
|
||||
return deferred.promise();
|
||||
},
|
||||
insert: function(values) {
|
||||
var deferred = $.Deferred();
|
||||
values['_token'] = "{{ csrf_token() }}";
|
||||
|
||||
// Start progress tracking
|
||||
if (!progressTracker.isActive) {
|
||||
progressTracker.start(1);
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "{{url("admin/insert/". $tableName)}}",
|
||||
method: "POST",
|
||||
data: values,
|
||||
beforeSend: function(x) {
|
||||
$("#modal-popin .block-content").append("<div class='d-block m-1 btn btn-info' id='ajaxInsert'>Inserting new record...</div>");
|
||||
}
|
||||
})
|
||||
.done(function(e) {
|
||||
$("#ajaxInsert").removeClass("btn-info").addClass("btn-success").html("Record inserted successfully");
|
||||
progressTracker.increment();
|
||||
deferred.resolve(e);
|
||||
})
|
||||
.fail(function(e){
|
||||
progressTracker.increment();
|
||||
$("#ajaxInsert").removeClass("btn-info").addClass("btn-danger").html("Record insertion failed");
|
||||
deferred.reject("{{e2("Insertion failed")}}");
|
||||
});
|
||||
return deferred.promise();
|
||||
},
|
||||
remove: function(key) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
// Start progress tracking
|
||||
if (!progressTracker.isActive) {
|
||||
progressTracker.start(1);
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "{{url("admin/remove/". $tableName)}}",
|
||||
data : {
|
||||
'_token' : "{{ csrf_token() }}",
|
||||
'key' : key,
|
||||
'module' : "{{ $id }}",
|
||||
},
|
||||
beforeSend: function(x) {
|
||||
$("#modal-popin .block-content").append("<div class='d-block m-1 btn btn-info' id='ajax"+key+"'>ID:#"+key+" Deleting...</div>");
|
||||
},
|
||||
method: "DELETE"
|
||||
})
|
||||
.done(function(e) {
|
||||
$(document.getElementById("ajax" + key)).removeClass("btn-info").addClass("btn-success").html("ID:#" + key + " deleted");
|
||||
progressTracker.increment();
|
||||
return deferred.resolve();
|
||||
})
|
||||
.fail(function(e){
|
||||
$(document.getElementById("ajax" + key)).removeClass("btn-info").addClass("btn-danger").html("ID:#" + key + " deletion failed");
|
||||
progressTracker.increment();
|
||||
deferred.reject("Deletion failed");
|
||||
});
|
||||
return deferred.promise();
|
||||
},
|
||||
update: function(key, values) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
// Start progress tracking
|
||||
if (!progressTracker.isActive) {
|
||||
progressTracker.start(1);
|
||||
}
|
||||
|
||||
// console.log("val" + values);
|
||||
$.ajax({
|
||||
url: "{{url("admin/save-json/". $tableName )}}",
|
||||
method: "PUT",
|
||||
data: {
|
||||
'_token' : "{{ csrf_token() }}",
|
||||
values : values,
|
||||
key : key
|
||||
},
|
||||
beforeSend: function(x) {
|
||||
$("#modal-popin .block-content").append("<div class='d-block m-1 alert alert-info' id='ajax"+key+"'>ID:#"+key+" Updating...</div>");
|
||||
}
|
||||
})
|
||||
.done(function(e) {
|
||||
console.log(e);
|
||||
var result = e.trim();
|
||||
var text = result; // Varsayılan olarak result'u text'e ata
|
||||
var type = "success";
|
||||
|
||||
if (result == "weld_log_edit_time_limit") {
|
||||
<?php $hour = setting('weld_log_edit_time_limit', false, 4); ?>
|
||||
text = "{{e2('The data has not been updated, because you cannot update this data anymore because :hour hour has passed. Please contact your administrator.', ['hour' => $hour])}}";
|
||||
type = "warning";
|
||||
Swal.fire('', text, type); // SweetAlert ile sonucu göster
|
||||
$(document.getElementById("ajax" + key))
|
||||
.removeClass("alert-info")
|
||||
.addClass("alert-warning")
|
||||
.html("ID:#" + key + " timeout <br>" + text);
|
||||
} else if (result == "restricted_columns_filled") {
|
||||
text = "{{e2('The data has not been updated, because restricted columns are filled and your user level does not have permission to edit this record. Please contact your administrator.')}}";
|
||||
type = "warning";
|
||||
Swal.fire('', text, type); // SweetAlert ile sonucu göster
|
||||
$(document.getElementById("ajax" + key))
|
||||
.removeClass("alert-info")
|
||||
.addClass("alert-warning")
|
||||
.html("ID:#" + key + " restricted <br>" + text);
|
||||
} else if (result == "0") {
|
||||
text = "Update could not be made, please contact your administrator.";
|
||||
type = "error";
|
||||
Swal.fire('', text, type); // SweetAlert ile sonucu göster
|
||||
$(document.getElementById("ajax" + key))
|
||||
.removeClass("alert-info")
|
||||
.addClass("alert-danger")
|
||||
.html("ID:#" + key + " update error <br>" + text);
|
||||
} else if (isNaN(result)) { // Eğer result bir string ise
|
||||
/*
|
||||
text = result;
|
||||
type = "info";
|
||||
Swal.fire('', text, type); // SweetAlert ile sonucu göster
|
||||
*/
|
||||
$(document.getElementById("ajax" + key))
|
||||
.removeClass("alert-info")
|
||||
.addClass("alert-success")
|
||||
.html("ID:#" + key + " updated <br>" + result);
|
||||
} else {
|
||||
// ID'yi başarı olarak göster ama Swal çalışmasın
|
||||
$(document.getElementById("ajax" + key))
|
||||
.removeClass("alert-info")
|
||||
.addClass("alert-success")
|
||||
.html("ID:#" + key + " updated successfully <br>" + result);
|
||||
}
|
||||
|
||||
progressTracker.increment();
|
||||
return deferred.resolve();
|
||||
})
|
||||
.fail(function(e){
|
||||
$(document.getElementById("ajax" + key))
|
||||
.removeClass("alert-info")
|
||||
.addClass("alert-danger")
|
||||
.html("ID:#" + key + " update failed");
|
||||
progressTracker.increment();
|
||||
deferred.reject("{{e2("Update failed")}}");
|
||||
});
|
||||
|
||||
return deferred.promise();
|
||||
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
@if(isSpecificPermission("import_excel_permission") || isAdmin())
|
||||
{
|
||||
location: 'after',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'upload',
|
||||
hint: '{{e2("Import Excel")}}',
|
||||
onClick: function(e) {
|
||||
$("#excel-import-input").click();
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
export: {
|
||||
enabled: true,
|
||||
formats: ['xlsx', 'pdf'],
|
||||
},
|
||||
onExporting(e) {
|
||||
// Create standardized filename: "ProjectCode_ModuleName_Date_Time"
|
||||
const projectNumber = '{{setting("project_number") ?: "QMS"}}';
|
||||
const currentDate = new Date();
|
||||
const dateStr = currentDate.getDate().toString().padStart(2, '0') + '.' +
|
||||
(currentDate.getMonth() + 1).toString().padStart(2, '0') + '.' +
|
||||
currentDate.getFullYear();
|
||||
const timeStr = currentDate.getHours().toString().padStart(2, '0') + '.' +
|
||||
currentDate.getMinutes().toString().padStart(2, '0');
|
||||
const standardFileName = projectNumber + '_' + '{{$id}}' + '_' + dateStr + '_' + timeStr;
|
||||
|
||||
if (e.format === 'xlsx') {
|
||||
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('{{$id}}');
|
||||
|
||||
DevExpress.excelExporter.exportDataGrid({
|
||||
component: e.component,
|
||||
worksheet,
|
||||
autoFilterEnabled: true,
|
||||
customizeCell: function (options) {
|
||||
|
||||
if (options.gridCell.rowType === "header") {
|
||||
options.excelCell.value = options.gridCell.column.caption || options.gridCell.column.dataField;
|
||||
}
|
||||
|
||||
if (options.gridCell.rowType == 'data') {
|
||||
/*
|
||||
if(options.gridCell.column.dataField == 'welding_position')
|
||||
{
|
||||
//debugging için bu kodu commente taşıdım
|
||||
}
|
||||
*/
|
||||
|
||||
if (options.gridCell.column.dataField && !options.gridCell.column.dataField.includes('date')) {
|
||||
options.excelCell.value = options.gridCell.value; //multiple choice deki aktarım sorununu düzeltmek için gridcell value excelcell value ye taşındı
|
||||
|
||||
}
|
||||
|
||||
// Decimal sayılar için virgül formatı - farklı veri tipleri için kontrol
|
||||
if (options.gridCell.value !== null && options.gridCell.value !== undefined) {
|
||||
var valueStr = options.gridCell.value.toString();
|
||||
|
||||
// Sayısal değer kontrolü (number, string olarak gelen sayılar)
|
||||
if ((typeof options.gridCell.value === 'number' || !isNaN(valueStr)) &&
|
||||
valueStr.includes('.')) {
|
||||
options.excelCell.value = valueStr.replace('.', ',');
|
||||
}
|
||||
// String olarak gelen decimal sayılar için
|
||||
else if (typeof options.gridCell.value === 'string' &&
|
||||
/^\d+\.\d+$/.test(valueStr)) {
|
||||
options.excelCell.value = valueStr.replace('.', ',');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), standardFileName + '.xlsx');
|
||||
});
|
||||
});
|
||||
e.cancel = true;
|
||||
}
|
||||
else if (e.format === 'pdf') {
|
||||
const doc = new jsPDF();
|
||||
DevExpress.pdfExporter.exportDataGrid({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
}).then(() => {
|
||||
doc.save(standardFileName + '.pdf');
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,93 @@
|
||||
// Yeni navigasyon buton davranışları (Optimize Edildi)
|
||||
var fadeDelay;
|
||||
var mouseMoveTimeout;
|
||||
|
||||
$("#dataGrid").on("mousemove", function (e) {
|
||||
// Throttle: Her pikselde değil, 50ms'de bir çalışsın
|
||||
if (mouseMoveTimeout) return;
|
||||
|
||||
mouseMoveTimeout = setTimeout(function () {
|
||||
var gridElement = $("#dataGrid");
|
||||
var containerWidth = gridElement.width();
|
||||
var offsetLeft = gridElement.offset().left;
|
||||
var mouseX = e.pageX - offsetLeft;
|
||||
var threshold = containerWidth * 0.15;
|
||||
|
||||
clearTimeout(fadeDelay);
|
||||
|
||||
if (mouseX < threshold) {
|
||||
$("#leftButton").fadeIn(300);
|
||||
$("#rightButton").fadeOut(300);
|
||||
} else if (mouseX > containerWidth - threshold) {
|
||||
$("#rightButton").fadeIn(300);
|
||||
$("#leftButton").fadeOut(300);
|
||||
} else {
|
||||
fadeDelay = setTimeout(function () {
|
||||
$(".navigation-button").fadeOut(300);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
mouseMoveTimeout = null;
|
||||
}, 50);
|
||||
}).on("mouseleave", function () {
|
||||
fadeDelay = setTimeout(function () {
|
||||
$(".navigation-button").fadeOut(300);
|
||||
}, 300);
|
||||
});
|
||||
|
||||
$("#leftButton button").click(function () {
|
||||
var grid = $("#dataGrid").dxDataGrid("instance");
|
||||
var scrollable = grid.getScrollable();
|
||||
var scrollPos = scrollable.scrollLeft();
|
||||
var clientWidth = scrollable.clientWidth();
|
||||
|
||||
scrollable.scrollTo({ left: scrollPos - clientWidth });
|
||||
});
|
||||
|
||||
$("#rightButton button").click(function () {
|
||||
var grid = $("#dataGrid").dxDataGrid("instance");
|
||||
var scrollable = grid.getScrollable();
|
||||
var scrollPos = scrollable.scrollLeft();
|
||||
var clientWidth = scrollable.clientWidth();
|
||||
|
||||
scrollable.scrollTo({ left: scrollPos + clientWidth });
|
||||
});
|
||||
|
||||
// Butona tıklayınca kopyalama işlemi
|
||||
$("#copyButton").on("click", function () {
|
||||
var cellValue = $(this).data("cellValue");
|
||||
|
||||
// Hücre içeriğini kopyala
|
||||
navigator.clipboard.writeText(cellValue).then(function () {
|
||||
// alert("Hücre içeriği kopyalandı: " + cellValue);
|
||||
Swal.fire('Copied', cellValue);
|
||||
}, function (err) {
|
||||
console.error("Kopyalama başarısız: ", err);
|
||||
});
|
||||
|
||||
// Butonu gizle
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
// Clear selection when clicking outside the grid
|
||||
$(document).on("click", function (e) {
|
||||
// Check if click is outside the dataGrid
|
||||
if (!$(e.target).closest("#dataGrid").length &&
|
||||
!$(e.target).closest(".dx-popup").length &&
|
||||
!$(e.target).closest(".dx-overlay").length &&
|
||||
!$(e.target).closest(".dx-toolbar").length &&
|
||||
!$(e.target).closest(".dx-scrollbar").length &&
|
||||
!$(e.target).closest(".dx-scrollable").length &&
|
||||
!$(e.target).closest(".navigation-button").length) {
|
||||
|
||||
// Clear selection
|
||||
if (dataGrid) {
|
||||
dataGrid.clearSelection();
|
||||
$("#dataGrid .dx-row").removeClass("dx-row-clicked");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@include("$path.partials.js-shortcuts")
|
||||
@@ -0,0 +1,395 @@
|
||||
// Load module-specific setCellValue function (if exists) before initSetCellValue
|
||||
@includeIf($path . '.js.set-cell-value.' . $id)
|
||||
|
||||
function initSetCellValue(datas) {
|
||||
// console.log("initSetCellValue");
|
||||
// console.log(datas);
|
||||
if (typeof setCellValue == 'function') {
|
||||
setCellValue(datas);
|
||||
}
|
||||
}
|
||||
console.log("Module Name: {{$id}}");
|
||||
@include("$path.partials.js-data-source")
|
||||
|
||||
function logEvent(text, description = '', type = 'success') {
|
||||
console.log(text);
|
||||
Swal.fire(
|
||||
text,
|
||||
description,
|
||||
type
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
var cellColors = [];
|
||||
@php
|
||||
// Define colors array in helper too if needed, or rely on variables
|
||||
// Ideally this should be passed from somewhere or defined once
|
||||
$colors = [
|
||||
'#e8e8e8', // Açık gri
|
||||
'#d1e8f0', // Açık mavi
|
||||
'#d8f0d1', // Açık yeşil
|
||||
'#f0e8d1', // Açık sarı
|
||||
'#e8d1e8', // Açık mor
|
||||
'#f0d1d1', // Açık kırmızı
|
||||
'#d1e0e8', // Açık mavi-gri
|
||||
'#e8e0d1', // Açık bej
|
||||
'#d1e8d8', // Açık yeşil-mavi
|
||||
'#e8d8d1', // Açık pembe
|
||||
'#e8d1e8', // Açık lavanta
|
||||
'#d1e8e8', // Açık cyan
|
||||
'#e8d1d1', // Açık pembe-gri
|
||||
'#d8f0d8', // Açık mint
|
||||
'#f0e0d1', // Açık şeftali
|
||||
'#d1e0e0', // Açık teal
|
||||
'#e8e8d1', // Açık krem
|
||||
'#e8d1e8', // Açık mor-gri
|
||||
'#d1d1e8', // Açık indigo
|
||||
'#e8d8d8', // Açık somon
|
||||
'#e8e8f0', // Açık periwinkle
|
||||
'#d1e8d1', // Açık nane
|
||||
'#f0e8d8', // Açık kayısı
|
||||
'#d8f0d1', // Açık limon
|
||||
'#d1e0e8', // Açık gök mavisi
|
||||
'#e8d1e8', // Açık orkide
|
||||
'#e8d1d1', // Açık gül
|
||||
'#d1e8d8', // Açık deniz yeşili
|
||||
'#e8d8d1', // Açık şampanya
|
||||
'#e8e8e8', // Açık gümüş
|
||||
'#d1d1e8', // Açık lavanta-gri
|
||||
'#e8e8d8', // Açık altın
|
||||
'#d8f0d8', // Açık zümrüt
|
||||
'#d1e0d1', // Açık zeytin
|
||||
'#e8d1e8', // Açık mercan
|
||||
'#e8d1e8', // Açık menekşe
|
||||
'#d1e8d1', // Açık adaçayı
|
||||
'#f0d8d8', // Açık gül pembe
|
||||
'#e8e0d1', // Açık kum
|
||||
'#d1d1e8', // Açık yıldız mavisi
|
||||
'#e8d8d8', // Açık somon pembe
|
||||
'#d8f0d1', // Açık bahar yeşili
|
||||
'#d1e0e0', // Açık buz mavisi
|
||||
'#e8d1e8', // Açık leylak
|
||||
'#d1e8d1', // Açık toprak
|
||||
'#d1e8d8', // Açık okyanus
|
||||
'#e8d8d1', // Açık şeftali krem
|
||||
'#e8e8f0', // Açık gece mavisi
|
||||
'#d1d1d1', // Açık kömür
|
||||
'#e8e8d1', // Açık altın sarısı
|
||||
'#e8d1e8', // Açık iris
|
||||
'#d1e0e8', // Açık gök kuşağı
|
||||
'#e8d1d1', // Açık inci
|
||||
'#d8f0d8', // Açık yosun
|
||||
'#d1e8d1', // Açık nane yeşili
|
||||
'#e8d8d8', // Açık mercan pembe
|
||||
'#e8d1d1', // Açık kum bej
|
||||
'#d1d1e8', // Açık gök mavisi
|
||||
'#e8e8d8', // Açık altın krem
|
||||
'#e8e0d1', // Açık fildişi
|
||||
'#d1e0d1', // Açık yaprak yeşili
|
||||
'#e8d1e8', // Açık orkide pembe
|
||||
'#d8f0d1', // Açık limon yeşili
|
||||
'#d1e8d8', // Açık deniz köpüğü
|
||||
'#e8d1e8', // Açık şeftali altın
|
||||
'#e8d1e8', // Açık menekşe mavi
|
||||
'#d1e0e0', // Açık buz kristali
|
||||
'#e8d1d1', // Açık gül altın
|
||||
'#e8e8e8', // Açık gümüş beyaz
|
||||
'#d1e8d1', // Açık nane kristali
|
||||
'#e8d8d8', // Açık somon altın
|
||||
'#d8f0d8', // Açık zümrüt yeşili
|
||||
'#d1d1e8', // Açık yıldız gecesi
|
||||
'#e8e8d1', // Açık altın beyaz
|
||||
'#e8d1d1', // Açık kum altın
|
||||
'#d1e0e8', // Açık gök kristali
|
||||
'#e8d1e8', // Açık leylak pembe
|
||||
'#e8e8f0', // Açık periwinkle beyaz
|
||||
'#d1e8d8', // Açık deniz kristali
|
||||
'#e8d8d1', // Açık şeftali beyaz
|
||||
'#e8d1e8', // Açık iris beyaz
|
||||
'#d1d1d1', // Açık kömür beyaz
|
||||
'#e8e8d8', // Açık altın kristali
|
||||
'#d8f0d1', // Açık bahar kristali
|
||||
'#d1e0d1', // Açık zeytin beyaz
|
||||
'#e8d1d1', // Açık mercan kristali
|
||||
'#f0f0e0', // Açık kum kristali
|
||||
'#e8f8e8', // Açık adaçayı beyaz
|
||||
'#f8f0f0', // Açık gül kristali
|
||||
'#f0e8f0', // Açık mor beyaz
|
||||
'#e8e8f8', // Açık yıldız kristali
|
||||
'#f8f8e8', // Açık altın adaçayı
|
||||
'#f0f8f0', // Açık zümrüt kristali
|
||||
'#e8f0f8', // Açık gök adaçayı
|
||||
'#f8e8f0', // Açık leylak kristali
|
||||
'#f0f0f8', // Açık periwinkle adaçayı
|
||||
'#e8f8f0', // Açık deniz adaçayı
|
||||
'#f8f8e8', // Açık şeftali adaçayı
|
||||
'#f0e8f8', // Açık iris adaçayı
|
||||
'#e8e8e0', // Açık kömür adaçayı
|
||||
'#f8f8f0', // Açık altın adaçayı kristali
|
||||
'#f0f8e8', // Açık bahar adaçayı
|
||||
'#e8f0e0', // Açık zeytin adaçayı
|
||||
'#f8e8e8', // Açık mercan adaçayı
|
||||
'#f0f0e0', // Açık kum adaçayı
|
||||
'#e8f8e8', // Açık adaçayı kristali
|
||||
'#f8f0f0', // Açık gül adaçayı
|
||||
'#f0e8f0', // Açık mor adaçayı
|
||||
'#e8e8f8', // Açık yıldız adaçayı
|
||||
'#f8f8e8', // Açık altın adaçayı beyaz
|
||||
'#f0f8f0', // Açık zümrüt adaçayı
|
||||
'#e8f0f8', // Açık gök adaçayı beyaz
|
||||
];
|
||||
@endphp
|
||||
|
||||
var description = [];
|
||||
@php
|
||||
$desc = db("column_descriptions") -> where("module_name", $id) -> get() -> pluck("description", "column_name");
|
||||
@endphp
|
||||
description = @json($desc);
|
||||
console.log(description);
|
||||
|
||||
// Value hints
|
||||
@php
|
||||
$valueHintsConfig = get_value_hints($tableName);
|
||||
@endphp
|
||||
var valueHints = @json($valueHintsConfig['hints'] ?? []);
|
||||
var hintColumns = @json($valueHintsConfig['columns'] ?? []);
|
||||
|
||||
@if (isset($blockGroup))
|
||||
@php $colorIndex = 0; @endphp
|
||||
@foreach($blockGroup as $blockTitle => $columns)
|
||||
@php $currentColor = $colors[$colorIndex] ?? '#ffffff'; @endphp
|
||||
cellColors['{{ $blockTitle }}'] = "{{ $currentColor }}";
|
||||
@foreach($columns as $column)
|
||||
cellColors['{{ $column }}'] = "{{ $currentColor }}";
|
||||
@endforeach
|
||||
@php $colorIndex++; @endphp
|
||||
@endforeach
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
// Helper function to remove field from filter array recursively
|
||||
function cleanFilterFromField(filter, fieldName) {
|
||||
if (!filter || !Array.isArray(filter)) {
|
||||
return filter;
|
||||
}
|
||||
var result = [];
|
||||
for (var i = 0; i < filter.length; i++) {
|
||||
var item = filter[i];
|
||||
if (Array.isArray(item)) {
|
||||
// Check if this is a filter condition [field, operator, value]
|
||||
if (item.length >= 2 && item[0] === fieldName) {
|
||||
// Skip this filter condition
|
||||
continue;
|
||||
}
|
||||
// Recursively clean nested arrays
|
||||
var cleaned = cleanFilterFromField(item, fieldName);
|
||||
if (cleaned && cleaned.length > 0) {
|
||||
result.push(cleaned);
|
||||
}
|
||||
} else if (typeof item === 'string' && (item === 'and' || item === 'or' || item === 'not')) {
|
||||
// Keep logical operators
|
||||
result.push(item);
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
}
|
||||
// Clean up consecutive logical operators
|
||||
var cleanedResult = [];
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
if (typeof result[i] === 'string' && (result[i] === 'and' || result[i] === 'or' || result[i] === 'not')) {
|
||||
if (cleanedResult.length > 0 && typeof cleanedResult[cleanedResult.length - 1] !== 'string') {
|
||||
cleanedResult.push(result[i]);
|
||||
}
|
||||
} else {
|
||||
cleanedResult.push(result[i]);
|
||||
}
|
||||
}
|
||||
return cleanedResult;
|
||||
}
|
||||
|
||||
@if (isset($id) && $id === 'weldlog')
|
||||
try {
|
||||
const saved = localStorage.getItem(storageKey);
|
||||
if (saved) {
|
||||
const state = JSON.parse(saved);
|
||||
var hasStaleField = false;
|
||||
var staleWeldlogFields = ['wps_joint_type_ru', 'joint_release_rfi_no', 'joint_release_rfi_date', 'joint_release_document_no', 'joint_release_document_date', 'rt_release_rfi_no', 'rt_release_rfi_date', 'ut_release_rfi_no', 'ut_release_rfi_date', 'pt_release_rfi_no', 'pt_release_rfi_date', 'mt_release_rfi_no', 'mt_release_rfi_date', 'pmi_release_rfi_no', 'pmi_release_rfi_date', 'vt_release_rfi_no', 'vt_release_rfi_date', 'pwht_release_rfi_no', 'pwht_release_rfi_date', 'ht_release_rfi_no', 'ht_release_rfi_date', 'ferrite_release_rfi_no', 'ferrite_release_rfi_date'];
|
||||
|
||||
// Check columns
|
||||
if (state && state.columns && Array.isArray(state.columns)) {
|
||||
hasStaleField = state.columns.some(function (col) {
|
||||
return col && staleWeldlogFields.indexOf(col.dataField) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
// Check filterValue and filter
|
||||
if (!hasStaleField && state) {
|
||||
const filterStr = JSON.stringify(state.filterValue || state.filter || '');
|
||||
hasStaleField = staleWeldlogFields.some(function(f) { return filterStr.indexOf(f) !== -1; });
|
||||
}
|
||||
|
||||
if (hasStaleField) {
|
||||
localStorage.removeItem(storageKey);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error cleaning localStorage for weldlog:', e);
|
||||
try {
|
||||
localStorage.removeItem(storageKey);
|
||||
} catch (e2) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
@endif
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const focusIdParam = urlParams.get('focus_id') || urlParams.get('id');
|
||||
let focusHighlightApplied = false;
|
||||
|
||||
function normalizeFocusValue(value) {
|
||||
if (!value) return null;
|
||||
var trimmed = value.toString().trim();
|
||||
if (!trimmed.length) return null;
|
||||
var numeric = Number(trimmed);
|
||||
return isNaN(numeric) ? trimmed : numeric;
|
||||
}
|
||||
|
||||
function applyFocusIdToGrid(gridInstance) {
|
||||
if (!focusIdParam || focusHighlightApplied || !gridInstance) {
|
||||
return;
|
||||
}
|
||||
var focusValue = normalizeFocusValue(focusIdParam);
|
||||
if (focusValue === null || typeof gridInstance.columnOption !== 'function') {
|
||||
return;
|
||||
}
|
||||
focusHighlightApplied = true;
|
||||
try {
|
||||
gridInstance.option('focusedRowEnabled', true);
|
||||
gridInstance.option('focusedRowKey', focusValue);
|
||||
} catch (err) { }
|
||||
|
||||
var idColumn = gridInstance.columnOption('id');
|
||||
if (idColumn) {
|
||||
try {
|
||||
gridInstance.columnOption('id', 'filterValue', focusValue);
|
||||
gridInstance.columnOption('id', 'selectedFilterOperation', '=');
|
||||
gridInstance.option('filterValue', ['id', '=', focusValue]);
|
||||
} catch (err) { }
|
||||
} else if (typeof gridInstance.searchByText === 'function') {
|
||||
gridInstance.searchByText(String(focusValue));
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
if (typeof gridInstance.getRowIndexByKey !== 'function') {
|
||||
return;
|
||||
}
|
||||
var rowIndex = gridInstance.getRowIndexByKey(focusValue);
|
||||
if (rowIndex >= 0) {
|
||||
try {
|
||||
gridInstance.option('focusedRowIndex', rowIndex);
|
||||
var rowElement = gridInstance.getRowElement(rowIndex);
|
||||
if (rowElement && rowElement.length && gridInstance.getScrollable) {
|
||||
var scrollable = gridInstance.getScrollable();
|
||||
if (scrollable && scrollable.scrollToElement) {
|
||||
scrollable.scrollToElement(rowElement);
|
||||
}
|
||||
}
|
||||
} catch (err) { }
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.scrollToColumn = function(columnName, btnElement) {
|
||||
var dataGrid = $("#dataGrid").dxDataGrid("instance");
|
||||
if (!dataGrid) return;
|
||||
|
||||
// Highlight button
|
||||
if (btnElement) {
|
||||
$(".datagrid-column-nav button").removeClass("btn-primary").addClass("btn-outline-secondary");
|
||||
$(btnElement).removeClass("btn-outline-secondary").addClass("btn-primary");
|
||||
}
|
||||
|
||||
// Ensure the column is visible
|
||||
dataGrid.columnOption(columnName, "visible", true);
|
||||
|
||||
setTimeout(function() {
|
||||
var columnIndex = dataGrid.columnOption(columnName, "visibleIndex");
|
||||
if(columnIndex === undefined || columnIndex === -1) return;
|
||||
|
||||
var scrollable = dataGrid.getScrollable();
|
||||
if(!scrollable) return;
|
||||
|
||||
// Sum widths approach (0-based) to ensure stable scrolling
|
||||
var visibleColumns = dataGrid.getVisibleColumns();
|
||||
var totalWidth = 0;
|
||||
var targetFound = false;
|
||||
|
||||
for(var i=0; i < visibleColumns.length; i++) {
|
||||
var col = visibleColumns[i];
|
||||
|
||||
// Stop if we reached target
|
||||
if(col.visibleIndex === columnIndex || col.dataField === columnName || col.name === columnName) {
|
||||
targetFound = true;
|
||||
// If target itself is fixed left, we scroll to 0.
|
||||
if(col.fixed && (col.fixedPosition === "left" || !col.fixedPosition)) {
|
||||
totalWidth = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip fixed columns (left) as they don't contribute to scrollable area offset
|
||||
if (col.fixed && (col.fixedPosition === "left" || !col.fixedPosition)) continue;
|
||||
|
||||
// Add width: prefer visibleWidth (rendered), fallback to width option, fallback to 100
|
||||
var w = col.visibleWidth || col.width || 100;
|
||||
totalWidth += w;
|
||||
}
|
||||
|
||||
if (targetFound) {
|
||||
scrollable.scrollTo({ left: totalWidth });
|
||||
}
|
||||
|
||||
}, 200);
|
||||
}
|
||||
|
||||
window.openPdfModal = function(url, title) {
|
||||
var modal = $('#modal-popin');
|
||||
modal.find('.block-title').html(title || 'PDF Preview');
|
||||
|
||||
// Set to extra large for better viewing
|
||||
modal.find('.modal-dialog').removeClass('modal-lg').addClass('modal-xl');
|
||||
|
||||
// Add a loading spinner while PDF is loading
|
||||
modal.find('.block-content').html('<div class="text-center p-5"><i class="fa fa-spinner fa-spin fa-3x"></i><br>Loading PDF...</div>');
|
||||
|
||||
// Use iframe for native browser PDF viewer
|
||||
var iframe = $('<iframe>')
|
||||
.attr('src', url)
|
||||
.addClass('pdf-preview')
|
||||
.css({
|
||||
'width': '100%',
|
||||
'height': '85vh',
|
||||
'border': 'none',
|
||||
'display': 'none'
|
||||
})
|
||||
.on('load', function() {
|
||||
modal.find('.fa-spinner').parent().remove();
|
||||
$(this).show();
|
||||
});
|
||||
|
||||
modal.find('.block-content').append(iframe);
|
||||
|
||||
modal.find('.modal-footer').hide();
|
||||
modal.modal('show');
|
||||
|
||||
modal.one('hidden.bs.modal', function() {
|
||||
modal.find('.block-content').empty();
|
||||
modal.find('.modal-footer').show();
|
||||
modal.find('.modal-dialog').removeClass('modal-xl').addClass('modal-lg');
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
// Progress Bar initialize
|
||||
$("#dataGridProgressBar").dxProgressBar({
|
||||
min: 0,
|
||||
max: 100,
|
||||
value: 0,
|
||||
statusFormat: function (ratio) {
|
||||
return Math.round(ratio * 100) + "%";
|
||||
},
|
||||
showStatus: true
|
||||
});
|
||||
|
||||
$("#deleteButton").dxButton({
|
||||
text: "Delete Selected",
|
||||
onClick: function () {
|
||||
// Prevent multiple operations
|
||||
if (progressTracker.isActive) {
|
||||
alert("Please wait for current operation to complete.");
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedRowKeys = dataGrid.getSelectedRowKeys();
|
||||
if (selectedRowKeys.length > 0) {
|
||||
var store = dataGrid.getDataSource().store();
|
||||
var promises = [];
|
||||
|
||||
// Start progress tracking for multiple deletion
|
||||
progressTracker.start(selectedRowKeys.length);
|
||||
|
||||
selectedRowKeys.forEach(function (key) {
|
||||
promises.push(store.remove(key));
|
||||
});
|
||||
$.when.apply($, promises).done(function () {
|
||||
dataGrid.refresh();
|
||||
}).fail(function () {
|
||||
alert("Deletion failed for some rows.");
|
||||
});
|
||||
} else {
|
||||
alert("No rows selected.");
|
||||
}
|
||||
}
|
||||
});
|
||||
$(document).on("dxcontextmenu", function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
@foreach($columnsList as $column)
|
||||
@if (is_array($column) && isset($column['name']) && in_array($column['name'], $selectedColumns))
|
||||
@if (isset($column['type']) && $column['type'] == "auto-complete")
|
||||
@php
|
||||
$url = url("admin/autocomplete/". ($column['relation']['table'] ?? ''). "/". ($column['relation']['column'] ?? ''). "?with-column");
|
||||
@endphp
|
||||
@if (isset($column['relation']) && $column['relation'] != "" && isset($column['relation']['column']))
|
||||
var {{ $column['name'] }}_data;
|
||||
var {{ $column['name'] }}_lookupDataSource = {
|
||||
store: new DevExpress.data.CustomStore({
|
||||
key: "{{ $column['relation']['column'] }}",
|
||||
loadMode: "raw",
|
||||
load: function () {
|
||||
var d = $.Deferred();
|
||||
return $.getJSON("{{ $url }}").done(function (jsonData) {
|
||||
d.resolve(jsonData);
|
||||
});
|
||||
}
|
||||
}),
|
||||
sort: "{{ $column['relation']['column'] }}"
|
||||
};
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if (isset($column['relation']['datas']))
|
||||
const {{ $column['name'] }}_data = @json($column['relation']['datas']);
|
||||
@includeIf("$path.template.js-{$column['type']}")
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
@@ -0,0 +1,34 @@
|
||||
<div id="jsonPopup"></div>
|
||||
<script>
|
||||
var jsonPopupInstance = null;
|
||||
|
||||
function showJsonPopup(jsonString, rowData) {
|
||||
var prettyJson;
|
||||
try {
|
||||
prettyJson = JSON.stringify(JSON.parse(jsonString), null, 4);
|
||||
} catch(e) {
|
||||
prettyJson = jsonString;
|
||||
}
|
||||
if(!jsonPopupInstance) {
|
||||
$("#jsonPopup").dxPopup({
|
||||
title: "{{e2("Deleted Data")}}",
|
||||
contentTemplate: function() {
|
||||
return $("<pre>").css({ "max-height": "100vh", "overflow": "auto" }).text(prettyJson);
|
||||
},
|
||||
width: 800,
|
||||
height: 800,
|
||||
showCloseButton: true,
|
||||
visible: true,
|
||||
onHidden: function() {
|
||||
jsonPopupInstance.option("contentTemplate", function() { return $("<pre>"); });
|
||||
}
|
||||
});
|
||||
jsonPopupInstance = $("#jsonPopup").dxPopup("instance");
|
||||
} else {
|
||||
jsonPopupInstance.option("contentTemplate", function() {
|
||||
return $("<pre>").css({ "max-height": "100vh", "overflow": "auto" }).text(prettyJson);
|
||||
});
|
||||
jsonPopupInstance.show();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,669 @@
|
||||
@php
|
||||
if (!isset($tableName)) { $tableName = ""; }
|
||||
$moduleId = isset($c) ? $c -> id : (isset($type) && is_object($type) ? $type -> id : null);
|
||||
$moduleSlug = isset($c) ? $c -> slug : (isset($type) && is_object($type) ? $type -> slug : null);
|
||||
|
||||
// Get inspection history configuration from settings
|
||||
$inspectionConfig = null;
|
||||
$inspectionHistoryActive = false;
|
||||
$inspectionHistoryPath = null;
|
||||
$inspectionHistoryFileNamePattern = null;
|
||||
|
||||
if ($moduleSlug) {
|
||||
$inspectionConfig = getInspectionHistoryConfig($moduleSlug);
|
||||
if ($inspectionConfig) {
|
||||
$inspectionHistoryActive = $inspectionConfig['active'] ?? false;
|
||||
$inspectionHistoryPath = $inspectionConfig['path'] ?? null;
|
||||
$inspectionHistoryFileNamePattern = $inspectionConfig['pattern'] ?? null;
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
onContextMenuPreparing: function(e) {
|
||||
var run = true;
|
||||
|
||||
if (e.row && e.row.data && 'ru_material_group_1' in e.row.data && (e.row.data.ru_material_group_1 === null || e.row.data.ru_material_group_1 === "")) {
|
||||
// Eleman var ama boş
|
||||
run = true;
|
||||
}
|
||||
|
||||
if (e.row && e.row.data && 'ru_material_group_2' in e.row.data && (e.row.data.ru_material_group_2 === null || e.row.data.ru_material_group_2 === "")) {
|
||||
// Eleman var ama boş
|
||||
run = true;
|
||||
}
|
||||
|
||||
if (e.target == "content") {
|
||||
var excludedColumns = ['wps_no'];
|
||||
var hasColumn = e.column && typeof e.columnIndex !== "undefined";
|
||||
var columnDataField = hasColumn ? e.column.dataField : null;
|
||||
|
||||
var isIncluded = hasColumn;
|
||||
|
||||
if (hasColumn && excludedColumns.includes(columnDataField)) {
|
||||
isIncluded = false;
|
||||
}
|
||||
if (!e.items) e.items = [];
|
||||
@if (isSpecificPermission("clear_value_permission", null, $moduleId))
|
||||
e.items.push({
|
||||
text: "🧹{{e2("Clear Value")}}",
|
||||
onItemClick: function (args) {
|
||||
e.component.cellValue(e.rowIndex, e.columnIndex, null);
|
||||
}
|
||||
|
||||
});
|
||||
@endif
|
||||
|
||||
if (run && hasColumn) {
|
||||
@if (isSpecificPermission("row_column_history_permission", null, $moduleId))
|
||||
e.items.push({
|
||||
text: "⌚{{ e2(' Column History') }}",
|
||||
visible(e) {
|
||||
return !e.row.isEditing; // Sadece düzenleme yapılmadığında göster
|
||||
},
|
||||
onItemClick: function (args) {
|
||||
var columns = e.component.getVisibleColumns();
|
||||
var columnName = columns[e.columnIndex] ? columns[e.columnIndex].dataField : null;
|
||||
var tableName = "{{ $tableName }}"; // Laravel'den gelen tablo adı
|
||||
console.log(columnName);
|
||||
|
||||
if (!tableName || !columnName) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Missing table or column name.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
return;
|
||||
}
|
||||
$('#modal-popin').modal();
|
||||
$('#modal-popin .block-title').html(columnName + " History");
|
||||
$('#modal-popin .block-content').html("{{e2("Loading...")}}");
|
||||
$('#modal-popin .modal-footer').addClass("d-none");
|
||||
// AJAX ile veriyi getir
|
||||
$.ajax({
|
||||
url: `?ajax=column-history`,
|
||||
method: 'GET',
|
||||
data: {
|
||||
table: tableName,
|
||||
column: columnName,
|
||||
id: e.row.data.id // İlgili satırın ID'sini gönder
|
||||
},
|
||||
success: function (response) {
|
||||
// Gelen veriyi modalda göster
|
||||
$('#modal-popin .block-content').html(response);
|
||||
|
||||
},
|
||||
error: function () {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: History could not be loaded.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@if (isset($inspectionHistoryActive) && $inspectionHistoryActive)
|
||||
e.items.push({
|
||||
text: "📸{{ e2(' Inspection History') }}",
|
||||
visible(e) {
|
||||
return !e.row.isEditing; // Sadece düzenleme yapılmadığında göster
|
||||
},
|
||||
onItemClick: function (args) {
|
||||
var tableName = "{{ $tableName }}"; // Laravel'den gelen tablo adı
|
||||
var rowId = e.row.data.id; // Row ID'yi al
|
||||
var moduleSlug = "{{ $moduleSlug ?? '' }}"; // Module slug'ı
|
||||
console.log('Row ID:', rowId, 'Module Slug:', moduleSlug);
|
||||
|
||||
if (!tableName || !rowId) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Missing table or row ID.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
return;
|
||||
}
|
||||
$('#modal-popin').modal();
|
||||
$('#modal-popin .block-title').html("Inspection History - Row #" + rowId);
|
||||
$('#modal-popin .block-content').html("{{e2("Loading...")}}");
|
||||
$('#modal-popin .modal-footer').addClass("d-none");
|
||||
// AJAX ile veriyi getir
|
||||
$.ajax({
|
||||
url: `?ajax=inspection-history`,
|
||||
method: 'GET',
|
||||
data: {
|
||||
table: tableName,
|
||||
row_id: rowId,
|
||||
module_slug: moduleSlug // Module slug'ı gönder
|
||||
},
|
||||
success: function (response) {
|
||||
// Gelen veriyi modalda göster
|
||||
$('#modal-popin .block-content').html(response);
|
||||
|
||||
},
|
||||
error: function () {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Inspection history could not be loaded.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@endif
|
||||
e.items.push({
|
||||
text: "📋{{ e2(' Row History') }}",
|
||||
visible(e) {
|
||||
return !e.row.isEditing; // Sadece düzenleme yapılmadığında göster
|
||||
},
|
||||
onItemClick: function (args) {
|
||||
var tableName = "{{ $tableName }}"; // Laravel'den gelen tablo adı
|
||||
var rowId = e.row.data.id; // Row ID'yi al
|
||||
console.log('Row ID:', rowId);
|
||||
|
||||
if (!tableName || !rowId) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Missing table or row ID.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
return;
|
||||
}
|
||||
$('#modal-popin').modal();
|
||||
$('#modal-popin .block-title').html("Row #" + rowId + " History");
|
||||
$('#modal-popin .block-content').html("{{e2("Loading...")}}");
|
||||
$('#modal-popin .modal-footer').addClass("d-none");
|
||||
// AJAX ile veriyi getir
|
||||
$.ajax({
|
||||
url: `?ajax=row-history`,
|
||||
method: 'GET',
|
||||
data: {
|
||||
table: tableName,
|
||||
row_id: rowId // Row ID'yi gönder
|
||||
},
|
||||
success: function (response) {
|
||||
// Gelen veriyi modalda göster
|
||||
$('#modal-popin .block-content').html(response);
|
||||
|
||||
},
|
||||
error: function () {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Row history could not be loaded.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@endif
|
||||
@if (isSpecificPermission("copy_paste_permission", null, $moduleId))
|
||||
if (hasColumn) {
|
||||
e.items.push({
|
||||
text: "📑 {{e2("Copy Value")}}",
|
||||
onItemClick: function (args) {
|
||||
var copyData = e.component.cellValue(e.rowIndex, e.columnIndex);
|
||||
localStorage.setItem("copy_value", copyData);
|
||||
}
|
||||
});
|
||||
|
||||
e.items.push({
|
||||
text: "🩹 {{e2("Paste Value")}}",
|
||||
onItemClick: function (args) {
|
||||
|
||||
var columns = e.component.getVisibleColumns();
|
||||
|
||||
// columnIndex'e karşılık gelen sütun adını al
|
||||
var columnName = columns[e.columnIndex] ? columns[e.columnIndex].dataField : null;
|
||||
|
||||
// Eğer sütun adı 'wps_no' ise
|
||||
if (columnName === 'wps_no') {
|
||||
// Burada istediğiniz işlemi yapabilirsiniz
|
||||
}
|
||||
|
||||
if (columns[e.columnIndex] && columns[e.columnIndex].allowEditing == false) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('This column is read only. Please copy using the same columns.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
e.component.cellValue(e.rowIndex, e.columnIndex, localStorage.getItem("copy_value"));
|
||||
}
|
||||
});
|
||||
}
|
||||
@endif
|
||||
|
||||
@if (isSpecificPermission("add_row_permission", null, $moduleId))
|
||||
e.items.push({
|
||||
text: "🐑{{e2("Clone Row")}}",
|
||||
visible(e) {
|
||||
return !e.row.isEditing;
|
||||
},
|
||||
onItemClick: function (args) {
|
||||
//$(".dx-icon-edit-button-addrow").trigger("click");
|
||||
/*
|
||||
console.log("clone row");
|
||||
e.component.clearFilter();
|
||||
selectedData = e.row.data;
|
||||
selectedData.id = selectedData.id + 1;
|
||||
//addedRow++;
|
||||
e.component.addRow();
|
||||
|
||||
*/
|
||||
@if (isset($tableName))
|
||||
$.post("{{url('admin/clone-row/' . $tableName)}}", {
|
||||
data: JSON.stringify(e.row.data),
|
||||
_token: "{{csrf_token()}}"
|
||||
}, function () {
|
||||
e.component.refresh();
|
||||
});
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
if (isIncluded) {
|
||||
@if (isSpecificPermission("copy_start_until_paste_permission", null, $moduleId))
|
||||
e.items.push({
|
||||
text: "📑⌚{{e2("Copy Start")}}",
|
||||
onItemClick: function (args) {
|
||||
copyData = e.component.cellValue(e.rowIndex, e.columnIndex);
|
||||
selectedColIndex = e.columnIndex;
|
||||
selectedRowIndex = e.rowIndex;
|
||||
console.log(e);
|
||||
console.log(selectedColIndex);
|
||||
console.log(selectedRowIndex);
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Data copied start')}}: " + copyData,
|
||||
type: "success",
|
||||
displayTime: 2000,
|
||||
position: "bottom center"
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
e.items.push({
|
||||
text: "⏬🩹{{e2("Until Paste")}}",
|
||||
onItemClick: function (args) {
|
||||
|
||||
if (e.columnIndex != selectedColIndex) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Wrong! Please copy using the same columns.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
} else {
|
||||
// Performans için batch update kullan
|
||||
e.component.beginUpdate();
|
||||
|
||||
try {
|
||||
// Tüm satırları bir dizide topla
|
||||
var updates = [];
|
||||
for (var rowIndex = selectedRowIndex + 1; rowIndex <= e.rowIndex; rowIndex++) {
|
||||
updates.push({
|
||||
rowIndex: rowIndex,
|
||||
columnIndex: e.columnIndex,
|
||||
value: copyData
|
||||
});
|
||||
}
|
||||
|
||||
// Toplu güncelleme yap
|
||||
updates.forEach(function (update) {
|
||||
e.component.cellValue(update.rowIndex, update.columnIndex, update.value);
|
||||
});
|
||||
|
||||
} finally {
|
||||
// Her durumda endUpdate çağrılsın
|
||||
e.component.endUpdate();
|
||||
}
|
||||
|
||||
// Başarı mesajı göster
|
||||
var updatedRowsCount = e.rowIndex - selectedRowIndex;
|
||||
DevExpress.ui.notify({
|
||||
message: updatedRowsCount + " {{e2('rows updated successfully')}}",
|
||||
type: "success",
|
||||
displayTime: 2000,
|
||||
position: "bottom center"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
e.items.push({
|
||||
text: "🧮{{e2("SUM This Column")}}",
|
||||
onItemClick: function (args) {
|
||||
var columnIndex = e.columnIndex;
|
||||
var rowIndex = e.rowIndex;
|
||||
var allData = e.component.getVisibleRows();
|
||||
try {
|
||||
var total = 0;
|
||||
$.each(allData, function (index, data) {
|
||||
total += eval(data.values[columnIndex]);
|
||||
});
|
||||
|
||||
//Swal.fire(total.toFixed(2).toString(), "{{e2("Total ")}}" + e.column.caption, "success");
|
||||
$(".footer-status").html(total.toFixed(2).toString() + " {{e2("Total ")}}" + e.column.caption);
|
||||
} catch (error) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('SUM operation could not be performed because there are string values in the column.')}} (" + e.column.caption + ")",
|
||||
type: "error",
|
||||
displayTime: 4000,
|
||||
position: "bottom center"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
e.items.push({
|
||||
text: "🧮{{e2("AVG This Column")}}",
|
||||
onItemClick: function (args) {
|
||||
|
||||
var columnIndex = e.columnIndex;
|
||||
var rowIndex = e.rowIndex;
|
||||
var allData = e.component.getVisibleRows();
|
||||
|
||||
try {
|
||||
var total = 0;
|
||||
var count = 0;
|
||||
$.each(allData, function (index, data) {
|
||||
total += eval(data.values[columnIndex]);
|
||||
count++;
|
||||
});
|
||||
var avg = Math.round(total / count) * 100 / 100;
|
||||
//Swal.fire(avg.toFixed(2).toString(), "{{e2("Average ")}}" + e.column.caption, "success");
|
||||
$(".footer-status").html(avg.toFixed(2).toString() + " {{e2("Average ")}}" + e.column.caption);
|
||||
} catch (error) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Average operation could not be performed because there are string values in the column.')}} (" + e.column.caption + ")",
|
||||
type: "error",
|
||||
displayTime: 4000,
|
||||
position: "bottom center"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
e.items.push({
|
||||
text: "🧮{{e2("Count This Column")}}",
|
||||
onItemClick: function (args) {
|
||||
console.log(args);
|
||||
var columnIndex = e.columnIndex;
|
||||
var rowIndex = e.rowIndex;
|
||||
var allData = e.component.getVisibleRows();
|
||||
|
||||
var count = 0;
|
||||
$.each(allData, function (index, data) {
|
||||
count++;
|
||||
});
|
||||
|
||||
// Swal.fire(count.toString(), "{{e2("Count ")}}" + e.column.caption, "success");
|
||||
$(".footer-status").html(count.toString() + " {{e2("Count ")}}" + e.column.caption);
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Document History menüsü - PDF sütunları için
|
||||
var columns = e.component.getVisibleColumns();
|
||||
var columnName = (columns[e.columnIndex] && columns[e.columnIndex].dataField) ? columns[e.columnIndex].dataField : null;
|
||||
var isPdfColumn = columnName && (
|
||||
columnName.toLowerCase().includes('download') ||
|
||||
columnName.toLowerCase().includes('file') ||
|
||||
columnName.toLowerCase().includes('pdf') ||
|
||||
columnName.toLowerCase().includes('document') ||
|
||||
columnName.toLowerCase().includes('naks_technology') ||
|
||||
columnName.toLowerCase().includes('report')
|
||||
);
|
||||
|
||||
if (isPdfColumn) {
|
||||
@if (isAuth($moduleSlug, "read") && isSpecificPermission("document_history_permission", null, $moduleId))
|
||||
e.items.push({
|
||||
text: "📋 Document History",
|
||||
visible(e) {
|
||||
return !e.row.isEditing;
|
||||
},
|
||||
onItemClick: function (args) {
|
||||
var tableName = "{{ $tableName }}";
|
||||
var rowId = e.row.data.id;
|
||||
var columnName = columns[e.columnIndex].dataField;
|
||||
|
||||
// Tıklanan hücredeki dosya adını al
|
||||
var cellValue = e.component.cellValue(e.rowIndex, e.columnIndex);
|
||||
var fileName = null;
|
||||
|
||||
// Cell value'dan dosya adını çıkart
|
||||
if (cellValue && typeof cellValue === 'string') {
|
||||
// Eğer HTML link ise dosya adını çıkart
|
||||
if (cellValue.includes('<a')) {
|
||||
var tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = cellValue;
|
||||
var link = tempDiv.querySelector('a');
|
||||
if (link && link.href) {
|
||||
fileName = link.href.split('/').pop();
|
||||
}
|
||||
} else {
|
||||
// Doğrudan dosya adı ise
|
||||
fileName = cellValue.split('/').pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (!tableName || !rowId || !columnName) {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Missing table, row ID or column information.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
$('#modal-popin').modal();
|
||||
$('#modal-popin .block-title').html("Document History - " + (fileName || columnName));
|
||||
$('#modal-popin .block-content').html("Loading...");
|
||||
$('#modal-popin .modal-footer').addClass("d-none");
|
||||
|
||||
// AJAX ile document history'yi getir
|
||||
$.ajax({
|
||||
url: '{{url("admin-ajax/document-history")}}',
|
||||
method: 'POST',
|
||||
data: {
|
||||
table: tableName,
|
||||
column: columnName,
|
||||
row_id: rowId,
|
||||
file_name: fileName,
|
||||
_token: "{{csrf_token()}}"
|
||||
},
|
||||
success: function (response) {
|
||||
$('#modal-popin .block-content').html(response);
|
||||
},
|
||||
error: function () {
|
||||
DevExpress.ui.notify({
|
||||
message: "{{e2('Error: Document history could not be loaded.')}}",
|
||||
type: "error",
|
||||
displayTime: 3000,
|
||||
position: "bottom center"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@endif
|
||||
}
|
||||
}
|
||||
},
|
||||
@if (isSpecificPermission("copy_start_until_paste_permission", null, $moduleId))
|
||||
onCellClick: function(e) {
|
||||
if (e.rowType !== "data" || !e.column) return;
|
||||
|
||||
// Static checks
|
||||
if (e.column.allowEditing === false || e.column.readOnly === true || (e.column.editorOptions && e.column.editorOptions.readOnly === true)) return;
|
||||
|
||||
// Dynamic checks via onEditorPreparing
|
||||
var onEditorPreparing = e.component.option('onEditorPreparing');
|
||||
if (onEditorPreparing) {
|
||||
var editorOptions = $.extend(true, {}, e.column.editorOptions || {});
|
||||
var args = {
|
||||
component: e.component,
|
||||
row: e.row,
|
||||
column: e.column,
|
||||
dataField: e.column.dataField,
|
||||
parentType: "dataRow",
|
||||
editorOptions: editorOptions,
|
||||
rowIndex: e.rowIndex,
|
||||
value: e.value
|
||||
};
|
||||
|
||||
try {
|
||||
onEditorPreparing(args);
|
||||
if (args.editorOptions.readOnly === true || args.allowEditing === false) {
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
// Ignore errors in dynamic check
|
||||
}
|
||||
}
|
||||
|
||||
var component = e.component;
|
||||
var cellElement = e.cellElement;
|
||||
var rowIndex = e.rowIndex;
|
||||
var columnIndex = e.columnIndex;
|
||||
|
||||
// Remove previous selection and handle
|
||||
$(".excel-selection").removeClass("excel-selection");
|
||||
$(".excel-handle").remove();
|
||||
|
||||
// Add selection border
|
||||
var $cell = $(cellElement);
|
||||
$cell.addClass("excel-selection");
|
||||
|
||||
// Inject CSS if not present
|
||||
if ($("#excel-grid-styles").length === 0) {
|
||||
$("head").append('<style id="excel-grid-styles">.excel-selection{box-shadow: inset 0 0 0 2px #217346 !important;position: relative;}.excel-handle{position: absolute;bottom: -4px;right: -4px;width: 8px;height: 8px;background-color: #217346;border: 1px solid white;cursor: crosshair;z-index: 1000;}.excel-drag-highlight{background-color: rgba(33, 115, 70, 0.1) !important;box-shadow: inset 0 0 0 1px #217346 !important;}</style>');
|
||||
}
|
||||
|
||||
// Create handle
|
||||
var $handle = $('<div class="excel-handle"></div>');
|
||||
$cell.append($handle);
|
||||
|
||||
$handle.on("mousedown", function (event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
var startRowIndex = rowIndex;
|
||||
var startValue = e.value;
|
||||
var visibleRows = component.getVisibleRows();
|
||||
var cellRects = [];
|
||||
|
||||
// Cache cell positions for current column
|
||||
for (var i = 0; i < visibleRows.length; i++) {
|
||||
if (visibleRows[i].rowType === "data") {
|
||||
var cell = component.getCellElement(i, columnIndex);
|
||||
if (cell && cell.length) {
|
||||
var rect = cell[0].getBoundingClientRect();
|
||||
cellRects.push({
|
||||
rowIndex: i,
|
||||
top: rect.top,
|
||||
bottom: rect.bottom,
|
||||
element: cell
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var overlay = $('<div style="position:fixed;top:0;left:0;right:0;bottom:0;z-index:99999;cursor:crosshair;"></div>').appendTo("body");
|
||||
var lastTargetIndex = startRowIndex;
|
||||
|
||||
$(document).on("mousemove.excelDrag", function (moveEvent) {
|
||||
var mouseY = moveEvent.clientY;
|
||||
|
||||
// Find target row
|
||||
var targetIndex = -1;
|
||||
for (var i = 0; i < cellRects.length; i++) {
|
||||
if (mouseY >= cellRects[i].top && mouseY <= cellRects[i].bottom) {
|
||||
targetIndex = cellRects[i].rowIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetIndex !== -1 && targetIndex !== lastTargetIndex) {
|
||||
lastTargetIndex = targetIndex;
|
||||
|
||||
// Clear previous highlights
|
||||
$(".excel-drag-highlight").removeClass("excel-drag-highlight");
|
||||
|
||||
// Highlight range
|
||||
var minIndex = Math.min(startRowIndex, targetIndex);
|
||||
var maxIndex = Math.max(startRowIndex, targetIndex);
|
||||
|
||||
for (var i = 0; i < cellRects.length; i++) {
|
||||
if (cellRects[i].rowIndex >= minIndex && cellRects[i].rowIndex <= maxIndex) {
|
||||
$(cellRects[i].element).addClass("excel-drag-highlight");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("mouseup.excelDrag", function () {
|
||||
$(document).off(".excelDrag");
|
||||
overlay.remove();
|
||||
$(".excel-drag-highlight").removeClass("excel-drag-highlight");
|
||||
|
||||
if (lastTargetIndex !== -1 && lastTargetIndex !== startRowIndex) {
|
||||
var minIndex = Math.min(startRowIndex, lastTargetIndex);
|
||||
var maxIndex = Math.max(startRowIndex, lastTargetIndex);
|
||||
|
||||
component.beginUpdate();
|
||||
try {
|
||||
for (var i = minIndex; i <= maxIndex; i++) {
|
||||
if (i !== startRowIndex) {
|
||||
component.cellValue(i, columnIndex, startValue);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
component.endUpdate();
|
||||
}
|
||||
|
||||
DevExpress.ui.notify({
|
||||
message: (maxIndex - minIndex) + " {{e2('rows updated')}}",
|
||||
type: "success",
|
||||
displayTime: 2000
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
@endif
|
||||
@@ -0,0 +1,133 @@
|
||||
localStorage.removeItem("rowIndex");
|
||||
localStorage.removeItem("columnIndex");
|
||||
$(document).bind("keydown", async function(e){
|
||||
console.log(e.which);
|
||||
|
||||
if(e.ctrlKey && e.which == 81) {
|
||||
//ctrl q
|
||||
@if(isset($tableName))
|
||||
var selectedRowData = localStorage.getItem("selectedRowData");
|
||||
|
||||
$.post("{{url('admin/clone-row/' . $tableName)}}", {
|
||||
data : selectedRowData,
|
||||
_token : "{{csrf_token()}}"
|
||||
}, function() {
|
||||
$("#dataGrid").dxDataGrid("instance").refresh();
|
||||
});
|
||||
@endif
|
||||
|
||||
}
|
||||
var dataGrid = $("#dataGrid").dxDataGrid("instance");
|
||||
if(e.shiftKey && e.which == 78){ //shift n
|
||||
console.log("new row");
|
||||
dataGrid.addRow();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(e.ctrlKey && e.which == 86) { // ctrk v
|
||||
/*
|
||||
const text = await navigator.clipboard.readText();
|
||||
console.log("copy text");
|
||||
console.log(text);
|
||||
|
||||
var rowIndex = eval(localStorage.getItem("rowIndex"));
|
||||
var colIndex = eval(localStorage.getItem("columnIndex"));
|
||||
console.log(dataGrid);
|
||||
dataGrid.cellValue(rowIndex, colIndex, text);
|
||||
// dataGrid.closeEditCell();
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(e.ctrlKey && e.which == 90){ // ctrl z
|
||||
/*
|
||||
var value = $(".dx-focused").val();
|
||||
const selector = $(".dx-focused");
|
||||
var rowIndex = dataGrid.option("focusedRowIndex");
|
||||
var colIndex = dataGrid.option("focusedColumnIndex");
|
||||
console.log(rowIndex);
|
||||
var originalData = JSON.parse(localStorage.getItem("originalData"+rowIndex + colIndex));
|
||||
dataGrid.cellValue(rowIndex, colIndex, originalData[0]);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(e.ctrlKey && e.which == 67) { // ctrl c
|
||||
/*
|
||||
console.log("e.which");
|
||||
console.log(e.which);
|
||||
var value = localStorage.getItem("cellValue");
|
||||
if(value == "") {
|
||||
|
||||
console.log("empty");
|
||||
} else {
|
||||
console.log(value);
|
||||
|
||||
navigator.clipboard.writeText(value)
|
||||
.then(() => {
|
||||
console.log('Text copied to clipboard');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to copy text: ', error);
|
||||
});
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if(e.ctrlKey && e.which == 107){ //ctrl +
|
||||
console.log("new row");
|
||||
dataGrid.addRow();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
if(e.ctrlKey && e.which == 83){
|
||||
|
||||
$(".dx-icon-edit-button-save").trigger("click");
|
||||
|
||||
if(dataGrid.hasEditData()) {
|
||||
dataGrid.saveEditData().then(function() {
|
||||
if(!dataGrid.hasEditData()) {
|
||||
console.log("Saved successfully");
|
||||
// Saved successfully
|
||||
} else {
|
||||
console.log("Saving failed");
|
||||
// Saving failed
|
||||
}
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$("#add-row-tooltip").dxTooltip({
|
||||
target: '.dx-datagrid-addrow-button',
|
||||
showEvent: 'mouseenter',
|
||||
hideEvent: 'mouseleave',
|
||||
hideOnOutsideClick: false,
|
||||
});
|
||||
$("#save-tooltip").dxTooltip({
|
||||
target: '.dx-datagrid-save-button',
|
||||
showEvent: 'mouseenter',
|
||||
hideEvent: 'mouseleave',
|
||||
hideOnOutsideClick: false,
|
||||
});
|
||||
$("#undo-tooltip").dxTooltip({
|
||||
target: '.dx-datagrid-cancel-button',
|
||||
showEvent: 'mouseenter',
|
||||
hideEvent: 'mouseleave',
|
||||
hideOnOutsideClick: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
$moduleId = isset($c) ? $c->id : (isset($type) && is_object($type) ? $type->id : null);
|
||||
?>
|
||||
@if(isSpecificPermission("clear_filter_permission", null, $moduleId))
|
||||
{
|
||||
location: 'before',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'filter',
|
||||
hint: '{{e2("Clear Filter")}}',
|
||||
onClick: function(e) {
|
||||
dataGrid.clearFilter();
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(isSpecificPermission("add_row_permission", null, $moduleId))"addRowButton",@endif
|
||||
@if(isSpecificPermission("apply_filter_permission", null, $moduleId))
|
||||
"applyFilterButton",
|
||||
{
|
||||
location: "before",
|
||||
widget: "dxButton",
|
||||
options: {
|
||||
hint: "Copy Filter",
|
||||
icon: "copy",
|
||||
onClick() {
|
||||
const dataGrid = $("#{{ $gridId ?? 'dataGrid' }}").dxDataGrid("instance");
|
||||
const filter = dataGrid.getCombinedFilter(true);
|
||||
if (filter) {
|
||||
navigator.clipboard.writeText(JSON.stringify(filter)).then(() => {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Copied!',
|
||||
text: 'Current filter has been copied to clipboard.'
|
||||
});
|
||||
});
|
||||
} else {
|
||||
navigator.clipboard.writeText("null").then(() => {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Copied!',
|
||||
text: 'No filter applied; clipboard contains null.'
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
location: "before",
|
||||
widget: "dxButton",
|
||||
options: {
|
||||
hint: "Paste Filter",
|
||||
icon: "paste",
|
||||
onClick() {
|
||||
const dataGrid = $("#{{ $gridId ?? 'dataGrid' }}").dxDataGrid("instance");
|
||||
navigator.clipboard.readText().then(txt => {
|
||||
try {
|
||||
const filter = JSON.parse(txt);
|
||||
if (filter && filter !== "null") {
|
||||
dataGrid.option("filterValue", filter);
|
||||
} else {
|
||||
dataGrid.clearFilter();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Paste Filter Error", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(isSpecificPermission("column_chooser_permission", null, $moduleId))"columnChooserButton",@endif
|
||||
@if(isSpecificPermission("revert_permission", null, $moduleId))
|
||||
{
|
||||
location: 'after',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'revert',
|
||||
hint: '{{e2("Discard Changes")}}',
|
||||
onClick: function(e) {
|
||||
Swal.fire({
|
||||
title: '{{e2("Are you sure?")}}',
|
||||
text: '{{e2("You will lose all unsaved changes!")}}',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '{{e2("Yes, discard changes")}}'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
dataGrid.cancelEditData();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(isSpecificPermission("save_permission", null, $moduleId))"saveButton",@endif
|
||||
@if(isSpecificPermission("search_panel_permission", null, $moduleId))"searchPanel",@endif
|
||||
@if(isSpecificPermission("export_permission", null, $moduleId))"exportButton",@endif
|
||||
@if(isSpecificPermission("group_panel_permission", null, $moduleId))"groupPanel",@endif
|
||||
@if(isset($inspectionHistoryActive) && $inspectionHistoryActive)
|
||||
{
|
||||
location: 'before',
|
||||
widget: 'dxSelectBox',
|
||||
options: {
|
||||
width: 200,
|
||||
placeholder: '{{e2("Filter Inspection")}}',
|
||||
items: [
|
||||
{ id: 'all', text: '{{e2("All Rows")}}' },
|
||||
{ id: 'with_inspection', text: '{{e2("With Inspection")}}' },
|
||||
{ id: 'without_inspection', text: '{{e2("Without Inspection")}}' }
|
||||
],
|
||||
displayExpr: 'text',
|
||||
valueExpr: 'id',
|
||||
value: 'all',
|
||||
onValueChanged: function(e) {
|
||||
var dataGrid = $("#{{ $gridId ?? 'dataGrid' }}").dxDataGrid("instance");
|
||||
|
||||
// Clear existing filters on ID
|
||||
dataGrid.columnOption("id", "filterValues", null);
|
||||
dataGrid.columnOption("id", "filterType", "include");
|
||||
dataGrid.clearFilter("dataSource");
|
||||
|
||||
if (e.value === 'with_inspection') {
|
||||
if(inspectionRowIds && inspectionRowIds.length > 0) {
|
||||
// Use column option to avoid "Unknown filter operation" error
|
||||
dataGrid.columnOption("id", "filterType", "include");
|
||||
dataGrid.columnOption("id", "filterValues", inspectionRowIds);
|
||||
} else {
|
||||
dataGrid.filter(['id', '=', -1]); // Match nothing
|
||||
}
|
||||
} else if (e.value === 'without_inspection') {
|
||||
if(inspectionRowIds && inspectionRowIds.length > 0) {
|
||||
dataGrid.columnOption("id", "filterType", "exclude");
|
||||
dataGrid.columnOption("id", "filterValues", inspectionRowIds);
|
||||
} else {
|
||||
dataGrid.clearFilter();
|
||||
}
|
||||
} else {
|
||||
dataGrid.clearFilter();
|
||||
dataGrid.columnOption("id", "filterValues", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(isSpecificPermission("select_all_permission", null, $moduleId))
|
||||
{
|
||||
location: 'before',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'selectall',
|
||||
hint: 'Select All',
|
||||
onClick: function(e) {
|
||||
// Get grid instance safely
|
||||
var grid = $("#{{ $gridId ?? 'dataGrid' }}").dxDataGrid("instance");
|
||||
|
||||
// Switch to multiple selection mode
|
||||
grid.option("selection.mode", "multiple");
|
||||
|
||||
// Select all rows visually (handles deferred selection)
|
||||
grid.selectAll();
|
||||
|
||||
// Fetch all IDs for localStorage (needed for operations like Delete)
|
||||
grid.getDataSource().store().load({
|
||||
filter: grid.getCombinedFilter(),
|
||||
sort: grid.getDataSource().sort(),
|
||||
skip: 0,
|
||||
take: 1000000
|
||||
}).done(function(data) {
|
||||
// Handle different data structures (array or object with data property)
|
||||
var items = Array.isArray(data) ? data : (data.data || []);
|
||||
var keys = items.map(function(item) {
|
||||
return item.id;
|
||||
});
|
||||
|
||||
// Store keys for batch operations
|
||||
localStorage.setItem("selectRows", JSON.stringify(keys));
|
||||
|
||||
// Notify user
|
||||
if(typeof DevExpress !== 'undefined' && DevExpress.ui && DevExpress.ui.notify) {
|
||||
DevExpress.ui.notify(keys.length + " rows selected", "success", 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(isSpecificPermission("deselect_all_permission", null, $moduleId))
|
||||
{
|
||||
location: 'before',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'unselectall', // Use a different icon for deselect (e.g., 'unselectall')
|
||||
hint: 'Deselect All',
|
||||
onClick: function(e) {
|
||||
// Deselect all rows in the DataGrid and clear the selection from localStorage
|
||||
dataGrid.clearSelection();
|
||||
localStorage.removeItem("selectRows");
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(isSpecificPermission("refresh_permission", null, $moduleId))
|
||||
{
|
||||
location: 'before',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'refresh',
|
||||
hint: 'Refresh DataGrid',
|
||||
onClick: function(e) {
|
||||
// Refresh the DataGrid to reload data
|
||||
dataGrid.refresh();
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(isSpecificPermission("delete_selected_permission", null, $moduleId))
|
||||
{
|
||||
location: 'before',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'remove',
|
||||
hint: '{{e2("Delete Selected")}}',
|
||||
onClick: function(e) {
|
||||
var dataGrid = $("#{{ $gridId ?? 'dataGrid' }}").dxDataGrid("instance");
|
||||
var store = dataGrid.getDataSource().store();
|
||||
|
||||
// Promise tabanlı seçim kontrolü (deferred mode desteği için)
|
||||
$.when(dataGrid.getSelectedRowKeys()).done(function(selectedKeys) {
|
||||
// Eğer grid üzerinden seçim gelmediyse localStorage kontrol et (Select All durumu için)
|
||||
if (!selectedKeys || selectedKeys.length === 0) {
|
||||
var storedKeys = localStorage.getItem("selectRows");
|
||||
if (storedKeys) {
|
||||
try {
|
||||
selectedKeys = JSON.parse(storedKeys);
|
||||
} catch(e) {
|
||||
selectedKeys = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedKeys || selectedKeys.length === 0) {
|
||||
Swal.fire({
|
||||
icon: 'warning',
|
||||
title: '{{e2("Warning")}}',
|
||||
text: '{{e2("Please select at least one row.")}}'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: '{{e2("Are you sure?")}}',
|
||||
text: '{{e2("You will lose the selected records!")}}',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '{{e2("Yes, delete it!")}}'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
var promises = [];
|
||||
|
||||
// Progress tracker başlat
|
||||
if (typeof progressTracker !== 'undefined') {
|
||||
progressTracker.start(selectedKeys.length);
|
||||
}
|
||||
|
||||
selectedKeys.forEach(function(key) {
|
||||
promises.push(store.remove(key));
|
||||
});
|
||||
|
||||
$.when.apply($, promises).done(function() {
|
||||
dataGrid.refresh();
|
||||
dataGrid.clearSelection();
|
||||
localStorage.removeItem("selectRows");
|
||||
Swal.fire('{{e2("Deleted!")}}', '{{e2("Your selected rows have been deleted.")}}', 'success');
|
||||
}).fail(function() {
|
||||
if (typeof progressTracker !== 'undefined') {
|
||||
progressTracker.complete();
|
||||
}
|
||||
Swal.fire('{{e2("Deletion failed for some rows.")}}', '', 'error');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
@endif
|
||||
@if(!isset($summaryTable))
|
||||
/*
|
||||
{
|
||||
location: 'before',
|
||||
widget: 'dxButton',
|
||||
options: {
|
||||
icon: 'copy',
|
||||
text: '{{e2("Clone Row")}}',
|
||||
onClick: function(e) {
|
||||
console.log("Clone");
|
||||
console.log(e);
|
||||
localStorage.setItem("clone", "ok");
|
||||
let dataGrid = $("#{{ $gridId ?? 'dataGrid' }}").dxDataGrid("instance");
|
||||
// dataGrid.addRow();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
*/
|
||||
@endif
|
||||
{
|
||||
location: 'after',
|
||||
widget: 'dxSelectBox',
|
||||
options: {
|
||||
placeholder: '{{e2("Go to Column")}}',
|
||||
searchEnabled: true,
|
||||
width: 150,
|
||||
displayExpr: 'text',
|
||||
valueExpr: 'value',
|
||||
dataSource: [
|
||||
@if(isset($columnsList) && isset($selectedColumns))
|
||||
@foreach($columnsList as $column)
|
||||
@if(in_array($column['name'], $selectedColumns))
|
||||
{
|
||||
"value": "{{$column['name']}}",
|
||||
"text": "{{ isset($column['caption']) ? $column['caption'] : e2($column['name']) }}"
|
||||
},
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
],
|
||||
onValueChanged: function(e) {
|
||||
var grid = $("#{{ $gridId ?? 'dataGrid' }}").dxDataGrid("instance");
|
||||
var colName = e.value;
|
||||
|
||||
if(colName) {
|
||||
// Use 0 as default row index since we just want to scroll horizontally
|
||||
// getCellElement works with visible row indices
|
||||
var rowIndex = 0;
|
||||
|
||||
var cellElement = grid.getCellElement(rowIndex, colName);
|
||||
|
||||
if(cellElement && cellElement.length > 0) {
|
||||
var scrollable = grid.getScrollable();
|
||||
scrollable.scrollToElement(cellElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,130 @@
|
||||
function mainValidationCallBack(e) {
|
||||
console.log("mainValidationCallBack");
|
||||
console.log(e);
|
||||
if (typeof initValidationCallBack == 'function') {
|
||||
initValidationCallBack(e);
|
||||
}
|
||||
}
|
||||
function isNotEmpty(value) {
|
||||
return value !== undefined && value !== null && value !== '';
|
||||
}
|
||||
const mechanicalJointTypesGlobal = <?php echo json_encode_tr($mechanicalJointTypes); ?>;
|
||||
const mechanicalDisabledFieldsGlobal = <?php echo json_encode_tr($mechanicalDisabledFields); ?>;
|
||||
const mechanicalDisabledPrefixesGlobal = <?php echo json_encode_tr($mechanicalDisabledPrefixes); ?>;
|
||||
const mechanicalEditableWhitelistGlobal = <?php echo json_encode_tr($mechanicalEditableWhitelist); ?>;
|
||||
const mechanicalControlsEnabled = <?php echo $enableMechanicalControls ? 'true' : 'false'; ?>;
|
||||
const mechanicalSummaryFilterEnabled = <?php echo $weldedSummaryFilter ? 'true' : 'false'; ?>;
|
||||
const mechanicalPlaceholderEnabled = <?php echo $showMechanicalNdtPlaceholder ? 'true' : 'false'; ?>;
|
||||
const mechanicalPlaceholderFields = <?php echo json_encode_tr($mechanicalNdtFields); ?>;
|
||||
const mechanicalPlaceholderText = "N/A – Non-Welded Connection";
|
||||
const mechanicalDetectionEnabled = mechanicalControlsEnabled || mechanicalSummaryFilterEnabled || mechanicalPlaceholderEnabled;
|
||||
|
||||
function getJointTypeFromRow(rowData) {
|
||||
if (!rowData) return null;
|
||||
return rowData.type_of_welds || rowData.type_of_joint || rowData.joint || rowData.joint_type || rowData.type;
|
||||
}
|
||||
|
||||
function isMechanicalJointRow(rowData) {
|
||||
if (!mechanicalDetectionEnabled) return false;
|
||||
const jointValue = getJointTypeFromRow(rowData);
|
||||
return !!jointValue && mechanicalJointTypesGlobal.indexOf(jointValue) !== -1;
|
||||
}
|
||||
|
||||
function shouldDisableMechanicalField(field) {
|
||||
if (!mechanicalControlsEnabled) return false;
|
||||
if (!field) return false;
|
||||
if (mechanicalEditableWhitelistGlobal.indexOf(field) !== -1) return false;
|
||||
if (mechanicalDisabledFieldsGlobal.indexOf(field) !== -1) return true;
|
||||
return mechanicalDisabledPrefixesGlobal.some(function (prefix) {
|
||||
return field.indexOf(prefix) === 0;
|
||||
});
|
||||
}
|
||||
|
||||
function applyMechanicalEditorState(e) {
|
||||
if (!mechanicalControlsEnabled) return;
|
||||
if (!e || e.parentType !== 'data') return;
|
||||
const rowData = (e.row && e.row.data) || {};
|
||||
if (!isMechanicalJointRow(rowData)) return;
|
||||
|
||||
if (shouldDisableMechanicalField(e.dataField)) {
|
||||
e.editorOptions = e.editorOptions || {};
|
||||
e.editorOptions.readOnly = true;
|
||||
e.editorOptions.value = null;
|
||||
e.editorOptions.placeholder = 'N/A – Non-welded joint';
|
||||
} else if (e.dataField === 'fitter_name') {
|
||||
e.editorOptions = e.editorOptions || {};
|
||||
e.editorOptions.readOnly = false;
|
||||
e.editorOptions.placeholder = e.editorOptions.placeholder || 'Enter fitter name';
|
||||
}
|
||||
}
|
||||
|
||||
function clearMechanicalOnlyFields(component, rowIndex) {
|
||||
if (!mechanicalControlsEnabled) return;
|
||||
if (!component || rowIndex === undefined || rowIndex === null) return;
|
||||
const columns = component.getVisibleColumns();
|
||||
columns.forEach(function (column) {
|
||||
if (column && shouldDisableMechanicalField(column.dataField)) {
|
||||
component.cellValue(rowIndex, column.dataField, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleMechanicalCellChange(e) {
|
||||
if (!mechanicalControlsEnabled) return;
|
||||
if (!e || !e.component || !e.column) return;
|
||||
if (e.column.dataField === 'type_of_welds') {
|
||||
if (isMechanicalJointRow({ type_of_welds: e.value })) {
|
||||
clearMechanicalOnlyFields(e.component, e.rowIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyMechanicalRowStyles(component) {
|
||||
if (!mechanicalControlsEnabled) return;
|
||||
if (!component) return;
|
||||
component.getVisibleRows().forEach(function (row) {
|
||||
if (row.rowType !== 'data') return;
|
||||
const $row = $(row.rowElement);
|
||||
if (isMechanicalJointRow(row.data)) {
|
||||
$row.addClass('mechanical-row');
|
||||
} else {
|
||||
$row.removeClass('mechanical-row');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleMechanicalCustomSummary(options) {
|
||||
if (!mechanicalSummaryFilterEnabled) return;
|
||||
if (!options || !options.name) return;
|
||||
const normalizedName = options.name.replace(/^group_/, '');
|
||||
const isSum = normalizedName.indexOf('sum_') === 0;
|
||||
const isAvg = normalizedName.indexOf('avg_') === 0;
|
||||
if (!isSum && !isAvg) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (options.summaryProcess) {
|
||||
case 'start':
|
||||
options.totalValue = isAvg ? { sum: 0, count: 0 } : 0;
|
||||
break;
|
||||
case 'calculate':
|
||||
if (isMechanicalJointRow(options.data)) {
|
||||
return;
|
||||
}
|
||||
const numericValue = Number(options.value) || 0;
|
||||
if (isSum) {
|
||||
options.totalValue += numericValue;
|
||||
} else {
|
||||
options.totalValue.sum += numericValue;
|
||||
options.totalValue.count += 1;
|
||||
}
|
||||
break;
|
||||
case 'finalize':
|
||||
if (isAvg) {
|
||||
const sum = options.totalValue.sum || 0;
|
||||
const count = options.totalValue.count || 0;
|
||||
options.totalValue = count ? sum / count : 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
@foreach($columnsList as $column)
|
||||
@if (is_array($column) && isset($column['name']) && in_array($column['name'], $selectedColumns))
|
||||
|
||||
function validationCallback_@php echo $column['name']; @endphp (e) {
|
||||
@php
|
||||
$callbackFolder = $id;
|
||||
|
||||
if ($callbackFolder == "base-weldmap") $callbackFolder = "weldmap";
|
||||
if ($callbackFolder == "weldlog") $callbackFolder = "weldmap";
|
||||
|
||||
$validationCallbackPath = 'components.table.datagrid.validation-callback.'.$callbackFolder. '.js-'.$column['name'];
|
||||
@endphp
|
||||
|
||||
@if (View::exists($validationCallbackPath))
|
||||
@include($validationCallbackPath)
|
||||
@else
|
||||
var result;
|
||||
|
||||
@if (in_array($column['name'], $requiredFields))
|
||||
@if (isset($column['type']) && $column['type'] === 'decimal')
|
||||
// Sayısal alanlar için kontrol
|
||||
result = e.value !== null && !isNaN(e.value) && e.value !== '';
|
||||
@elseif (isset($column['type']) && $column['type'] === 'date')
|
||||
// Tarih alanları için kontrol
|
||||
if (e.value === null || e.value === undefined || e.value === '') {
|
||||
result = true;
|
||||
} else if (e.value instanceof Date) {
|
||||
// Date objesi ise geçerli bir tarih mi kontrol et
|
||||
result = !isNaN(e.value.getTime());
|
||||
} else if (typeof e.value === 'string') {
|
||||
// String ise boş olup olmadığını kontrol et
|
||||
result = e.value.trim() !== '';
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
@else
|
||||
// Metin alanları ve diğer tipler için kontrol
|
||||
if (typeof e.value === 'string') {
|
||||
result = e.value.trim() !== '';
|
||||
} else {
|
||||
result = e.value !== null && e.value !== undefined;
|
||||
}
|
||||
@endif
|
||||
@else
|
||||
@if (isset($column['type']) && $column['type'] === 'date')
|
||||
// Tarih alanları için (zorunlu olmayan) - boş değerlere izin ver, dolu ise geçerli tarih kontrolü
|
||||
if (e.value === null || e.value === undefined || e.value === '') {
|
||||
result = true; // Boş değerlere izin ver
|
||||
} else if (e.value instanceof Date) {
|
||||
result = !isNaN(e.value.getTime());
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
@else
|
||||
result = true;
|
||||
@endif
|
||||
@endif
|
||||
|
||||
return result;
|
||||
@endif
|
||||
}
|
||||
@endif
|
||||
@endforeach
|
||||
@@ -0,0 +1,190 @@
|
||||
// Load module-specific setCellValue function (if exists) before initSetCellValue
|
||||
@includeIf($path. '.js.set-cell-value.'.$id)
|
||||
|
||||
function initSetCellValue(datas) {
|
||||
console.log('[DataGrid] initSetCellValue called', datas);
|
||||
console.log('[DataGrid] setCellValue function exists?', typeof setCellValue == 'function');
|
||||
if (typeof setCellValue == 'function') {
|
||||
setCellValue(datas);
|
||||
} else {
|
||||
console.warn('[DataGrid] setCellValue function not found!');
|
||||
}
|
||||
}
|
||||
console.log("Module Name: {{$id}}");
|
||||
@include("$path.partials.js-data-source")
|
||||
|
||||
function logEvent(text, description = '', type = 'success') {
|
||||
console.log(text);
|
||||
Swal.fire(
|
||||
text,
|
||||
description,
|
||||
type
|
||||
);
|
||||
}
|
||||
|
||||
const columnChooserModes = [{
|
||||
key: 'dragAndDrop',
|
||||
name: '{{e2("Drag and drop")}}',
|
||||
}, {
|
||||
key: 'select',
|
||||
name: '{{e2("Select")}}',
|
||||
}];
|
||||
|
||||
var cellColors = [];
|
||||
var description = [];
|
||||
@php
|
||||
$desc = db("column_descriptions") -> where("module_name", $id) -> get() -> pluck("description", "column_name");
|
||||
@endphp
|
||||
description = @json($desc);
|
||||
console.log(description);
|
||||
|
||||
// Value hints
|
||||
@php
|
||||
$valueHintsConfig = get_value_hints($tableName);
|
||||
@endphp
|
||||
var valueHints = @json($valueHintsConfig['hints'] ?? []);
|
||||
var hintColumns = @json($valueHintsConfig['columns'] ?? []);
|
||||
|
||||
@php
|
||||
$colors = [
|
||||
'#e8e8e8', // Açık gri
|
||||
'#d1e8f0', // Açık mavi
|
||||
'#d8f0d1', // Açık yeşil
|
||||
'#f0e8d1', // Açık sarı
|
||||
'#e8d1e8', // Açık mor
|
||||
'#f0d1d1', // Açık kırmızı
|
||||
'#d1e0e8', // Açık mavi-gri
|
||||
'#e8e0d1', // Açık bej
|
||||
'#d1e8d8', // Açık yeşil-mavi
|
||||
'#e8d8d1', // Açık pembe
|
||||
'#e8d1e8', // Açık lavanta
|
||||
'#d1e8e8', // Açık cyan
|
||||
'#e8d1d1', // Açık pembe-gri
|
||||
'#d8f0d8', // Açık mint
|
||||
'#f0e0d1', // Açık şeftali
|
||||
'#d1e0e0', // Açık teal
|
||||
'#e8e8d1', // Açık krem
|
||||
'#e8d1e8', // Açık mor-gri
|
||||
'#d1d1e8', // Açık indigo
|
||||
'#e8d8d8', // Açık somon
|
||||
'#e8e8f0', // Açık periwinkle
|
||||
'#d1e8d1', // Açık nane
|
||||
'#f0e8d8', // Açık kayısı
|
||||
'#d8f0d1', // Açık limon
|
||||
'#d1e0e8', // Açık gök mavisi
|
||||
'#e8d1e8', // Açık orkide
|
||||
'#e8d1d1', // Açık gül
|
||||
'#d1e8d8', // Açık deniz yeşili
|
||||
'#e8d8d1', // Açık şampanya
|
||||
'#e8e8e8', // Açık gümüş
|
||||
'#d1d1e8', // Açık lavanta-gri
|
||||
'#e8e8d8', // Açık altın
|
||||
'#d8f0d8', // Açık zümrüt
|
||||
'#d1e0d1', // Açık zeytin
|
||||
'#e8d1e8', // Açık mercan
|
||||
'#e8d1e8', // Açık menekşe
|
||||
'#d1e8d1', // Açık adaçayı
|
||||
'#f0d8d8', // Açık gül pembe
|
||||
'#e8e0d1', // Açık kum
|
||||
'#d1d1e8', // Açık yıldız mavisi
|
||||
'#e8d8d8', // Açık somon pembe
|
||||
'#d8f0d1', // Açık bahar yeşili
|
||||
'#d1e0e0', // Açık buz mavisi
|
||||
'#e8d1e8', // Açık leylak
|
||||
'#d1e8d1', // Açık toprak
|
||||
'#d1e8d8', // Açık okyanus
|
||||
'#e8d8d1', // Açık şeftali krem
|
||||
'#e8e8f0', // Açık gece mavisi
|
||||
'#d1d1d1', // Açık kömür
|
||||
'#e8e8d1', // Açık altın sarısı
|
||||
'#e8d1e8', // Açık iris
|
||||
'#d1e0e8', // Açık gök kuşağı
|
||||
'#e8d1d1', // Açık inci
|
||||
'#d8f0d8', // Açık yosun
|
||||
'#d1e8d1', // Açık nane yeşili
|
||||
'#e8d8d8', // Açık mercan pembe
|
||||
'#e8d1d1', // Açık kum bej
|
||||
'#d1d1e8', // Açık gök mavisi
|
||||
'#e8e8d8', // Açık altın krem
|
||||
'#e8e0d1', // Açık fildişi
|
||||
'#d1e0d1', // Açık yaprak yeşili
|
||||
'#e8d1e8', // Açık orkide pembe
|
||||
'#d8f0d1', // Açık limon yeşili
|
||||
'#d1e8d8', // Açık deniz köpüğü
|
||||
'#e8d8d1', // Açık şeftali altın
|
||||
'#e8d1e8', // Açık menekşe mavi
|
||||
'#d1e0e0', // Açık buz kristali
|
||||
'#e8d1d1', // Açık gül altın
|
||||
'#e8e8e8', // Açık gümüş beyaz
|
||||
'#d1e8d1', // Açık nane kristali
|
||||
'#e8d8d8', // Açık somon altın
|
||||
'#d8f0d8', // Açık zümrüt yeşili
|
||||
'#d1d1e8', // Açık yıldız gecesi
|
||||
'#e8d1e8', // Açık altın beyaz
|
||||
'#e8d1d1', // Açık kum altın
|
||||
'#d1e0e8', // Açık gök kristali
|
||||
'#e8d1e8', // Açık leylak pembe
|
||||
'#e8e8f0', // Açık periwinkle beyaz
|
||||
'#d1e8d8', // Açık deniz kristali
|
||||
'#e8d8d1', // Açık şeftali beyaz
|
||||
'#e8d1e8', // Açık iris beyaz
|
||||
'#d1d1d1', // Açık kömür beyaz
|
||||
'#e8e8d8', // Açık altın kristali
|
||||
'#d8f0d1', // Açık bahar kristali
|
||||
'#d1e0d1', // Açık zeytin beyaz
|
||||
'#e8d1d1', // Açık mercan kristali
|
||||
'#f0f0e0', // Açık kum kristali
|
||||
'#e8f8e8', // Açık adaçayı beyaz
|
||||
'#f8f0f0', // Açık gül kristali
|
||||
'#f0e8f0', // Açık mor beyaz
|
||||
'#e8e8f8', // Açık yıldız kristali
|
||||
'#f8f8e8', // Açık altın adaçayı
|
||||
'#f0f8f0', // Açık zümrüt kristali
|
||||
'#e8f0f8', // Açık gök adaçayı
|
||||
'#f8e8f0', // Açık leylak kristali
|
||||
'#f0f0f8', // Açık periwinkle adaçayı
|
||||
'#e8f8f0', // Açık deniz adaçayı
|
||||
'#f8f8e8', // Açık şeftali adaçayı
|
||||
'#f0e8f8', // Açık iris adaçayı
|
||||
'#e8e8e0', // Açık kömür adaçayı
|
||||
'#f8f8f0', // Açık altın adaçayı kristali
|
||||
'#f0f8e8', // Açık bahar adaçayı
|
||||
'#e8f0e0', // Açık zeytin adaçayı
|
||||
'#f8e8e8', // Açık mercan adaçayı
|
||||
'#f0f0e0', // Açık kum adaçayı
|
||||
'#e8f8e8', // Açık adaçayı kristali
|
||||
'#f8f0f0', // Açık gül adaçayı
|
||||
'#f0e8f0', // Açık mor adaçayı
|
||||
'#e8e8f8', // Açık yıldız adaçayı
|
||||
'#f8f8e8', // Açık altın adaçayı beyaz
|
||||
'#f0f8f0', // Açık zümrüt adaçayı
|
||||
'#e8f0f8', // Açık gök adaçayı beyaz
|
||||
];
|
||||
|
||||
if (isset($blockGroup)) {
|
||||
$colorIndex = 0;
|
||||
foreach($blockGroup as $blockTitle => $columns) {
|
||||
$color = $colors[$colorIndex] ?? '#ffffff';
|
||||
echo "cellColors['".e2($blockTitle). "'] = '{$color}';\n";
|
||||
foreach($columns as $column) {
|
||||
echo "cellColors['{$column}'] = '{$color}';\n";
|
||||
}
|
||||
$colorIndex++;
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
|
||||
var selectedData = null;
|
||||
var copyData = null;
|
||||
var selectedRowIndex = null;
|
||||
var selectedColIndex = null;
|
||||
var addedRow = 1;
|
||||
|
||||
const userId = "{{ u()->id }}";
|
||||
const tableName = "{{ $tableName }}";
|
||||
const storageKey = `grid_state_${userId}_${tableName}`;
|
||||
const moduleId = "{{ isset($id) ? $id : '' }}";
|
||||
// Inspection History IDs
|
||||
var inspectionRowIds = @json($inspectionRowIds ?? []);
|
||||
console.log("inspectionRowIds");
|
||||
console.log(inspectionRowIds);
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
dataField: "{{$name}}",
|
||||
caption: "Screenshot",
|
||||
allowEditing: false,
|
||||
allowFiltering: false,
|
||||
allowSorting: false,
|
||||
allowExporting: false,
|
||||
cellTemplate: function (container, options) {
|
||||
if (options.data.screenshot_path) {
|
||||
|
||||
var filePath = options.data.screenshot_path.replace(/^storage\//, '');
|
||||
var fileUrl = '/' + filePath;
|
||||
|
||||
$('<a><i class="fa fa-file-pdf" style="color:#d9534f; font-size:18px;"></i></a>')
|
||||
.attr('href', fileUrl)
|
||||
.attr('target', '_blank')
|
||||
.attr('download', fileUrl.split('/').pop())
|
||||
.appendTo(container);
|
||||
} else {
|
||||
$('<span>-</span>').appendTo(container);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
dataField: "{{$name}}",
|
||||
allowEditing: false,
|
||||
allowFiltering: true,
|
||||
allowSorting: true,
|
||||
allowExporting: false,
|
||||
cellTemplate: function (container, options) {
|
||||
|
||||
<?php
|
||||
$data = [
|
||||
'path' => $prependColumn['path'],
|
||||
'pattern' => $prependColumn['pattern'],
|
||||
];
|
||||
?>
|
||||
|
||||
if(typeof options.data.id != "undefined") {
|
||||
var url = "{{url("/admin/link-creator/")}}/{{$tableName}}/" + options.data.id + '/?data=<?php echo json_encode_tr($data) ?>';
|
||||
$.ajax({
|
||||
url : url,
|
||||
success: function(result) {
|
||||
$('<a><?php echo $prependColumn['html'] ?: '<i class="fa fa-file-pdf"></i>' ?></a>')
|
||||
.attr('href', result)
|
||||
.attr('target', '_blank')
|
||||
.appendTo(container);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
$patternString = $prependColumn['pattern'];
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
?>
|
||||
{
|
||||
dataField: "{{$patternString}}",
|
||||
caption: "{{$name}}",
|
||||
allowEditing: true,
|
||||
allowExporting: false,
|
||||
allowFiltering: true,
|
||||
allowSorting: true,
|
||||
cellTemplate: function (container, options) {
|
||||
<?php
|
||||
|
||||
foreach($variables AS $variable) {
|
||||
$patternString = str_replace($variable, "options.data.".$variable, $patternString);
|
||||
}
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
?>
|
||||
var text = `{{$patternString}}`;
|
||||
container.html(text);
|
||||
|
||||
|
||||
},
|
||||
<?php if(isset($column['name'])) {
|
||||
?>
|
||||
setCellValue(rowData, value, data, options) {
|
||||
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
<?php } ?>
|
||||
},
|
||||
@@ -0,0 +1,241 @@
|
||||
{
|
||||
dataField: "{{ $column['name'] }}",
|
||||
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption'])
|
||||
? $column['relation']['caption']
|
||||
: $column['name'];
|
||||
|
||||
// Fetch distinct values from database to persist custom values after refresh
|
||||
$dbDistinctValues = [];
|
||||
|
||||
if (isset($tableDifferentValues) && isset($tableDifferentValues[$column['name']])) {
|
||||
$dbDistinctValues = $tableDifferentValues[$column['name']];
|
||||
} elseif (isset($tableName)) {
|
||||
try {
|
||||
$dbDistinctValues = db($tableName)
|
||||
->whereNotNull($column['name'])
|
||||
->where($column['name'], '!=', '')
|
||||
->distinct()
|
||||
->pluck($column['name'])
|
||||
->filter()
|
||||
->values()
|
||||
->toArray();
|
||||
} catch (\Exception $e) {
|
||||
$dbDistinctValues = [];
|
||||
}
|
||||
}
|
||||
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
|
||||
caption: "{{ e2($captionName) }}",
|
||||
dataType: "string",
|
||||
isSelectDropdown: true,
|
||||
|
||||
calculateDisplayValue: function (rowData) {
|
||||
var value = rowData['{{ $column['name'] }}'];
|
||||
return value || '';
|
||||
},
|
||||
|
||||
<?php if (in_array($column['name'], $requiredFields)) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } else { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{ $column['name'] }},
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
|
||||
lookup: {
|
||||
dataSource: createFuseSearchStore(
|
||||
(function () {
|
||||
|
||||
// Merge database distinct values with existing data
|
||||
var dbValues = <?php echo json_encode(array_values($dbDistinctValues)); ?>;
|
||||
var existingData = {{ $column['name'] }}_data || [];
|
||||
|
||||
<?php
|
||||
$vars = pattern_to_variables($column['relation']['pattern'])[1];
|
||||
$firstVar = $vars[0] ?? 'value';
|
||||
?>
|
||||
|
||||
// Add DB values as objects if they don't exist in existing data
|
||||
dbValues.forEach(function (val) {
|
||||
if (val && typeof val === 'string') {
|
||||
|
||||
var exists = existingData.some(function (item) {
|
||||
if (typeof item === 'string') return item === val;
|
||||
return item['{{ $firstVar }}'] === val;
|
||||
});
|
||||
|
||||
if (!exists) {
|
||||
var obj = {};
|
||||
obj['{{ $firstVar }}'] = val;
|
||||
existingData.push(obj);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return existingData;
|
||||
})(),
|
||||
[
|
||||
<?php
|
||||
$vars = pattern_to_variables($column['relation']['pattern'])[1];
|
||||
foreach ($vars as $v) {
|
||||
echo "'$v',";
|
||||
}
|
||||
?>
|
||||
]
|
||||
),
|
||||
|
||||
<?php
|
||||
$patternString = $column['relation']['pattern'];
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
|
||||
foreach ($variables as $variable) {
|
||||
$patternString = str_replace(
|
||||
$variable,
|
||||
"data." . $variable,
|
||||
$patternString
|
||||
);
|
||||
}
|
||||
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
?>
|
||||
|
||||
valueExpr: function (data) {
|
||||
if (data) {
|
||||
if (typeof data === 'string') return data;
|
||||
return `{{ $patternString }}`;
|
||||
}
|
||||
},
|
||||
|
||||
displayExpr: function (data) {
|
||||
if (data) {
|
||||
if (typeof data === 'string') return data;
|
||||
return `{{ $patternString }}`;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
editorOptions: {
|
||||
acceptCustomValue: true,
|
||||
|
||||
onCustomItemCreating: function (args) {
|
||||
if (!args.text || args.text.trim() === '') {
|
||||
args.customItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var customText = args.text.trim();
|
||||
|
||||
// Create an object matching the data structure
|
||||
var customObj = {};
|
||||
|
||||
<?php
|
||||
$vars = pattern_to_variables($column['relation']['pattern'])[1];
|
||||
$firstVar = $vars[0] ?? 'value';
|
||||
?>
|
||||
|
||||
customObj['{{ $firstVar }}'] = customText;
|
||||
|
||||
// Add to the data array so byKey can find it
|
||||
{{ $column['name'] }}_data.push(customObj);
|
||||
|
||||
args.customItem = customObj;
|
||||
},
|
||||
|
||||
searchEnabled: true,
|
||||
searchMode: 'contains',
|
||||
searchTimeout: 200,
|
||||
minSearchLength: 0,
|
||||
showClearButton: true,
|
||||
|
||||
onSelectionChanged: function (selectionChangedArgs) {
|
||||
console.log("onSelectionChanged");
|
||||
console.log(selectionChangedArgs);
|
||||
|
||||
localStorage.setItem(
|
||||
"selectedRowData",
|
||||
JSON.stringify(selectionChangedArgs.selectedItem)
|
||||
);
|
||||
},
|
||||
|
||||
onFocusIn: function (e) {
|
||||
try {
|
||||
// open lookup once focused
|
||||
e.component.open();
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
|
||||
// this prevents button click from closing the lookup
|
||||
openOnFieldClick: false
|
||||
},
|
||||
|
||||
setCellValue(rowData, value, data, options) {
|
||||
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
|
||||
console.log("setCellValue");
|
||||
console.log(value);
|
||||
|
||||
rowData.{{ $column['name'] }} = value;
|
||||
|
||||
var exceptValue = ['undefined', 'null'];
|
||||
var selectedRowData = localStorage.getItem("selectedRowData");
|
||||
|
||||
try {
|
||||
var selectedRow = JSON.parse(selectedRowData);
|
||||
|
||||
/*
|
||||
{{ $column['name'] }}_data.forEach(data => {
|
||||
if (`{{ $patternString }}` == value) {
|
||||
selectedRow = data;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
<?php
|
||||
if (isset($column['relation']['affected'])) {
|
||||
foreach ($column['relation']['affected'] as $affectColumn => $affectedValue) {
|
||||
|
||||
$patternString = $affectedValue;
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
|
||||
foreach ($variables as $variable) {
|
||||
$patternString = str_replace(
|
||||
$variable,
|
||||
"selectedRow." . $variable,
|
||||
$patternString
|
||||
);
|
||||
}
|
||||
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
|
||||
if ($patternString != "all") {
|
||||
?>
|
||||
if (!exceptValue.includes(`{{ $patternString }}`)) {
|
||||
rowData.<?php echo $affectColumn ?> = `{{ $patternString }}`;
|
||||
}
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
|
||||
// editCellTemplate: {{ $column['name'] }}_dropDownBoxEditorTemplate,
|
||||
},
|
||||
@@ -0,0 +1,229 @@
|
||||
{
|
||||
dataField: "{{ $column['name'] }}",
|
||||
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption'])
|
||||
? $column['relation']['caption']
|
||||
: $column['name'];
|
||||
|
||||
// Fetch distinct values from database to persist custom values after refresh
|
||||
$dbDistinctValues = [];
|
||||
|
||||
if (isset($tableDifferentValues) && isset($tableDifferentValues[$column['name']])) {
|
||||
$dbDistinctValues = $tableDifferentValues[$column['name']];
|
||||
} elseif (isset($tableName)) {
|
||||
try {
|
||||
$dbDistinctValues = db($tableName)
|
||||
->whereNotNull($column['name'])
|
||||
->where($column['name'], '!=', '')
|
||||
->distinct()
|
||||
->pluck($column['name'])
|
||||
->filter()
|
||||
->values()
|
||||
->toArray();
|
||||
} catch (\Exception $e) {
|
||||
$dbDistinctValues = [];
|
||||
}
|
||||
}
|
||||
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
|
||||
caption: "{{ e2($captionName) }}",
|
||||
dataType: "{{ $column['type'] }}",
|
||||
isSelectDropdown: true,
|
||||
|
||||
calculateDisplayValue: function (rowData) {
|
||||
var value = rowData['{{ $column['name'] }}'];
|
||||
return value || '';
|
||||
},
|
||||
|
||||
<?php if (in_array($column['name'], $requiredFields)) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } else { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{ $column['name'] }},
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
|
||||
lookup: {
|
||||
dataSource: createFuseSearchStore(
|
||||
(function () {
|
||||
|
||||
// Merge database distinct values with existing data
|
||||
var dbValues = <?php echo json_encode(array_values($dbDistinctValues)); ?>;
|
||||
var existingData = {{ $column['name'] }}_data || [];
|
||||
|
||||
<?php
|
||||
$vars2 = pattern_to_variables($column['relation']['pattern'])[1];
|
||||
$firstVar2 = $vars2[0] ?? 'value';
|
||||
?>
|
||||
|
||||
// Add DB values as objects if they don't exist in existing data
|
||||
dbValues.forEach(function (val) {
|
||||
if (val && typeof val === 'string') {
|
||||
|
||||
var exists = existingData.some(function (item) {
|
||||
if (typeof item === 'string') return item === val;
|
||||
return item['{{ $firstVar2 }}'] === val;
|
||||
});
|
||||
|
||||
if (!exists) {
|
||||
var obj = {};
|
||||
obj['{{ $firstVar2 }}'] = val;
|
||||
existingData.push(obj);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return existingData;
|
||||
})(),
|
||||
[
|
||||
<?php
|
||||
$vars = pattern_to_variables($column['relation']['pattern'])[1];
|
||||
foreach ($vars as $v) {
|
||||
echo "'$v',";
|
||||
}
|
||||
?>
|
||||
]
|
||||
),
|
||||
|
||||
<?php
|
||||
$patternString = $column['relation']['pattern'];
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
|
||||
foreach ($variables as $variable) {
|
||||
$patternString = str_replace(
|
||||
$variable,
|
||||
"data." . $variable,
|
||||
$patternString
|
||||
);
|
||||
}
|
||||
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
?>
|
||||
|
||||
valueExpr: function (data) {
|
||||
if (data) {
|
||||
if (typeof data === 'string') return data;
|
||||
return `{{ $patternString }}`;
|
||||
}
|
||||
},
|
||||
|
||||
displayExpr: function (data) {
|
||||
if (data) {
|
||||
if (typeof data === 'string') return data;
|
||||
return `{{ $patternString }}`;
|
||||
}
|
||||
},
|
||||
|
||||
onSelectionChanged: function (e) {
|
||||
// console.log(e);
|
||||
},
|
||||
},
|
||||
|
||||
editorOptions: {
|
||||
acceptCustomValue: true,
|
||||
|
||||
onCustomItemCreating: function (args) {
|
||||
if (!args.text || args.text.trim() === '') {
|
||||
args.customItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var customText = args.text.trim();
|
||||
|
||||
// Create an object matching the data structure
|
||||
var customObj = {};
|
||||
|
||||
<?php
|
||||
$vars2 = pattern_to_variables($column['relation']['pattern'])[1];
|
||||
$firstVar2 = $vars2[0] ?? 'value';
|
||||
?>
|
||||
|
||||
customObj['{{ $firstVar2 }}'] = customText;
|
||||
|
||||
// Add to the data array so byKey can find it
|
||||
{{ $column['name'] }}_data.push(customObj);
|
||||
|
||||
args.customItem = customObj;
|
||||
},
|
||||
|
||||
searchEnabled: true,
|
||||
searchMode: 'contains',
|
||||
searchTimeout: 200,
|
||||
minSearchLength: 0,
|
||||
showClearButton: true,
|
||||
|
||||
onFocusIn: function (e) {
|
||||
try {
|
||||
// open lookup once focused
|
||||
e.component.open();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
setCellValue(rowData, value, data, options) {
|
||||
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
|
||||
console.log("setCellValue");
|
||||
console.log(value);
|
||||
|
||||
rowData.{{ $column['name'] }} = value;
|
||||
|
||||
var selectedRowData = localStorage.getItem("selectedRowData");
|
||||
|
||||
try {
|
||||
var selectedRow = JSON.parse(selectedRowData);
|
||||
|
||||
/*
|
||||
{{ $column['name'] }}_data.forEach(data => {
|
||||
if (`{{ $patternString }}` == value) {
|
||||
selectedRow = data;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
<?php
|
||||
if (isset($column['relation']['affected'])) {
|
||||
foreach ($column['relation']['affected'] as $affectColumn => $affectedValue) {
|
||||
|
||||
$patternString = $affectedValue;
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
|
||||
foreach ($variables as $variable) {
|
||||
$patternString = str_replace(
|
||||
$variable,
|
||||
"selectedRow." . $variable,
|
||||
$patternString
|
||||
);
|
||||
}
|
||||
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
|
||||
if ($patternString != "all") {
|
||||
?>
|
||||
rowData.<?php echo $affectColumn ?> = `{{ $patternString }}`;
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
|
||||
editCellTemplate: {{ $column['name'] }}_dropDownBoxEditorTemplate,
|
||||
},
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "string",
|
||||
validationRules: [{
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
lookup: {
|
||||
dataSource : [
|
||||
<?php foreach($column['relation']['datas'] AS $data) {
|
||||
$key = $column['relation']['value'];
|
||||
?>
|
||||
'{{$data->$key}}',
|
||||
<?php
|
||||
} ?>
|
||||
]
|
||||
},
|
||||
editorOptions: {
|
||||
searchEnabled: true,
|
||||
searchMode: 'contains',
|
||||
searchTimeout: 200,
|
||||
minSearchLength: 0,
|
||||
showClearButton: true
|
||||
},
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
rowData.{{$column['name']}} = value;
|
||||
datas = {
|
||||
'rowData' : rowData,
|
||||
'value' : value,
|
||||
'options' : options,
|
||||
'data' : data,
|
||||
'name' : "{{$column['name']}}",
|
||||
'type' : "{{$column['type']}}",
|
||||
};
|
||||
if(typeof initChange === 'function') {
|
||||
initChange(datas);
|
||||
}
|
||||
try {
|
||||
|
||||
} catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
@if($column['name'] == 'constructor')
|
||||
name: "constructor_column",
|
||||
@endif
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
$validationType = $column['relation']['validationType'] ?? 'custom';
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "string",
|
||||
validationRules: [{
|
||||
|
||||
type : '{{$validationType}}',
|
||||
validationCallback: validationCallback_{{$column['name']}},
|
||||
}],
|
||||
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
|
||||
},
|
||||
@@ -0,0 +1,87 @@
|
||||
@php
|
||||
$seperator = isset($column['relation']['seperator']) ? $column['relation']['seperator'] : ",";
|
||||
$multipleChoiceData = [];
|
||||
$localStorageData = [];
|
||||
foreach($column['relation']['datas'] AS $data) {
|
||||
$patternString = $column['relation']['pattern'];
|
||||
|
||||
preg_match_all('/{(.*?)}/',$patternString, $matches);
|
||||
|
||||
if(isset($matches[1])) {
|
||||
foreach($matches[1] AS $match) {
|
||||
$patternString = str_replace("{" . $match . "}", $data->$match, $patternString);
|
||||
}
|
||||
}
|
||||
$multipleChoiceData[] = $patternString;
|
||||
$localStorageData[$patternString] = $data;
|
||||
}
|
||||
@endphp
|
||||
|
||||
const {{$column['name']}}_tag_data = <?php echo json_encode_tr($multipleChoiceData) ?>;
|
||||
localStorage.setItem("{{$column['name']}}_tag_data", JSON.stringify(<?php echo json_encode_tr($localStorageData) ?>));
|
||||
|
||||
function {{$column['name']}}_tagBoxEditorTemplate(cellElement, cellInfo) {
|
||||
var cellValue = cellInfo.value != null
|
||||
? cellInfo.value.split("{{$seperator}}").filter(val => val.trim() !== "")
|
||||
: [];
|
||||
|
||||
return $('<div>').dxTagBox({
|
||||
dataSource: {{$column['name']}}_tag_data,
|
||||
value: cellValue,
|
||||
showSelectionControls: true,
|
||||
maxDisplayedTags: 2,
|
||||
showMultiTagOnly: false,
|
||||
applyValueMode: 'instantly',
|
||||
searchEnabled: true,
|
||||
onValueChanged(e) {
|
||||
console.log("onValueChanged");
|
||||
console.log(e);
|
||||
|
||||
try {
|
||||
// Yeni değerlerden boş olanları filtrele
|
||||
const filteredValues = e.value != null
|
||||
? e.value.filter(val => val.trim() !== "")
|
||||
: [];
|
||||
|
||||
// Hücreye yeni değeri uygula
|
||||
cellInfo.setValue(filteredValues.join("{{$seperator}}"));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
onFocusIn(e) {
|
||||
console.log("onFocusIn");
|
||||
console.log(e);
|
||||
|
||||
if (typeof tagBoxFocusIn == 'function') {
|
||||
tagBoxFocusIn(e, cellElement, cellInfo);
|
||||
} else {
|
||||
console.log("tagBoxFocusIn not found");
|
||||
}
|
||||
|
||||
e.component.open(); // TagBox açılıyor
|
||||
},
|
||||
onFocusOut(e) {
|
||||
console.log("onFocusOut");
|
||||
console.log(e);
|
||||
|
||||
if (typeof tagBoxFocusOut == 'function') {
|
||||
tagBoxFocusOut(e, cellElement, cellInfo);
|
||||
} else {
|
||||
console.log("tagBoxFocusOut not found");
|
||||
}
|
||||
},
|
||||
onSelectionChanged(e) {
|
||||
console.log("onSelectionChanged");
|
||||
console.log(e);
|
||||
|
||||
if (typeof tagBoxSelectionChanged == 'function') {
|
||||
tagBoxSelectionChanged(e, cellElement, cellInfo);
|
||||
} else {
|
||||
console.log("tagBoxSelectionChanged not found");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
@php
|
||||
try {
|
||||
$thisColumns =$column['relation']['datas'][0];
|
||||
} catch (\Throwable $th) {
|
||||
//throw $th;
|
||||
$thisColumns = null;
|
||||
}
|
||||
|
||||
|
||||
$printColumn = pattern_to_variables($column['relation']['pattern'])[1]; //[];
|
||||
|
||||
if(count($printColumn)<4) {
|
||||
$exceptColumns = ['id', 'updated_at', 'created_at'];
|
||||
$exceptColumns = array_merge($exceptColumns,$printColumn);
|
||||
|
||||
$printColumnCount = 0;
|
||||
if(!is_null($thisColumns)) {
|
||||
foreach($thisColumns AS $thisColumn => $thisColumnData) {
|
||||
if(!in_array($thisColumn, $exceptColumns)) {
|
||||
$printColumn[] = $thisColumn;
|
||||
|
||||
$printColumnCount++;
|
||||
if($printColumnCount > 4) break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$selecDropDownData = [];
|
||||
foreach($column['relation']['datas'] AS $data) {
|
||||
$patternString = $column['relation']['pattern'];
|
||||
|
||||
preg_match_all('/{(.*?)}/',$patternString, $matches);
|
||||
|
||||
if(isset($matches[1])) {
|
||||
foreach($matches[1] AS $match) {
|
||||
$patternString = str_replace("{" . $match . "}", $data->$match, $patternString);
|
||||
}
|
||||
}
|
||||
$selecDropDownData[] = $patternString;
|
||||
}
|
||||
@endphp
|
||||
|
||||
const {{$column['name']}}_tag_data = <?php echo json_encode_tr($selecDropDownData) ?>;
|
||||
|
||||
// alert("ok");
|
||||
function {{$column['name']}}_dropDownBoxEditorTemplate(cellElement, cellInfo) {
|
||||
return $('<div>').dxDropDownBox({
|
||||
acceptCustomValue : true,
|
||||
openOnFieldClick: false,
|
||||
onEnterKey: function(e) {
|
||||
var component = e.component;
|
||||
var value = component.option("value");
|
||||
var dataSource = component.option("dataSource");
|
||||
dataSource.push(value);
|
||||
component.option("dataSource", dataSource);
|
||||
component.option("value", "");
|
||||
},
|
||||
dropDownOptions: {
|
||||
width: {{count($printColumn)*250}},
|
||||
maxWidth: "50vw",
|
||||
|
||||
class: "dropDownBox"
|
||||
},
|
||||
|
||||
// dataSource: {{$column['name']}}_tag_data,
|
||||
|
||||
@php
|
||||
$patternString = $column['relation']['pattern'];
|
||||
$variables = pattern_to_variables($patternString)[1];
|
||||
foreach($variables AS $variable) {
|
||||
$patternString = str_replace($variable, "data.".$variable, $patternString);
|
||||
}
|
||||
$patternString = str_replace('{', '${', $patternString);
|
||||
@endphp
|
||||
keyExpr: function(data) {
|
||||
if(data) {
|
||||
return `{{$patternString}}`;
|
||||
}
|
||||
},
|
||||
|
||||
onInitialized: function(e) {
|
||||
/*
|
||||
$(e.element).on("focusin", function() {
|
||||
e.component.option("opened", true);
|
||||
//e.component.option().focus();
|
||||
});
|
||||
*/
|
||||
},
|
||||
value: cellInfo.value,
|
||||
contentTemplate(e) {
|
||||
return $('<div>').dxDataGrid({
|
||||
dataSource: {{$column['name']}}_data,
|
||||
keyExpr: function(data) {
|
||||
if(data) {
|
||||
return `{{$patternString}}`;
|
||||
}
|
||||
},
|
||||
editing: {
|
||||
mode: 'cell',
|
||||
allowAdding: true,
|
||||
},
|
||||
hoverStateEnabled: true,
|
||||
keyboardNavigation: {
|
||||
enterKeyAction: 'moveFocus',
|
||||
enterKeyDirection: 'row',
|
||||
editOnKeyPress: true,
|
||||
},
|
||||
remoteOperations: false,
|
||||
columns: <?php echo json_encode_tr($printColumn); ?>,
|
||||
hoverStateEnabled: false,
|
||||
scrolling: { mode: 'virtual' },
|
||||
filterRow: { visible: true },
|
||||
height: 250,
|
||||
search: true,
|
||||
selection: { mode: 'single' },
|
||||
selectedRowKeys: [cellInfo.value],
|
||||
focusedRowEnabled: true,
|
||||
focusedRowKey: cellInfo.value,
|
||||
editorOptions: {
|
||||
|
||||
|
||||
onSelectionChanged(selectionChangedArgs) {
|
||||
console.log("onSelectionChanged");
|
||||
console.log(selectionChangedArgs);
|
||||
console.log(selectionChangedArgs.selectedRowKeys[0]);
|
||||
|
||||
localStorage.setItem("selectedRowData", JSON.stringify(selectionChangedArgs.selectedRowsData[0]));
|
||||
// console.log(localStorage.getItem("selectedRowData"));
|
||||
e.component.option('value', selectionChangedArgs.selectedRowKeys[0]);
|
||||
cellInfo.setValue(selectionChangedArgs.selectedRowKeys[0]);
|
||||
|
||||
|
||||
//cellInfo.setValue("selectionChangedArgs.selectedRowKeys[0]");
|
||||
if (selectionChangedArgs.selectedRowKeys.length > 0) {
|
||||
e.component.close();
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "string",
|
||||
<?php if(in_array($column['name'], $requiredFields)) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
},
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
dataField: "{{($column['name'])}}",
|
||||
<?php
|
||||
$captionName = isset($column['relation']['caption']) ? $column['relation']['caption'] : $column['name'];
|
||||
?>
|
||||
caption: "{{e2($captionName)}}",
|
||||
dataType: "time",
|
||||
dataType: "string",
|
||||
editorOptions: {
|
||||
mask: "00:00",
|
||||
maskRules: {
|
||||
"0": /[0-9]/
|
||||
},
|
||||
useMaskedValue: true
|
||||
},
|
||||
<?php if(in_array($column['name'], $requiredFields)) { ?>
|
||||
validationRules: [
|
||||
{
|
||||
type: 'required'
|
||||
}
|
||||
],
|
||||
<?php } ?>
|
||||
setCellValue(rowData, value, data, options) {
|
||||
@include("components.table.datagrid.js.init-cell-value")
|
||||
},
|
||||
},
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
if(typeof e.value == "undefined") {
|
||||
return true;
|
||||
} else {
|
||||
var min = e.data.date;
|
||||
var selectedDate = e.value;
|
||||
|
||||
var formattedDate = moment(min).format("DD/MM/YYYY");
|
||||
e.rule.message = "Date Start from " + formattedDate;
|
||||
|
||||
if(moment(min).isSameOrBefore(selectedDate, 'day')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.getJSON("{{autocomplete_type("pqr_date")}}?row=" + encodeURIComponent(JSON.stringify(e.data)), function(dateJSON) {
|
||||
|
||||
var min = dateJSON.valid_from;
|
||||
var max = dateJSON.valid_to;
|
||||
var selectedDate = e.value;
|
||||
var result;
|
||||
|
||||
e.rule.message = "Date Between from " + min + " to " + max;
|
||||
|
||||
if(moment(selectedDate).isBetween(min, max)) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
d.resolve(result);
|
||||
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.get("?ajax=punch-list-no-diff&test_package="+e.data.test_package+"&value=" + e.value, function(response) {
|
||||
response = response.trim();
|
||||
var result;
|
||||
console.log(response);
|
||||
if(response == 1) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
e.rule.message = "This trick has been used before. Please use a different number";
|
||||
}
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.get("?ajax=diff-rfi-no&row=" + encodeURIComponent(JSON.stringify(e.data)), function(response) {
|
||||
|
||||
var result;
|
||||
response = response.trim();
|
||||
|
||||
|
||||
if(response == 1) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
e.rule.message = "This trick has been used before. Please use a different number";
|
||||
}
|
||||
d.resolve(result);
|
||||
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.get("?ajax=no_of_the_joint_as_per_as_built_survey-diff&id="+e.data.id+"&iso_number="+e.data.iso_number+"&value=" + e.value, function(response) {
|
||||
response = response.trim();
|
||||
var result;
|
||||
console.log(response);
|
||||
if(response == 0) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
e.rule.message = "This joint has been used before. Please use a different number";
|
||||
}
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
try {
|
||||
var nps_1 = eval(e.value);
|
||||
var nps_2 = eval(e.data.nps_2);
|
||||
// Check if nps_1 is null or empty
|
||||
if (e.value === null || e.value === "" || e.value === undefined) {
|
||||
e.rule.message = "{{e2("Please enter a valid value")}}";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nps_2 == nps_1) {
|
||||
return true;
|
||||
}
|
||||
if (nps_2 > nps_1) {
|
||||
return true;
|
||||
}
|
||||
if (nps_2 < nps_1) {
|
||||
e.rule.message = "{{e2("Please enter a value less than")}} " + nps_2;
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("error");
|
||||
console.log(error);
|
||||
|
||||
return true;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
try {
|
||||
var nps_2 = eval(e.value);
|
||||
var nps_1 = eval(e.data.nps_1);
|
||||
|
||||
if (e.value === null || e.value === "" || e.value === undefined) {
|
||||
e.rule.message = "{{e2("Please enter a valid value")}}";
|
||||
return false;
|
||||
}
|
||||
if(e.data.type_of_welds == "BW")
|
||||
{
|
||||
|
||||
if(nps_2 == nps_1){
|
||||
return true;
|
||||
} else {
|
||||
e.rule.message = "{{e2("Please same value of NPS1 Because this type of welds: BW ")}} ";
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return true;
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
const d = $.Deferred();
|
||||
var result;
|
||||
|
||||
if (e.value === null || e.value === "" || e.value === undefined) {
|
||||
e.rule.message = "{{e2("Please enter a valid value")}}";
|
||||
return false;
|
||||
}
|
||||
|
||||
$.getJSON("{{row_detail_url("w_p_s","details")}}?value=" + e.data.wps_no, function(wpsDetail) {
|
||||
|
||||
var min = wpsDetail.min_outside_diameter;
|
||||
var max = wpsDetail.max_outside_diameter;
|
||||
|
||||
|
||||
|
||||
@if($id != "base-weldmap")
|
||||
if(typeof min !== "undefined") {
|
||||
|
||||
if(max == null) {
|
||||
max = min + 10000;
|
||||
e.rule.message = "must be start from " + min;
|
||||
} else {
|
||||
e.rule.message = "must be between from " + min + " to " + max ;
|
||||
}
|
||||
|
||||
if(e.value>=min && e.value<=max) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
@else
|
||||
result = true;
|
||||
@endif
|
||||
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
try {
|
||||
if (e.value === null || e.value === "" || e.value === undefined) {
|
||||
e.rule.message = "{{e2("Please enter a valid value")}}";
|
||||
return false;
|
||||
}
|
||||
if(e.data.type_of_welds == "BW")
|
||||
{
|
||||
var outside_diameter_2 = eval(e.value);
|
||||
var outside_diameter_1 = eval(e.data.outside_diameter_1);
|
||||
|
||||
if(outside_diameter_1 == outside_diameter_2){
|
||||
return true;
|
||||
} else {
|
||||
e.rule.message = "{{e2("Please same value of OD1 Because this type of welds: BW ")}} ";
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return true;
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
if(e.data.welding_date != null) {
|
||||
if(e.value == null) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
|
||||
const d = $.Deferred();
|
||||
|
||||
$.getJSON("{{row_detail_url("w_p_s","details")}}?value=" + e.data.wps_no, function(wpsDetail) {
|
||||
|
||||
var min = wpsDetail.min_thick;
|
||||
var max = wpsDetail.max_thick;
|
||||
|
||||
var result;
|
||||
@if($id != "base-weldmap")
|
||||
if(typeof min !== "undefined") {
|
||||
|
||||
if(max == null) {
|
||||
max = min + 10000;
|
||||
e.rule.message = "must be start from " + min;
|
||||
} else {
|
||||
e.rule.message = "must be between from " + min + " to " + max ;
|
||||
}
|
||||
|
||||
if(e.value>=min && e.value<=max) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
@else
|
||||
result = true;
|
||||
@endif
|
||||
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
@php
|
||||
$currentUserLevel = u()->level ?? null;
|
||||
$weldLogEditTimeLimitExceptLevels = j(setting('weld_log_edit_time_limit_except_levels'));
|
||||
if (empty($weldLogEditTimeLimitExceptLevels)) {
|
||||
$weldLogEditTimeLimitExceptLevels = [
|
||||
'Admin',
|
||||
'Manager (Center Office)',
|
||||
'Manager (PTO)',
|
||||
'Manager (Lead)',
|
||||
'Quality Staff',
|
||||
];
|
||||
}
|
||||
@endphp
|
||||
|
||||
const weldLogEditTimeLimitExceptLevels = {!! json_encode($weldLogEditTimeLimitExceptLevels) !!};
|
||||
const currentUserLevel = {!! json_encode($currentUserLevel) !!};
|
||||
const isUserInWeldLogExceptionList = Array.isArray(weldLogEditTimeLimitExceptLevels) && currentUserLevel
|
||||
? weldLogEditTimeLimitExceptLevels.includes(currentUserLevel)
|
||||
: false;
|
||||
|
||||
const d = $.Deferred();
|
||||
var result;
|
||||
$.getJSON("{{row_detail_url("document_revisions","drawing_no")}}?nolike&order=revision_no:desc&value=" + e.data.iso_number, function(revisionDetail) {
|
||||
var min = e.data.fit_up_date;
|
||||
|
||||
var wpsNo = e.data.wps_no;
|
||||
|
||||
if(e.data.wps_no == null) {
|
||||
wpsNo = "";
|
||||
}
|
||||
|
||||
if(typeof e.data.wps_no != "string") {
|
||||
wpsNo = "";
|
||||
}
|
||||
|
||||
var selectedDate = e.value;
|
||||
if(selectedDate == null) {
|
||||
if(wpsNo === "") {
|
||||
result = true;
|
||||
} else {
|
||||
e.rule.message = "Since WPS number is entered, Welding Date must be entered.";
|
||||
result = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if(min == null) {
|
||||
result = true;
|
||||
} else {
|
||||
|
||||
if(moment(selectedDate).isSameOrAfter(min, 'day')) {
|
||||
e.rule.message = "Date Start from " + min;
|
||||
result = true;
|
||||
} else {
|
||||
e.rule.message = "Welding Date must be on or after Fit-up Date: " + moment(min).format('DD/MM/YYYY');
|
||||
result = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Date restriction check based on weld_date_restriction_days setting
|
||||
if(result && selectedDate != null && !isUserInWeldLogExceptionList) {
|
||||
var restrictionDays = {{setting('weld_date_restriction_days') ? setting('weld_date_restriction_days') : 'null'}};
|
||||
if(restrictionDays && restrictionDays > 0) {
|
||||
var today = moment();
|
||||
var maxAllowedDate = moment().add(restrictionDays, 'days');
|
||||
var minAllowedDate = moment().subtract(restrictionDays, 'days');
|
||||
|
||||
if(moment(selectedDate).isAfter(maxAllowedDate)) {
|
||||
e.rule.message = "Welding date cannot be more than " + restrictionDays + " days in the future. Maximum allowed date: " + maxAllowedDate.format('DD/MM/YYYY');
|
||||
result = false;
|
||||
} else if(moment(selectedDate).isBefore(minAllowedDate)) {
|
||||
e.rule.message = "Welding date cannot be more than " + restrictionDays + " days in the past. Minimum allowed date: " + minAllowedDate.format('DD/MM/YYYY');
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(result) {
|
||||
if(selectedDate == null ) {
|
||||
|
||||
} else {
|
||||
if(revisionDetail.revision_no != e.data.iso_rev) {
|
||||
e.rule.message = "Different revision no. Weldlog rev no: " + e.data.iso_rev + ", document revision no: " + revisionDetail.revision_no;
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
d.resolve(result);
|
||||
|
||||
});
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
|
||||
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
var max = e.data.welding_date;
|
||||
if(max == null) {
|
||||
return true;
|
||||
} else {
|
||||
var selectedDate = e.value;
|
||||
|
||||
e.rule.message = "Max date" + max ;
|
||||
|
||||
if(moment(selectedDate).isSameOrBefore(max, 'day')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
if(e.value == null) {
|
||||
return true;
|
||||
} else {
|
||||
var min = e.data.welding_date;
|
||||
var selectedDate = e.value;
|
||||
var formattedDate = moment(selectedDate).format("DD/MM/YYYY");
|
||||
e.rule.message = "Date Start from " + formattedDate;
|
||||
|
||||
if(moment(selectedDate).isSameOrAfter(min, 'day')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// Skip validation for PLATE type - diameter is not applicable
|
||||
if (e.data.wpq_test_type === 'PLATE') {
|
||||
return $.Deferred().resolve(true).promise();
|
||||
}
|
||||
|
||||
const d = $.Deferred();
|
||||
|
||||
console.log(e.data);
|
||||
let materials = '';
|
||||
if (e.data.material_group_1 || e.data.material_group_2) {
|
||||
materials = '&materials=';
|
||||
if (e.data.material_group_1) {
|
||||
materials += e.data.material_group_1;
|
||||
}
|
||||
if (e.data.material_group_2) {
|
||||
materials += (materials.endsWith('=') ? '' : ',') + e.data.material_group_2;
|
||||
}
|
||||
}
|
||||
|
||||
$.getJSON("{{autocomplete_type('naks_welder_diameter_max')}}?value=" + encodeURIComponent(e.data.naks_no) + materials, function(responseJSON) {
|
||||
if (typeof responseJSON.error === "string") {
|
||||
// If responseJSON.error exists, write the message to e.rule.message
|
||||
e.rule.message = responseJSON.error;
|
||||
// Swal.fire(responseJSON.error, '', 'error');
|
||||
} else {
|
||||
var start_max = responseJSON.start_max;
|
||||
console.log("naks_welder_diameter_max");
|
||||
console.log(e.value);
|
||||
var result =
|
||||
(start_max === null || start_max === "") // Eğer start_max null veya boş ise
|
||||
? (e.value === null || e.value === "" || (!isNaN(e.value) && e.value > 0)) // Boş veya 0'dan büyük değerler kabul edilir
|
||||
: (e.value !== null && e.value !== "" && !isNaN(e.value) && e.value <= start_max); // Aksi halde, start_max'a küçük eşit olmalı
|
||||
|
||||
console.log(result);
|
||||
|
||||
if (!result) {
|
||||
var message = "Value must be less than or equal to " + start_max;
|
||||
if (e.validator) {
|
||||
var $element = e.validator.element();
|
||||
$element.addClass('bg-warning');
|
||||
//$element.attr('data-toggle', 'popover');
|
||||
$element.attr('data-placement', 'bottom');
|
||||
$element.attr('title', message);
|
||||
$element.attr('data-original-title', message);
|
||||
$element.popover();
|
||||
$element.popover('show');
|
||||
setTimeout(function() {
|
||||
$(".popover").remove();
|
||||
}, 3000);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Skip validation for PLATE type - diameter is not applicable
|
||||
if (e.data.wpq_test_type === 'PLATE') {
|
||||
return $.Deferred().resolve(true).promise();
|
||||
}
|
||||
|
||||
const d = $.Deferred();
|
||||
|
||||
console.log(e.data);
|
||||
let materials = '';
|
||||
if (e.data.material_group_1 || e.data.material_group_2) {
|
||||
materials = '&materials=';
|
||||
if (e.data.material_group_1) {
|
||||
materials += e.data.material_group_1;
|
||||
}
|
||||
if (e.data.material_group_2) {
|
||||
materials += (materials.endsWith('=') ? '' : ',') + e.data.material_group_2;
|
||||
}
|
||||
}
|
||||
|
||||
$.getJSON("{{autocomplete_type('naks_welder_diameter_min')}}?value=" + encodeURIComponent(e.data.naks_no) + materials, function(responseJSON) {
|
||||
let result = true;
|
||||
|
||||
if (typeof responseJSON.error === "string") {
|
||||
// If responseJSON.error exists, write the message to e.rule.message
|
||||
e.rule.message = responseJSON.error;
|
||||
result = false;
|
||||
// Swal.fire(responseJSON.error, '', 'error');
|
||||
} else {
|
||||
var start_min = responseJSON.start_min;
|
||||
result = (e.value >= start_min);
|
||||
if (!result) {
|
||||
var message = "Value must be greater than or equal to " + start_min;
|
||||
if (e.validator) {
|
||||
var $element = e.validator.element();
|
||||
$element.addClass('bg-warning');
|
||||
//$element.attr('data-toggle', 'popover');
|
||||
$element.attr('data-placement', 'bottom');
|
||||
$element.attr('title', message);
|
||||
$element.attr('data-original-title', message);
|
||||
$element.popover();
|
||||
$element.popover('show');
|
||||
setTimeout(function() {
|
||||
$(".popover").remove();
|
||||
}, 3000);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// Skip validation for PLATE type - diameter is not applicable
|
||||
if (e.data.wpq_test_type === 'PLATE') {
|
||||
return $.Deferred().resolve(true).promise();
|
||||
}
|
||||
|
||||
const d = $.Deferred();
|
||||
|
||||
console.log(e.data);
|
||||
let materials = '';
|
||||
if (e.data.material_group_1 || e.data.material_group_2) {
|
||||
materials = '&materials=';
|
||||
if (e.data.material_group_1) {
|
||||
materials += e.data.material_group_1;
|
||||
}
|
||||
if (e.data.material_group_2) {
|
||||
materials += (materials.endsWith('=') ? '' : ',') + e.data.material_group_2;
|
||||
}
|
||||
}
|
||||
|
||||
$.getJSON("{{row_detail_url("w_p_s","details")}}?value=" + encodeURIComponent(e.data.wps_no), function(responseJSON) {
|
||||
|
||||
|
||||
if (typeof responseJSON.error === "string") {
|
||||
// Eğer responseJSON.error varsa, mesajı e.rule.message'e yaz
|
||||
e.rule.message = responseJSON.error;
|
||||
// Swal.fire(responseJSON.error, '', 'error');
|
||||
} else {
|
||||
var max_outside_diameter = responseJSON.max_outside_diameter;
|
||||
var min_outside_diameter = responseJSON.min_outside_diameter;
|
||||
|
||||
if (max_outside_diameter == null) {
|
||||
max_outside_diameter = min_outside_diameter + 10000;
|
||||
e.rule.message = "Value starts at " + min_outside_diameter;
|
||||
} else {
|
||||
e.rule.message = "Value between " + min_outside_diameter + " - " + max_outside_diameter;
|
||||
}
|
||||
|
||||
var result = (e.value >= min_outside_diameter && e.value <= max_outside_diameter);
|
||||
}
|
||||
|
||||
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.get("?ajax=kss-number-diff&id="+e.data.id+"&value=" + e.value, function(response) {
|
||||
response = response.trim();
|
||||
var result;
|
||||
console.log(response);
|
||||
if(response == 1) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
e.rule.message = "This trick has been used before. Please use a different number";
|
||||
}
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
return true;
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
let materials = '';
|
||||
if (e.data.material_group_1 || e.data.material_group_2) {
|
||||
materials = '&materials=';
|
||||
if (e.data.material_group_1) {
|
||||
materials += e.data.material_group_1;
|
||||
}
|
||||
if (e.data.material_group_2) {
|
||||
materials += (materials.endsWith('=') ? '' : ',') + e.data.material_group_2;
|
||||
}
|
||||
}
|
||||
|
||||
$.getJSON("{{row_detail_url("w_p_s","details")}}?value=" + encodeURIComponent(e.data.wps_no), function(responseJSON) {
|
||||
if (typeof responseJSON.error === "string") {
|
||||
// Eğer responseJSON.error varsa, mesajı e.rule.message'e yaz
|
||||
e.rule.message = responseJSON.error;
|
||||
// Swal.fire(responseJSON.error, '', 'error');
|
||||
}
|
||||
|
||||
var max_thick = responseJSON.max_thick;
|
||||
var min_thick = responseJSON.min_thick;
|
||||
|
||||
if (max_thick == null) {
|
||||
max_thick = min_thick + 10000;
|
||||
e.rule.message = "Value starts at " + min_thick;
|
||||
} else {
|
||||
e.rule.message = "Value between " + min_thick + " - " + max_thick;
|
||||
}
|
||||
|
||||
var result = (e.value >= min_thick && e.value <= max_thick);
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
console.log(e.data);
|
||||
let materials = '';
|
||||
if (e.data.material_group_1 || e.data.material_group_2) {
|
||||
materials = '&materials=';
|
||||
if (e.data.material_group_1) {
|
||||
materials += e.data.material_group_1;
|
||||
}
|
||||
if (e.data.material_group_2) {
|
||||
materials += (materials.endsWith('=') ? '' : ',') + e.data.material_group_2;
|
||||
}
|
||||
}
|
||||
|
||||
$.getJSON("{{autocomplete_type('naks_welder_thk_max')}}?value=" + encodeURIComponent(e.data.naks_no) + materials, function(responseJSON) {
|
||||
if (typeof responseJSON.error === "string") {
|
||||
// If responseJSON.error exists, write the message to e.rule.message
|
||||
e.rule.message = responseJSON.error;
|
||||
// Swal.fire(responseJSON.error, '', 'error');
|
||||
} else {
|
||||
var start_max = responseJSON.start_max;
|
||||
|
||||
var result =
|
||||
(start_max === null || start_max === "") // Eğer start_max null veya boş ise
|
||||
? (e.value === null || e.value === "" || (!isNaN(e.value) && e.value > 0)) // Boş veya 0'dan büyük değerler kabul edilir
|
||||
: (e.value !== null && e.value !== "" && !isNaN(e.value) && e.value <= start_max); // Aksi halde, start_max'a küçük eşit olmalı
|
||||
|
||||
|
||||
if (!result) {
|
||||
var message = "Value must be less than or equal to " + start_max;
|
||||
if (e.validator) {
|
||||
var $element = e.validator.element();
|
||||
$element.addClass('bg-warning');
|
||||
//$element.attr('data-toggle', 'popover');
|
||||
$element.attr('data-placement', 'bottom');
|
||||
$element.attr('title', message);
|
||||
$element.attr('data-original-title', message);
|
||||
$element.popover();
|
||||
$element.popover('show');
|
||||
setTimeout(function() {
|
||||
$(".popover").remove();
|
||||
}, 3000);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
console.log(e.data);
|
||||
let materials = '';
|
||||
if (e.data.material_group_1 || e.data.material_group_2) {
|
||||
materials = '&materials=';
|
||||
if (e.data.material_group_1) {
|
||||
materials += e.data.material_group_1;
|
||||
}
|
||||
if (e.data.material_group_2) {
|
||||
materials += (materials.endsWith('=') ? '' : ',') + e.data.material_group_2;
|
||||
}
|
||||
}
|
||||
|
||||
$.getJSON("{{autocomplete_type('naks_welder_thk_min')}}?value=" + encodeURIComponent(e.data.naks_no) + materials, function(responseJSON) {
|
||||
if (typeof responseJSON.error === "string") {
|
||||
// If responseJSON.error exists, write the message to e.rule.message
|
||||
e.rule.message = responseJSON.error;
|
||||
// Swal.fire(responseJSON.error, '', 'error');
|
||||
} else {
|
||||
var start_min = responseJSON.start_min;
|
||||
|
||||
var result = (e.value >= start_min);
|
||||
|
||||
if (!result) {
|
||||
var message = "Value must be greater than or equal to " + start_min;
|
||||
if (e.validator) {
|
||||
var $element = e.validator.element();
|
||||
$element.addClass('bg-warning');
|
||||
//$element.attr('data-toggle', 'popover');
|
||||
$element.attr('data-placement', 'bottom');
|
||||
$element.attr('title', message);
|
||||
$element.attr('data-original-title', message);
|
||||
$element.popover();
|
||||
$element.popover('show');
|
||||
setTimeout(function() {
|
||||
$(".popover").remove();
|
||||
}, 3000);
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
|
||||
return d.promise();
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
var max = e.data.naks_validity;
|
||||
var selectedDate = e.value;
|
||||
|
||||
var formattedDate = moment(max).format("DD/MM/YYYY");
|
||||
e.rule.message = "Date max " + formattedDate;
|
||||
console.log(max);
|
||||
console.log(selectedDate);
|
||||
console.log(moment(selectedDate).isSameOrBefore(max, 'day'));
|
||||
if(moment(selectedDate).isSameOrBefore(max, 'day')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
var min = e.data.date;
|
||||
var selectedDate = e.value;
|
||||
|
||||
if(selectedDate == null) {
|
||||
return true;
|
||||
} else {
|
||||
e.rule.message = "Date Start from " + e.data.date ;
|
||||
|
||||
if(moment(min).isSameOrBefore(selectedDate, 'day')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.getJSON("{{autocomplete_type("wps_date")}}?row=" + encodeURIComponent(JSON.stringify(e.data)), function(dateJSON) {
|
||||
var min = dateJSON.start;
|
||||
var result;
|
||||
|
||||
if(typeof e.value == "undefined") {
|
||||
result = true;
|
||||
} else {
|
||||
var minRawDate = min;
|
||||
var min = Date.parse(minRawDate).valueOf();
|
||||
var selectedDate = Date.parse(e.value).valueOf();
|
||||
|
||||
e.rule.message = "Date Start from " + minRawDate;
|
||||
|
||||
if(moment(minRawDate).isSameOrBefore(e.value, 'day')) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
d.resolve(result);
|
||||
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.getJSON("{{autocomplete_type("pqr_detail")}}?row=" + encodeURIComponent(JSON.stringify(e.data)), function(responseJSON) {
|
||||
var max_outside_diameter = responseJSON.qualitication_outside_diameter_max;
|
||||
e.rule.message = "must be lower than " + max_outside_diameter ;
|
||||
var result;
|
||||
|
||||
if(e.value<max_outside_diameter) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.getJSON("{{autocomplete_type("pqr_detail")}}?row=" + encodeURIComponent(JSON.stringify(e.data)), function(responseJSON) {
|
||||
var thickness_max = responseJSON.thickness_max;
|
||||
e.rule.message = "must be lower than " + thickness_max ;
|
||||
var result;
|
||||
|
||||
if(e.value<thickness_max) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.getJSON("{{autocomplete_type("pqr_detail")}}?row=" + encodeURIComponent(JSON.stringify(e.data)), function(responseJSON) {
|
||||
var min_outside_diameter = responseJSON.qualitication_outside_diameter_min;
|
||||
e.rule.message = "must be greater than " + min_outside_diameter ;
|
||||
var result;
|
||||
|
||||
if(e.value>min_outside_diameter) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
const d = $.Deferred();
|
||||
|
||||
$.getJSON("{{autocomplete_type("pqr_detail")}}?row=" + encodeURIComponent(JSON.stringify(e.data)), function(responseJSON) {
|
||||
var thickness_min = responseJSON.thickness_min;
|
||||
e.rule.message = "must be greater than " + thickness_min ;
|
||||
var result;
|
||||
|
||||
if(e.value>thickness_min) {
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
d.resolve(result);
|
||||
});
|
||||
|
||||
return d.promise();
|
||||
Reference in New Issue
Block a user