Skip to content

Commit 9218e68

Browse files
Merge pull request #70 from ACT-Training/69-report-builder
69 report builder
2 parents d111841 + 56cae0d commit 9218e68

17 files changed

Lines changed: 489 additions & 286 deletions

composer.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
"spatie/laravel-package-tools": "^1.14.0"
2323
},
2424
"require-dev": {
25-
"laravel/pint": "^1.0",
26-
"nunomaduro/collision": "^7.8",
27-
"nunomaduro/larastan": "^2.0.1",
25+
"laravel/pint": "^v1.12.0",
26+
"nunomaduro/collision": "^v8.4.0",
27+
"nunomaduro/larastan": "^v2.9.8",
2828
"orchestra/testbench": "^9.0",
29-
"pestphp/pest": "^2.20",
30-
"pestphp/pest-plugin-arch": "^2.0",
31-
"pestphp/pest-plugin-laravel": "^2.0",
29+
"pestphp/pest": "^v3.2.2",
30+
"pestphp/pest-plugin-arch": "^v3.0.0",
31+
"pestphp/pest-plugin-laravel": "^v3.0.0",
3232
"phpstan/extension-installer": "^1.1",
3333
"phpstan/phpstan-deprecation-rules": "^1.0",
3434
"phpstan/phpstan-phpunit": "^1.0",

package-lock.json

Lines changed: 0 additions & 13 deletions
This file was deleted.

resources/views/components/search.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="flex items-center w-full sm:w-1/2 lg:w-1/3">
1+
<div class="flex items-center w-full">
22
<label for="simple-search" class="sr-only">Search</label>
33
<div class="relative w-full">
44
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">

resources/views/editor.blade.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<div class="mb-4">
2-
32
@if (! count($criteria))
43
<div class="flex justify-between items-center p-2 mb-4 text-sm font-medium leading-5 bg-white rounded-lg text-slate-400 shadow">
54
<span wire:click="addCriteria"
@@ -56,6 +55,17 @@ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:
5655
</div>
5756
@endif
5857

58+
@if($criterion['inputType'] === 'number')
59+
<div class="p-1 col-span-1">
60+
<label for="value-{{ $loop->index }}"
61+
class="sr-only block mb-2 text-sm font-medium text-gray-900 dark:text-white">Number</label>
62+
<input wire:model.live.debounce.1000ms="criteria.{{ $loop->index }}.value"
63+
type="number"
64+
id="value-{{ $loop->index }}"
65+
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
66+
</div>
67+
@endif
68+
5969
@if($criterion['inputType'] === 'date')
6070
@include('query-builder::components.date-input')
6171
@endif
@@ -98,4 +108,3 @@ class="pl-2 flex items-center gap-1 text-gray-500 group-hover:text-flamingo-500
98108
</div>
99109

100110

101-
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<div>
2+
3+
@includeIf($this->headerView())
4+
5+
@if($this->availableColumns())
6+
@include('query-builder::report-editor')
7+
@endif
8+
9+
@if($this->columns())
10+
11+
<div class="my-6">
12+
@if ($this->showQueryBuilder())
13+
<div class="m-4">
14+
@include('query-builder::editor')
15+
16+
@if(! $this->rows->count())
17+
<div class="p-4 mb-4 text-sm text-blue-800 rounded-lg bg-blue-50 dark:bg-gray-800 dark:text-blue-400"
18+
role="alert">
19+
<span class="font-bold">No records found have been found.</span> Try changing your query
20+
settings.
21+
</div>
22+
@endif
23+
</div>
24+
@endif
25+
26+
@if($this->isToolbarVisible())
27+
<div class="p-4 flex items-center gap-2 justify-between bg-gray-50">
28+
29+
<div class="p-4 flex items-center gap-2">
30+
@if($this->isSearchVisible())
31+
@include('query-builder::components.search')
32+
@endif
33+
</div>
34+
35+
<div class="p-4 flex items-center gap-2">
36+
37+
@if($this->areActionsVisible())
38+
@include('query-builder::components.actions')
39+
@endif
40+
41+
@if($this->isColumnSelectorVisible())
42+
@include('query-builder::components.columns-selector')
43+
@endif
44+
45+
@if($this->isRowSelectorVisible())
46+
@include('query-builder::components.rows-selector')
47+
@endif
48+
</div>
49+
</div>
50+
@endif
51+
52+
@if($this->rows->count())
53+
54+
<div id="{{ $this->identifier() }}" class="relative overflow-x-auto">
55+
<table class="w-full text-sm text-left text-gray-500">
56+
<thead class="text-xs text-gray-700 uppercase bg-gray-50">
57+
<tr class="border-y border-gray-200">
58+
59+
@if($selectable)
60+
<th class="p-0">
61+
<div class="pl-6 flex items-center">
62+
<input wire:model.live="selectPage" id="checkbox-select-page" type="checkbox"
63+
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
64+
<label for="checkbox-select-page"
65+
class="sr-only ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"></label>
66+
</div>
67+
</th>
68+
@endif
69+
70+
@foreach ($this->columns() as $column)
71+
@if(in_array($column->key, $displayColumns))
72+
<th @if ($column->isSortable()) wire:click="sort('{{ $column->key }}')" @endif>
73+
@if ($column->showHeader)
74+
<div @class([
75+
'flex items-center gap-1 bg-gray-50 px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 ' . $column->justify,
76+
'cursor-pointer' => $column->isSortable(),
77+
])>
78+
{{ $column->label }}
79+
80+
@if ($sortBy === $column->key)
81+
@if ($sortDirection === 'asc')
82+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5"
83+
viewBox="0 0 20 20"
84+
fill="currentColor">
85+
<path fill-rule="evenodd"
86+
d="M14.707 10.293a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 111.414-1.414L9 12.586V5a1 1 0 012 0v7.586l2.293-2.293a1 1 0 011.414 0z"
87+
clip-rule="evenodd"/>
88+
</svg>
89+
@else
90+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5"
91+
viewBox="0 0 20 20"
92+
fill="currentColor">
93+
<path fill-rule="evenodd"
94+
d="M5.293 9.707a1 1 0 010-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 01-1.414 1.414L11 7.414V15a1 1 0 11-2 0V7.414L6.707 9.707a1 1 0 01-1.414 0z"
95+
clip-rule="evenodd"/>
96+
</svg>
97+
@endif
98+
@endif
99+
100+
@if($this->isSearchableIconVisible() && $column->isSearchable())
101+
<x-tabler-search class="w-4 h-4 text-gray-300"/>
102+
@endif
103+
104+
</div>
105+
@endif
106+
</th>
107+
@endif
108+
@endforeach
109+
</tr>
110+
</thead>
111+
<tbody @if($this->useLoadingIndicator()) wire:loading.class="{{ $this->loadingClass }}" @endif>
112+
@if($selectable && $selectPage && $this->rows->count() < $this->rows->total())
113+
<tr class="bg-gray-100" wire:key="row-message">
114+
<td colspan="{{ count($displayColumns) + 1 }}" class="px-6 py-4">
115+
@unless($selectAll)
116+
<div>
117+
<span>You have selected <span
118+
class="font-bold">{{ count($selectedRows) }} {{ Str::of('row')->plural(count($selectedRows)) }}</span>. Do you want to select all {{ $this->rows->total() }}?</span>
119+
<button wire:click="selectAll"
120+
class="ml-2 text-blue-500 hover:text-blue-600">
121+
Select all
122+
</button>
123+
</div>
124+
@else
125+
<span>You have selected all {{ $this->rows->total() }} {{ Str::of('row')->plural(count($selectedRows)) }}.</span>
126+
@endif
127+
</td>
128+
</tr>
129+
@endif
130+
@foreach ($this->rows as $row)
131+
132+
@if($this->rowPreview($row))
133+
{!! $this->injectRow($row) !!}
134+
@endif
135+
136+
<tr @if($this->isClickable())
137+
{!! $this->renderRowClick($row->id) !!}
138+
@endif
139+
wire:key="row-{{ $row->id }}"
140+
@class([
141+
'bg-white border-b',
142+
'hover:bg-gray-50 cursor-pointer' => $this->isClickable(),
143+
])>
144+
145+
@if($selectable)
146+
<td class="p-0">
147+
<div class="pl-6 flex items-center">
148+
<input wire:model.live="selectedRows" id="checkbox-{{ $row->id }}"
149+
type="checkbox"
150+
value="{{ $row->id }}"
151+
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
152+
<label for="checkbox-{{ $row->id }}"
153+
class="sr-only ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"></label>
154+
</div>
155+
</td>
156+
@endif
157+
158+
@foreach ($this->columns() as $column)
159+
@if(in_array($column->key, $displayColumns))
160+
<td>
161+
<div class="py-3 px-6 flex items-center">
162+
<x-dynamic-component
163+
:component="$column->component"
164+
:value="$column->getValue($row)"
165+
:column="$column"
166+
:row="$row"
167+
>
168+
</x-dynamic-component>
169+
</div>
170+
</td>
171+
@endif
172+
@endforeach
173+
</tr>
174+
@endforeach
175+
</tbody>
176+
</table>
177+
</div>
178+
179+
@if($this->isPaginated() && $this->rows->hasPages())
180+
<div class="border-b border-gray-200 shadow-sm">
181+
@if($this->scroll() === true)
182+
<div class="py-2 px-6">{{ $this->rows->links() }}</div>
183+
@else
184+
<div class="py-2 px-6">{{ $this->rows->links(data: ['scrollTo' => $this->scroll()]) }}</div>
185+
@endif
186+
</div>
187+
@endif
188+
@endif
189+
190+
@if($this->useLoadingIndicator())
191+
{{-- Table loading spinners... --}}
192+
<div
193+
wire:loading
194+
class="absolute inset-0 bg-white {{ $this->loadingClass() }}"
195+
>
196+
{{-- --}}
197+
</div>
198+
199+
<div
200+
wire:loading.flex
201+
class="flex justify-center items-center absolute inset-0"
202+
>
203+
<svg class="animate-spin h-10 w-10 {{ $this->spinnerColor() }}" xmlns="http://www.w3.org/2000/svg"
204+
fill="none" viewBox="0 0 24 24">
205+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor"
206+
stroke-width="4"></circle>
207+
<path class="opacity-75" fill="currentColor"
208+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
209+
</svg>
210+
</div>
211+
@endif
212+
213+
214+
</div>
215+
216+
@includeIf($this->footerView())
217+
@endif
218+
</div>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<div x-data="{open: true }" x-cloak
2+
class="m-4 block p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700">
3+
4+
@if(!$selectedColumns)
5+
<div class="p-4 mb-4 text-sm text-blue-800 rounded-lg bg-blue-50 dark:bg-gray-800 dark:text-blue-400" role="alert">
6+
Please select one or more columns.
7+
</div>
8+
@endif
9+
10+
<div x-show="open">
11+
@foreach($this->availableColumns() as $section => $columns)
12+
<h6 class="mb-4 pb-1 text-base font-bold text-gray-600 dark:text-white border-b border-dashed">{{ $section }}</h6>
13+
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6">
14+
@foreach($columns as $columnKey => $column)
15+
<div class="flex items-center mb-4">
16+
<input wire:model.live.debounce="selectedColumns" id="{{$column['key']}}" type="checkbox"
17+
value="{{ $column['key'] }}"
18+
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
19+
<label for="{{$column['key']}}"
20+
class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">{{$column['label']}}</label>
21+
</div>
22+
@endforeach
23+
</div>
24+
@endforeach
25+
</div>
26+
27+
<div class="flex items-center gap-2 p-1 px-2 bg-gray-50 -mx-6 -mb-6 rounded-b-lg">
28+
<span class="text-sm text-gray-600">Columns</span>
29+
<button @click="open = !open">
30+
<span x-show="!open">
31+
<svg xmlns="http://www.w3.org/2000/svg"
32+
class="w-6 h-6"
33+
viewBox="0 0 24 24" stroke-width="1.5" stroke="#2c3e50" fill="none"
34+
stroke-linecap="round" stroke-linejoin="round">
35+
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
36+
<path d="M6 9l6 6l6 -6"/>
37+
</svg>
38+
</span>
39+
<span x-show="open">
40+
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.5"
41+
stroke="#2c3e50" fill="none"
42+
stroke-linecap="round" stroke-linejoin="round">
43+
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
44+
<path d="M6 15l6 -6l6 6"/>
45+
</svg>
46+
</span>
47+
</button>
48+
</div>
49+
</div>
50+
51+
52+

0 commit comments

Comments
 (0)