483 lines
31 KiB
PHP
483 lines
31 KiB
PHP
@extends($layout)
|
|
|
|
@section('content')
|
|
|
|
@php
|
|
$tickets = $tickets ?? [];
|
|
$todoTypeIcons = $ticketTypeIcons;
|
|
$allTicketGroups = $allTickets;
|
|
$reopenState = session()->get('quickadd_reopen', null);
|
|
$currentGroupBy = $searchCriteria['groupBy'] ?? 'all';
|
|
// Program (cross-project) board: columns are semantic status types and tickets are placed
|
|
// by their computed statusType (resolved from each project) instead of the raw status key.
|
|
$programBoard = $programBoard ?? false;
|
|
$placementField = $programBoard ? 'statusType' : 'status';
|
|
@endphp
|
|
|
|
{!! $tpl->displayNotification() !!}
|
|
|
|
<script>
|
|
leantime.kanbanGroupBy = '{{ $tpl->escape($currentGroupBy) }}';
|
|
</script>
|
|
|
|
@include('tickets::submodules.ticketHeader')
|
|
|
|
<div class="maincontent">
|
|
|
|
@include('tickets::submodules.ticketBoardTabs')
|
|
|
|
<div class="maincontentinner kanban-board-wrapper" >
|
|
|
|
{{-- Board actions (New / Filter / Group By) moved into the nav bar
|
|
(ticketBoardTabs) so there's no separate toolbar row here. --}}
|
|
<div class="clearfix"></div>
|
|
|
|
@if ($programBoard)
|
|
<p class="tw-text-[var(--secondary-font-color)]" style="margin-bottom:15px;">
|
|
<i class="fa fa-circle-info" aria-hidden="true"></i>
|
|
{{ __('text.program_status_rollup') }}
|
|
</p>
|
|
@endif
|
|
|
|
@if (isset($allTicketGroups['all']))
|
|
@php $allTickets = $allTicketGroups['all']['items']; @endphp
|
|
@endif
|
|
|
|
@php
|
|
$isGroupByActive = ! empty($searchCriteria['groupBy']) && $searchCriteria['groupBy'] !== 'all';
|
|
$columnHeaderClass = $isGroupByActive ? 'groupby-active' : '';
|
|
@endphp
|
|
<div class="kanban-column-headers {{ $columnHeaderClass }}" style="
|
|
display: flex;
|
|
position: sticky;
|
|
top: 110px;
|
|
justify-content: flex-start;
|
|
z-index: 9;
|
|
">
|
|
@foreach ($allKanbanColumns as $key => $statusRow)
|
|
<div class="column">
|
|
<h4 class="widgettitle title-primary title-border-{{ $statusRow['class'] }}">
|
|
@if ($login::userIsAtLeast($roles::$manager) && ! $programBoard)
|
|
<div class="inlineDropDownContainer" style="float:right;">
|
|
<a href="javascript:void(0);" class="dropdown-toggle ticketDropDown editHeadline" data-toggle="dropdown">
|
|
<i class="fa fa-ellipsis-v" aria-hidden="true"></i>
|
|
</a>
|
|
<ul class="dropdown-menu">
|
|
<li><a href="#/setting/editBoxLabel?module=ticketlabels&label={{ $key }}" class="editLabelModal">{!! __('headlines.edit_label') !!}</a>
|
|
</li>
|
|
<li><a href="{{ BASE_URL }}/projects/showProject/{{ session('currentProject') }}#todosettings">{!! __('links.add_remove_col') !!}</a></li>
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
<strong class="count">0</strong>
|
|
{{ $statusRow['name'] }}
|
|
</h4>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
|
|
@foreach ($allTicketGroups as $group)
|
|
@php $allTickets = $group['items']; @endphp
|
|
|
|
@if ($group['label'] != 'all')
|
|
@php
|
|
$swimlaneExpanded = ! in_array($group['id'], session('collapsedSwimlanes', []));
|
|
$groupBy = $searchCriteria['groupBy'] ?? 'status';
|
|
$groupId = $group['id'];
|
|
$groupIdKey = (string) $groupId;
|
|
$swimlaneBreakdown = $statusBreakdown[$groupIdKey] ?? $statusBreakdown[$groupId] ?? [];
|
|
$statusCounts = $swimlaneBreakdown['statusCounts'] ?? [];
|
|
$timeAlert = $swimlaneBreakdown['timeAlert'] ?? null;
|
|
@endphp
|
|
<div class="kanban-swimlane-row" data-expanded="{{ $swimlaneExpanded ? 'true' : 'false' }}" id="swimlane-row-{{ $group['id'] }}">
|
|
<div class="kanban-swimlane-sentinel" data-swimlane-id="{{ $group['id'] }}" aria-hidden="true"></div>
|
|
|
|
{{-- Render the component directly. It was previously invoked via
|
|
app('blade.compiler')::render('<x-...>', $data), but a <x-component> string
|
|
passed to Blade::render from inside an already-compiled view gets its bare
|
|
variables ($label, $groupId, …) pre-compiled by the outer pass and they are
|
|
not in the inner render scope — throwing "Undefined variable" for ANY
|
|
kanban group-by. A plain component tag with inline expressions is correct. --}}
|
|
<x-global::kanban.swimlane-row-header
|
|
:groupBy="$groupBy"
|
|
:groupId="$group['id']"
|
|
:label="$group['label']"
|
|
:totalCount="$swimlaneBreakdown['totalCount'] ?? count($group['items'])"
|
|
:statusCounts="$statusCounts"
|
|
:statusColumns="$allKanbanColumns"
|
|
:expanded="$swimlaneExpanded"
|
|
:moreInfo="$group['more-info'] ?? null"
|
|
:timeAlert="$group['timeAlert'] ?? null"
|
|
/>
|
|
|
|
<div class="kanban-swimlane-content{{ !$swimlaneExpanded ? ' collapsed' : '' }}" id="swimlane-content-{{ $group['id'] }}">
|
|
@endif
|
|
|
|
<div class="sortableTicketList kanbanBoard" id="kanboard-{{ $group['id'] }}" style="margin-top:-5px;">
|
|
|
|
<div class="row-fluid">
|
|
|
|
@php
|
|
$emptyColumns = [];
|
|
foreach ($allKanbanColumns as $key => $statusRow) {
|
|
$hasTickets = false;
|
|
if (isset($allTickets)) {
|
|
foreach ($allTickets as $ticket) {
|
|
if (isset($ticket[$placementField]) && $ticket[$placementField] == $key) {
|
|
$hasTickets = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (! $hasTickets) {
|
|
$emptyColumns[$key] = true;
|
|
}
|
|
}
|
|
@endphp
|
|
|
|
@foreach ($allKanbanColumns as $key => $statusRow)
|
|
<div class="column">
|
|
<div class="contentInner status_{{ $key }} {{ isset($emptyColumns[$key]) ? 'empty-column' : '' }}"
|
|
data-empty-text="{{ isset($emptyColumns[$key]) ? 'Empty' : '' }}"
|
|
aria-label="{{ isset($emptyColumns[$key]) ? 'Empty column' : htmlspecialchars($statusRow['name']).' column items' }}"
|
|
role="list">
|
|
|
|
@include('tickets::partials.quickadd-form', [
|
|
'statusId' => $key,
|
|
'swimlaneKey' => $group['value'] ?? $group['id'] ?? null,
|
|
'isEmpty' => isset($emptyColumns[$key]),
|
|
'currentGroupBy' => $searchCriteria['groupBy'] ?? null,
|
|
'programBoard' => $programBoard,
|
|
'availableProjects' => $availableProjects ?? null,
|
|
])
|
|
|
|
@foreach ($allTickets as $row)
|
|
@if (($row[$placementField] ?? null) == $key)
|
|
<div class="ticketBox moveable container priority-border-{{ $row['priority'] }}" id="ticket_{{ $row['id'] }}">
|
|
|
|
<div class="row" >
|
|
<div class="col-md-12">
|
|
|
|
@include('tickets::partials.ticketsubmenu', ['ticket' => $row, 'onTheClock' => $onTheClock])
|
|
|
|
@if ($row['dependingTicketId'] > 0)
|
|
<small><a href="#/tickets/showTicket/{{ $row['dependingTicketId'] }}" class="form-modal">{{ $row['parentHeadline'] }}</a></small> //
|
|
@endif
|
|
<small><i class="fa {{ $todoTypeIcons[strtolower($row['type'])] }}"></i> {!! __('label.'.strtolower($row['type'])) !!}</small>
|
|
<small>#{{ $row['id'] }}</small>
|
|
<div class="kanbanCardContent">
|
|
<h4><a href="#/tickets/showTicket/{{ $row['id'] }}" data-hx-get="{{ BASE_URL }}/tickets/showTicket/{{ $row['id'] }}" hx-swap="none" preload="mouseover">{{ $row['headline'] }}</a></h4>
|
|
|
|
<div class="kanbanContent" style="margin-bottom: 20px">
|
|
{!! $tpl->escapeMinimal($row['description']) !!}
|
|
</div>
|
|
|
|
</div>
|
|
<div class="tw-flex">
|
|
@if ($row['dateToFinish'] != '0000-00-00 00:00:00' && $row['dateToFinish'] != '1969-12-31 00:00:00')
|
|
<div>
|
|
{!! __('label.due_icon') !!}
|
|
<input type="text" title="{{ __('label.due') }}" value="{{ format($row['dateToFinish'])->date() }}" class="duedates secretInput" style="margin-left:0px;" data-id="{{ $row['id'] }}" name="date" />
|
|
</div>
|
|
<div>
|
|
@dispatchEvent('afterDates', ['ticket' => $row])
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="clearfix" style="padding-bottom: 8px;"></div>
|
|
|
|
<div class="timerContainer " id="timerContainer-{{ $row['id'] }}" >
|
|
|
|
<div class="dropdown ticketDropdown milestoneDropdown colorized show firstDropdown" >
|
|
<a style="background-color:{{ $tpl->escape($row['milestoneColor']) }}" class="dropdown-toggle f-left label-default milestone" href="javascript:void(0);" role="button" id="milestoneDropdownMenuLink{{ $row['id'] }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="text">@if ($row['milestoneid'] != '' && $row['milestoneid'] != 0){{ $row['milestoneHeadline'] }}@else{!! __('label.no_milestone') !!}@endif</span>
|
|
<i class="fa fa-caret-down" aria-hidden="true"></i>
|
|
</a>
|
|
<ul class="dropdown-menu" aria-labelledby="milestoneDropdownMenuLink{{ $row['id'] }}">
|
|
<li class="nav-header border">{!! __('dropdown.choose_milestone') !!}</li>
|
|
<li class='dropdown-item'><a style='background-color:#b0b0b0' href='javascript:void(0);' data-label="{!! __('label.no_milestone') !!}" data-value='{{ $row['id'].'_0_#b0b0b0' }}'> {!! __('label.no_milestone') !!} </a></li>
|
|
|
|
@php
|
|
foreach ($milestones as $milestone) {
|
|
echo "<li class='dropdown-item'>
|
|
<a href='javascript:void(0);' data-label='".$tpl->escape($milestone->headline)."' data-value='".$row['id'].'_'.$milestone->id.'_'.$tpl->escape($milestone->tags)."' id='ticketMilestoneChange".$row['id'].$milestone->id."' style='background-color:".$tpl->escape($milestone->tags)."'>".$tpl->escape($milestone->headline).'</a>';
|
|
echo '</li>';
|
|
}
|
|
@endphp
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
@if ($row['storypoints'] != '' && $row['storypoints'] > 0)
|
|
<div class="dropdown ticketDropdown effortDropdown show">
|
|
<a class="dropdown-toggle f-left label-default effort" href="javascript:void(0);" role="button" id="effortDropdownMenuLink{{ $row['id'] }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="text">{{ $efforts[''.$row['storypoints']] ?? $row['storypoints'] }}</span>
|
|
<i class="fa fa-caret-down" aria-hidden="true"></i>
|
|
</a>
|
|
<ul class="dropdown-menu" aria-labelledby="effortDropdownMenuLink{{ $row['id'] }}">
|
|
<li class="nav-header border">{!! __('dropdown.how_big_todo') !!}</li>
|
|
@php
|
|
foreach ($efforts as $effortKey => $effortValue) {
|
|
echo "<li class='dropdown-item'>
|
|
<a href='javascript:void(0);' data-value='".$row['id'].'_'.$effortKey."' id='ticketEffortChange".$row['id'].$effortKey."'>".$effortValue.'</a>';
|
|
echo '</li>';
|
|
}
|
|
@endphp
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
|
|
<div class="dropdown ticketDropdown priorityDropdown show">
|
|
<a class="dropdown-toggle f-left label-default priority priority-bg-{{ $row['priority'] }}" href="javascript:void(0);" role="button" id="priorityDropdownMenuLink{{ $row['id'] }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="text">@php if ($row['priority'] != '' && $row['priority'] > 0) { echo $priorities[$row['priority']] ?? __('label.priority_unkown'); } else { echo __('label.priority_unkown'); } @endphp</span>
|
|
<i class="fa fa-caret-down" aria-hidden="true"></i>
|
|
</a>
|
|
<ul class="dropdown-menu" aria-labelledby="priorityDropdownMenuLink{{ $row['id'] }}">
|
|
<li class="nav-header border">{!! __('dropdown.select_priority') !!}</li>
|
|
@php
|
|
foreach ($priorities as $priorityKey => $priorityValue) {
|
|
echo "<li class='dropdown-item'>
|
|
<a href='javascript:void(0);' class='priority-bg-".$priorityKey."' data-value='".$row['id'].'_'.$priorityKey."' id='ticketPriorityChange".$row['id'].$priorityKey."'>".$priorityValue.'</a>';
|
|
echo '</li>';
|
|
}
|
|
@endphp
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
<div class="dropdown ticketDropdown userDropdown noBg show right lastDropdown dropRight">
|
|
<a class="dropdown-toggle f-left" href="javascript:void(0);" role="button" id="userDropdownMenuLink{{ $row['id'] }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="text" style="display:inline-flex; align-items:center;">
|
|
@php
|
|
if ($row['editorFirstname'] != '') {
|
|
echo "<span id='userImage".$row['id']."'><img src='".BASE_URL.'/api/users?profileImage='.$row['editorId']."' width='25' style='vertical-align: middle;'/></span>";
|
|
} else {
|
|
echo "<span id='userImage".$row['id']."'><img src='".BASE_URL."/api/users?profileImage=false' width='25' style='vertical-align: middle;'/></span>";
|
|
}
|
|
|
|
if (! empty($row['collaboratorPreview'])) {
|
|
echo "<span class='ticket-collaborators' style='display:inline-flex; align-items:center; margin-left:6px;'>";
|
|
foreach ($row['collaboratorPreview'] as $index => $collaboratorId) {
|
|
$offset = $index > 0 ? 'margin-left:-8px;' : '';
|
|
echo "<span class='ticket-collaborator-avatar' title='".__('label.collaborators')."' style='display:inline-flex; width:18px; height:18px; border-radius:999px; border:2px solid var(--main-background-color, #fff); overflow:hidden; ".$offset."'><img src='".BASE_URL.'/api/users?profileImage='.$collaboratorId."' width='18' height='18' style='display:block; width:18px; height:18px;'/></span>";
|
|
}
|
|
if (($row['collaboratorOverflow'] ?? 0) > 0) {
|
|
echo "<span class='ticket-collaborator-more' title='".__('label.collaborators')."' style='display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px; padding:0 4px; margin-left:4px; border-radius:999px; background:var(--accent-color, #e9ecef); color:var(--secondary-font-color, #333); font-size:10px; line-height:18px;'>+".(int) $row['collaboratorOverflow'].'</span>';
|
|
}
|
|
echo '</span>';
|
|
}
|
|
@endphp
|
|
</span>
|
|
</a>
|
|
<ul class="dropdown-menu" aria-labelledby="userDropdownMenuLink{{ $row['id'] }}">
|
|
<li class="nav-header border">{!! __('dropdown.choose_user') !!}</li>
|
|
@php
|
|
if (is_array($users)) {
|
|
foreach ($users as $user) {
|
|
echo "<li class='dropdown-item'>
|
|
<a href='javascript:void(0);' data-label='".sprintf(__('text.full_name'), $tpl->escape($user['firstname']), $tpl->escape($user['lastname']))."' data-value='".$row['id'].'_'.$user['id'].'_'.$user['profileId']."' id='userStatusChange".$row['id'].$user['id']."' ><img src='".BASE_URL.'/api/users?profileImage='.$user['id']."' width='25' style='vertical-align: middle; margin-right:5px;'/>".sprintf(__('text.full_name'), $tpl->escape($user['firstname']), $tpl->escape($user['lastname'])).'</a>';
|
|
echo '</li>';
|
|
}
|
|
}
|
|
@endphp
|
|
</ul>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="clearfix"></div>
|
|
|
|
@if ($programBoard)
|
|
{{-- Cross-project board: columns are semantic stages, so give each card a
|
|
dropdown of its OWN project's real statuses (e.g. "Blocked") to set the
|
|
detailed status directly. patchTicket writes a key valid in that project,
|
|
so it stays orphan-safe. Also show which project the task belongs to. --}}
|
|
@php $rowProjectStatuses = $statusLabelsByProject[$row['projectId']] ?? []; @endphp
|
|
@php $rowProjectStatus = $rowProjectStatuses[$row['status']] ?? null; @endphp
|
|
<div style="margin-top:4px;">
|
|
<div class="dropdown ticketDropdown statusDropdown colorized show" style="display:inline-block;">
|
|
<a class="dropdown-toggle status {{ $rowProjectStatus['class'] ?? 'label-default' }} f-left" href="javascript:void(0);" role="button" id="statusDropdownMenuLink{{ $row['id'] }}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="text">{{ $tpl->escape($rowProjectStatus['name'] ?? __('label.new')) }}</span> <i class="fa fa-caret-down" aria-hidden="true"></i>
|
|
</a>
|
|
<ul class="dropdown-menu" aria-labelledby="statusDropdownMenuLink{{ $row['id'] }}">
|
|
<li class="nav-header border">{!! __('dropdown.choose_status') !!}</li>
|
|
@php
|
|
foreach ($rowProjectStatuses as $statusKey => $statusOption) {
|
|
echo "<li class='dropdown-item'><a href='javascript:void(0);' class='".$statusOption['class']."' data-label='".$tpl->escape($statusOption['name'])."' data-value='".$row['id'].'_'.$statusKey.'_'.$statusOption['class']."' id='ticketStatusChange".$row['id'].$statusKey."'>".$tpl->escape($statusOption['name']).'</a></li>';
|
|
}
|
|
@endphp
|
|
</ul>
|
|
</div>
|
|
<small class="tw-text-[var(--secondary-font-color)]">{{ $tpl->escape($row['projectName'] ?? '') }}</small>
|
|
</div>
|
|
@endif
|
|
|
|
@if ($row['commentCount'] > 0 || $row['subtaskCount'] > 0 || $row['tags'] != '')
|
|
<div class="row">
|
|
<div class="col-md-12 border-top" style="white-space: nowrap;">
|
|
@if ($row['commentCount'] > 0)
|
|
<a href="#/tickets/showTicket/{{ $row['id'] }}"><span class="fa-regular fa-comments"></span> {{ $row['commentCount'] }}</a>
|
|
@endif
|
|
|
|
@if ($row['subtaskCount'] > 0)
|
|
<a id="subtaskLink_{{ $row['id'] }}" href="#/tickets/showTicket/{{ $row['id'] }}" class="subtaskLineLink"> <span class="fa fa-diagram-successor"></span> {{ $row['subtaskCount'] }}</a>
|
|
@endif
|
|
@if ($row['tags'] != '')
|
|
@php $tagsArray = explode(',', $row['tags']); @endphp
|
|
<a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown">
|
|
<i class="fa fa-tags" aria-hidden="true"></i> {{ count($tagsArray) }}
|
|
</a>
|
|
<ul class="dropdown-menu ">
|
|
<li style="padding:10px"><div class='tagsinput readonly'>
|
|
@foreach ($tagsArray as $tag)
|
|
<span class='tag'><span>{{ $tag }}</span></span>
|
|
@endforeach
|
|
</div></li></ul>
|
|
@endif
|
|
|
|
</div>
|
|
|
|
</div>
|
|
@endif
|
|
|
|
</div>
|
|
@endif
|
|
@endforeach
|
|
</div>
|
|
|
|
</div>
|
|
@endforeach
|
|
<div class="clearfix"></div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
@if ($group['label'] != 'all')
|
|
</div> {{-- .kanban-swimlane-content --}}
|
|
</div> {{-- .kanban-swimlane-row --}}
|
|
@endif
|
|
|
|
@endforeach
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@once @push('scripts')
|
|
<script type="text/javascript">
|
|
|
|
jQuery(document).ready(function(){
|
|
|
|
@if (can('tickets.edit'))
|
|
leantime.ticketsController.initUserDropdown();
|
|
leantime.ticketsController.initMilestoneDropdown();
|
|
leantime.ticketsController.initDueDateTimePickers();
|
|
leantime.ticketsController.initEffortDropdown();
|
|
leantime.ticketsController.initPriorityDropdown();
|
|
|
|
@if ($programBoard)
|
|
{{-- Per-card status dropdown (program board only): set the exact project status. --}}
|
|
leantime.ticketsController.initStatusDropdown();
|
|
@endif
|
|
|
|
|
|
@if ($programBoard)
|
|
{{-- Program board: columns are status types; drag persists per-project via the plugin. --}}
|
|
var ticketStatusList = [@foreach ($allKanbanColumns as $key => $statusRow)'{{ $key }}',@endforeach];
|
|
if (leantime.pgmProBoard && typeof leantime.pgmProBoard.initProgramKanban === 'function') {
|
|
leantime.pgmProBoard.initProgramKanban(ticketStatusList);
|
|
} else {
|
|
console.warn('PgmPro board JS is not loaded; program kanban drag-and-drop is disabled.');
|
|
}
|
|
@else
|
|
var ticketStatusList = [@foreach ($allTicketStates as $key => $statusRow)'{{ $key }}',@endforeach];
|
|
leantime.ticketsController.initTicketKanban(ticketStatusList);
|
|
@endif
|
|
|
|
@else
|
|
leantime.authController.makeInputReadonly(".maincontentinner");
|
|
@endif
|
|
|
|
leantime.ticketsController.setUpKanbanColumns();
|
|
|
|
@if (isset($_GET['showTicketModal']))
|
|
@php
|
|
$modalUrl = $_GET['showTicketModal'] == '' ? '' : '/'.(int) $_GET['showTicketModal'];
|
|
@endphp
|
|
|
|
leantime.ticketsController.openTicketModalManually("{{ BASE_URL }}/tickets/showTicket{{ $modalUrl }}");
|
|
window.history.pushState({},document.title, '{{ BASE_URL }}/tickets/showKanban');
|
|
|
|
@endif
|
|
|
|
|
|
@php
|
|
foreach ($allTicketGroups as $group) {
|
|
foreach ($group['items'] as $ticket) {
|
|
if ($ticket['dependingTicketId'] > 0) {
|
|
@endphp
|
|
var startElement = document.getElementById('subtaskLink_{{ $ticket['dependingTicketId'] }}');
|
|
var endElement = document.getElementById('ticket_{{ $ticket['id'] }}');
|
|
|
|
|
|
if ( startElement != undefined && endElement != undefined) {
|
|
|
|
var startAnchor = LeaderLine.mouseHoverAnchor({
|
|
element: startElement,
|
|
showEffectName: 'draw',
|
|
style: {background: 'none', backgroundColor: 'none'},
|
|
hoverStyle: {background: 'none', backgroundColor: 'none', cursor: 'pointer'}
|
|
});
|
|
|
|
var line{{ $ticket['id'] }} = new LeaderLine(startAnchor, endElement, {
|
|
startPlugColor: 'var(--accent1)',
|
|
endPlugColor: 'var(--accent2)',
|
|
gradient: true,
|
|
size: 2,
|
|
path: "grid",
|
|
startSocket: 'bottom',
|
|
endSocket: 'auto'
|
|
});
|
|
|
|
jQuery("#ticket_{{ $ticket['id'] }}").mousedown(function () {
|
|
|
|
})
|
|
.mousemove(function () {
|
|
|
|
})
|
|
.mouseup(function () {
|
|
line{{ $ticket['id'] }}.position();
|
|
});
|
|
|
|
jQuery("#ticket_{{ $ticket['dependingTicketId'] }}").mousedown(function () {
|
|
|
|
})
|
|
.mousemove(function () {
|
|
|
|
|
|
})
|
|
.mouseup(function () {
|
|
line{{ $ticket['id'] }}.position();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
@php
|
|
}
|
|
}
|
|
}
|
|
@endphp
|
|
|
|
|
|
|
|
|
|
});
|
|
</script>
|
|
@endpush @endonce
|
|
|
|
@endsection
|