Skip to content

Commit

Permalink
Added swimlanes to the boards.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mantix committed Feb 26, 2024
1 parent 87d43dd commit b0b0254
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 37 deletions.
12 changes: 6 additions & 6 deletions resources/views/kanban-board.blade.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<div>
<div>
@includeIf($beforeStatusBoardView)
@includeIf($beforeKanbanBoardView)
</div>

<div class="{{ $styles['wrapper'] }}">
@foreach ($statuses as $status)
@include($statusView, [
'status' => $status,
<div class="{{ $styles['kanbanWrapper'] }}">
@foreach ($swimlanes as $swimlane)
@include($swimlaneView, [
'swimlane' => $swimlane,
])
@endforeach
</div>

<div>
@includeIf($afterStatusBoardView)
@includeIf($afterKanbanBoardView)
</div>

<div wire:ignore>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/status.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
'status' => $status,
])

<div id="{{ $status['statusRecordsId'] }}"
<div id="{{ $status['swimlaneStatusID'] }}"
data-status-group="{{ $status['group'] }}"
data-status-id="{{ $status['id'] }}"
class="status-container {{ $styles['statusRecords'] }}">
Expand Down
3 changes: 3 additions & 0 deletions resources/views/swimlane-footer.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{-- Injected variables $status, $styles --}}
<div class="{{ $styles['swimlaneFooter'] }}">
</div>
4 changes: 4 additions & 0 deletions resources/views/swimlane-header.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{-- Injected variables $status, $styles --}}
<div class="{{ $styles['swimlaneHeader'] }}">
{{ $swimlane['title'] }}
</div>
26 changes: 26 additions & 0 deletions resources/views/swimlane.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{-- Injected variables $swimlane, $styles --}}
<div class="{{ $styles['swimlaneWrapper'] }}">
<div class="{{ $styles['swimlane'] }}" id="{{ $swimlane['id'] }}">

@include($swimlaneHeaderView, [
'swimlane' => $swimlane,
])

<div id="swimlane-{{ $swimlane['id'] }}"
data-swimlane-id="{{ $swimlane['id'] }}"
class="swimlane-container {{ $styles['swimlaneRecords'] }}">

@foreach ($swimlane['statuses'] as $status)
@include($statusView, [
'status' => $status,
])
@endforeach

</div>

@include($swimlaneFooterView, [
'swimlane' => $swimlane,
])

</div>
</div>
83 changes: 53 additions & 30 deletions src/LivewireKanbanBoard.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,37 @@
* @package Mantix\LivewireKanbanBoard
* @property boolean $sortable
* @property boolean $sortableBetweenStatuses
* @property string $statusBoardView
* @property string $kanbanBoardView
* @property string $swimlaneView;
* @property string $swimlaneHeaderView;
* @property string $swimlaneFooterView;
* @property string $statusView
* @property string $statusHeaderView
* @property string $statusFooterView
* @property string $recordView
* @property string $recordContentView
* @property string $sortableView
* @property string $beforeStatusBoardView
* @property string $afterStatusBoardView
* @property string $beforeKanbanBoardView
* @property string $afterKanbanBoardView
* @property string $ghostClass
* @property boolean $recordClickEnabled
*/
class LivewireKanbanBoard extends Component {
public $sortable;
public $sortableBetweenStatuses;

public $statusBoardView;
public $kanbanBoardView;
public $swimlaneView;
public $swimlaneHeaderView;
public $swimlaneFooterView;
public $statusView;
public $statusHeaderView;
public $statusFooterView;
public $recordView;
public $recordContentView;
public $sortableView;
public $beforeStatusBoardView;
public $afterStatusBoardView;
public $beforeKanbanBoardView;
public $afterKanbanBoardView;

public $ghostClass;

Expand All @@ -43,31 +49,37 @@ class LivewireKanbanBoard extends Component {
public function mount(
$sortable = false,
$sortableBetweenStatuses = false,
$statusBoardView = null,
$kanbanBoardView = null,
$swimlaneView = null,
$swimlaneHeaderView = null,
$swimlaneFooterView = null,
$statusView = null,
$statusHeaderView = null,
$statusFooterView = null,
$recordView = null,
$recordContentView = null,
$sortableView = null,
$beforeStatusBoardView = null,
$afterStatusBoardView = null,
$beforeKanbanBoardView = null,
$afterKanbanBoardView = null,
$ghostClass = null,
$recordClickEnabled = false,
$extras = []
) {
$this->sortable = $sortable ?? false;
$this->sortableBetweenStatuses = $sortableBetweenStatuses ?? false;

$this->statusBoardView = $statusBoardView ?? 'livewire-kanban-board::kanban-board';
$this->kanbanBoardView = $kanbanBoardView ?? 'livewire-kanban-board::kanban-board';
$this->swimlaneView = $swimlaneView ?? 'livewire-kanban-board::swimlane';
$this->swimlaneHeaderView = $swimlaneHeaderView ?? 'livewire-kanban-board::swimlane-header';
$this->swimlaneFooterView = $swimlaneFooterView ?? 'livewire-kanban-board::swimlane-footer';
$this->statusView = $statusView ?? 'livewire-kanban-board::status';
$this->statusHeaderView = $statusHeaderView ?? 'livewire-kanban-board::status-header';
$this->statusFooterView = $statusFooterView ?? 'livewire-kanban-board::status-footer';
$this->recordView = $recordView ?? 'livewire-kanban-board::record';
$this->recordContentView = $recordContentView ?? 'livewire-kanban-board::record-content';
$this->sortableView = $sortableView ?? 'livewire-kanban-board::sortable';
$this->beforeStatusBoardView = $beforeStatusBoardView ?? null;
$this->afterStatusBoardView = $afterStatusBoardView ?? null;
$this->beforeKanbanBoardView = $beforeKanbanBoardView ?? null;
$this->afterKanbanBoardView = $afterKanbanBoardView ?? null;

$this->ghostClass = $ghostClass ?? 'bg-primary-subtle';

Expand All @@ -84,12 +96,16 @@ public function statuses(): Collection {
return collect();
}

public function swimlanes(): Collection {
return collect();
}

public function records(): Collection {
return collect();
}

public function isRecordInStatus($record, $status) {
return $record['status'] == $status['id'];
public function isRecordInStatusAndSwimlane($record, $status, $swimlane) {
return $record['status'] == $status['id'] && $record['swimlane'] == $swimlane['id'];
}

public function onStatusSorted($recordId, $statusId, $orderedIds) {
Expand All @@ -106,42 +122,49 @@ public function onRecordClick($recordId) {

public function styles() {
return [
'wrapper' => 'd-flex flex-nowrap overflow-x-auto rounded', // component wrapper
'kanbanWrapper' => '', // component wrapper
'swimlaneWrapper' => '', // swimlanes wrapper
'swimlane' => '', // swimlane column wrapper
'swimlaneHeader' => 'p-2 fs-4', // swimlane header
'swimlaneFooter' => '', // swimlane footer
'swimlaneRecords' => 'd-flex flex-nowrap overflow-x-auto rounded', // swimlane records wrapper
'statusWrapper' => 'flex-shrink-0', // statuses wrapper
'statusWidth' => 272, // statuses column width
'status' => 'flex-column rounded bg-primary fw-bold mx-1 px-2', // status column wrapper
'status' => 'flex-column rounded fw-bold mx-1 px-2', // status column wrapper
'statusHeader' => 'py-2 fs-5', // status header
'statusFooter' => '', // status footer
'statusRecords' => '', // status records wrapper
'record' => 'bg-white shadow rounded border fw-normal p-2 my-2', // record wrapper
'record' => 'shadow-sm rounded border fw-normal p-2 my-2', // record wrapper
'recordContent' => '', // record content
];
}

public function render() {
$swimlanes = $this->swimlanes();
$statuses = $this->statuses();

$records = $this->records();

$styles = $this->styles();

$statuses = $statuses
->map(function ($status) use ($records) {
$id = $this->id ?? 0;
$swimlanes = $swimlanes->map(function ($swimlane) use ($statuses, $records) {
$id = $this->id ?? 'kanban';
$swimlane['group'] = $id;
$swimlane['statuses'] = $statuses->map(function ($status) use ($id, $swimlane, $records) {
$status['group'] = $id;
$status['statusRecordsId'] = "{$id}-{$status['id']}";
$status['records'] = $records
->filter(function ($record) use ($status) {
return $this->isRecordInStatus($record, $status);
});

$status['swimlaneStatusID'] = $id . '-' . $swimlane['id'] . '-' . $status['id'];
$status['records'] = $records->filter(function ($record) use ($id, $swimlane, $status) {
$record['swimlaneStatusRecordID'] = $id . '-' . $swimlane['id'] . '-' . $status['id'] . '-' . $record['id'];
return $this->isRecordInStatusAndSwimlane($record, $status, $swimlane);
});
return $status;
});
return $swimlane;
});

return view($this->statusBoardView)
return view($this->kanbanBoardView)
->with([
'records' => $records,
'swimlanes' => $swimlanes,
'statuses' => $statuses,
'records' => $records,
'styles' => $styles,
]);
}
Expand Down

0 comments on commit b0b0254

Please sign in to comment.