ikinci temizlik tamamlandı

This commit is contained in:
Ümit Tunç
2026-04-28 21:15:09 +03:00
parent f80443aec0
commit 37e7296527
8313 changed files with 2400677 additions and 0 deletions
@@ -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];
});
}
}
@@ -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
@@ -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 } ?>
@@ -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 } ?>
},
@@ -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;
}
},
@@ -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>
@@ -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);
}
});
@@ -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>');
}
}
}
@@ -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 } ?>
@@ -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;
}
}
@@ -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")
},
},
@@ -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();
@@ -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();
@@ -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();
@@ -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();
@@ -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;
}
@@ -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;
}
@@ -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();
@@ -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;
}
@@ -0,0 +1,9 @@
if(e.data.welding_date != null) {
if(e.value == null) {
return false;
} else {
return true;
}
} else {
return true;
}
@@ -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();
@@ -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();
@@ -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;
}
}
@@ -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;
}
}
@@ -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();
@@ -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();
@@ -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();
@@ -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();
@@ -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();
@@ -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();
@@ -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();
@@ -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;
}
@@ -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();
@@ -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();
@@ -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();
@@ -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();
@@ -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();