@@ -14,6 +14,8 @@ <h1 class="font-medium tracking-tight text-2xl truncate">{{ trip.name }}</h1>
1414 < div class ="flex gap-2 items-center text-xs text-gray-500 "> < i class ="pi pi-github "> </ i > itskovacs/trip</ div >
1515 </ div >
1616 < div class ="flex items-center gap-2 print:hidden ">
17+ < p-button pTooltip ="Packing list " tooltipPosition ="left " text (click) ="openPackingList() " icon ="pi pi-briefcase "
18+ severity ="help " />
1719 < span
1820 class ="bg-gray-100 text-gray-800 text-xs md:text-sm font-medium me-2 px-2.5 py-0.5 rounded min-w-fit dark:bg-gray-400 "> {{
1921 (totalPrice | number:'1.0-2') || '-' }} {{ currency$ | async }}</ span >
@@ -22,7 +24,8 @@ <h1 class="font-medium tracking-tight text-2xl truncate">{{ trip.name }}</h1>
2224</ section >
2325
2426< section class ="p-4 print:px-1 grid lg:grid-cols-3 gap-4 print:block ">
25- < div class ="p-4 shadow self-start rounded-md lg:col-span-2 max-w-screen print:col-span-full ">
27+ < div [ngClass] ="{ 'lg:col-span-2': !isExpanded, 'lg:col-span-3': isExpanded } "
28+ class ="p-4 shadow self-start rounded-md max-w-screen print:col-span-full ">
2629 < div [class.sticky] ="!isMapFullscreen "
2730 class ="top-0 z-10 bg-white p-2 mb-2 flex justify-between items-center dark:bg-surface-900 ">
2831 < div >
@@ -32,14 +35,17 @@ <h1 class="font-semibold tracking-tight text-xl">Plans</h1>
3235
3336 < div class ="flex items-center gap-2 print:hidden ">
3437 < div class ="hidden md:flex items-center gap-2 ">
35- < p-button
38+ < p-button pTooltip ="Expand table " class ="hidden lg:flex " icon ="pi pi-arrows-h "
39+ (click) ="isExpanded = !isExpanded " text />
40+ < p-button pTooltip ="Show filters " icon ="pi pi-filter " (click) ="toggleFiltering() " text />
41+ < p-button [pTooltip] ="tableExpandableMode ? 'f' : 'Switch table mode, allow column resizing' "
3642 [icon] ="tableExpandableMode ? 'pi pi-arrow-up-right-and-arrow-down-left-from-center' : 'pi pi-arrow-down-left-and-arrow-up-right-to-center' "
3743 (click) ="tableExpandableMode = !tableExpandableMode " text />
3844 < div class ="border-l border-solid border-gray-700 h-4 "> </ div >
39- < p-button icon ="pi pi-car " (click) ="tripToNavigation() " text />
40- < p-button icon =" pi pi-directions " [severity] =" tripMapAntLayerDayID == -1 ? 'help' : 'primary' "
41- (click) ="toggleTripDaysHighlight() " text />
42- < p-button icon ="pi pi-print " (click) ="printTable() " text />
45+ < p-button pTooltip =" Open Google Maps directions " icon ="pi pi-car " (click) ="tripToNavigation() " text />
46+ < p-button pTooltip =" Show itinerary on map " icon =" pi pi-directions "
47+ [severity] =" tripMapAntLayerDayID == -1 ? 'help' : 'primary' " (click) ="toggleTripDaysHighlight() " text />
48+ < p-button pTooltip =" Print Trip " icon ="pi pi-print " (click) ="printTable() " text />
4349 </ div >
4450
4551 < div class ="flex md:hidden items-center ">
@@ -49,20 +55,31 @@ <h1 class="font-semibold tracking-tight text-xl">Plans</h1>
4955 </ div >
5056 </ div >
5157
58+ @if (isFilteringMode) {
59+ < div class ="grid md:grid-cols-2 gap-2 mb-2 ">
60+ < p-multiselect display ="chip " [options] ="tripTableColumns " [(ngModel)] ="tripTableSelectedColumns "
61+ styleClass ="capitalize " selectedItemsLabel ="{0} columns selected " placeholder ="Choose Columns " />
62+
63+ < input [formControl] ="tripTableSearchInput " pInputText placeholder ="Search... " />
64+ </ div >
65+ }
66+
5267 @defer {
5368 @if (flattenedTripItems.length) {
5469 < p-table [value] ="flattenedTripItems " class ="print-striped-rows " styleClass ="max-w-[85vw] md:max-w-full "
55- [rowGroupMode] ="tableExpandableMode ? 'subheader': 'rowspan' " groupRowsBy ="td_label ">
70+ [rowGroupMode] ="tableExpandableMode ? 'subheader': 'rowspan' " groupRowsBy ="td_label "
71+ [resizableColumns] ="tableExpandableMode ">
5672 < ng-template #header >
5773 < tr >
58- < th > Day</ th >
59- < th class ="w-10 "> Time</ th >
60- < th > Text</ th >
61- < th class ="w-24 "> Place</ th >
62- < th > Comment</ th >
63- < th class ="w-20 "> LatLng</ th >
64- < th class ="w-12 "> Price</ th >
65- < th class ="w-12 "> Status</ th >
74+ @if (!tableExpandableMode && tripTableSelectedColumns.includes('day')) {< th class ="w-24 " pResizableColumn > Day
75+ </ th > }
76+ @if (tripTableSelectedColumns.includes('time')) {< th class ="w-12 " pResizableColumn > Time</ th > }
77+ @if (tripTableSelectedColumns.includes('text')) {< th pResizableColumn > Text</ th > }
78+ @if (tripTableSelectedColumns.includes('place')) {< th pResizableColumn > Place</ th > }
79+ @if (tripTableSelectedColumns.includes('comment')) {< th pResizableColumn > Comment</ th > }
80+ @if (tripTableSelectedColumns.includes('LatLng')) {< th class ="w-12 " pResizableColumn > LatLng</ th > }
81+ @if (tripTableSelectedColumns.includes('price')) {< th class ="w-12 " pResizableColumn > Price</ th > }
82+ @if (tripTableSelectedColumns.includes('status')) {< th class ="w-12 " pResizableColumn > Status</ th > }
6683 </ tr >
6784 </ ng-template >
6885 @if (tableExpandableMode) {
@@ -83,81 +100,90 @@ <h1 class="font-semibold tracking-tight text-xl">Plans</h1>
83100 < ng-template #expandedrow let-tripitem >
84101 < tr class ="h-12 cursor-pointer " [class.font-bold] ="selectedItem?.id === tripitem.id "
85102 (click) ="onRowClick(tripitem) ">
86- < td class ="font-mono text-sm max-w-20 truncate "> {{ tripitem.td_label }}</ td >
87- < td class ="font-mono text-sm "> {{ tripitem.time }}</ td >
88- < td class ="relative max-w-60 truncate ">
89- < div class ="relative ">
90- @if (tripitem.status) {< div class ="block xl:hidden absolute top-0 -left-1.5 size-1.5 rounded-full "
103+ @if (tripTableSelectedColumns.includes('time')) {< td class ="font-mono text-sm "> {{ tripitem.time }}</ td > }
104+ @if (tripTableSelectedColumns.includes('text')) {< td class ="relative ">
105+ < div class ="truncate ">
106+ @if (tripitem.status) {< div class ="block absolute top-3 left-1.5 size-2 rounded-full "
91107 [style.background] ="tripitem.status.color "> </ div > }
92108 {{ tripitem.text }}
93109 </ div >
94- </ td >
95- < td class ="relative ">
110+ </ td > }
111+ @if (tripTableSelectedColumns.includes('place')) { < td class ="relative ">
96112 @if (tripitem.place) {
97- < div class ="ml-7 print:ml-0 max-w-24 print:whitespace-normal ">
113+ < div class ="ml-7 print:ml-0 truncate print:whitespace-normal ">
98114 < img [src] ="tripitem.place.image || tripitem.place.category.image "
99115 class ="absolute left-0 top-1/2 -translate-y-1/2 w-9 rounded-full object-cover print:hidden " /> {{
100116 tripitem.place.name }}
101117 </ div >
102118 } @else {-}
103- </ td >
104- < td class ="max-w-20 truncate print:whitespace-pre-line "> {{ tripitem.comment || '-' }}</ td >
105- < td class ="font-mono text-sm ">
106- < div class ="max-w-20 print:max-w-full truncate ">
119+ </ td > }
120+ @if (tripTableSelectedColumns.includes('comment')) {< td >
121+ < div class ="line-clamp-1 whitespace-pre-line print:line-clamp-none ">
122+ {{ tripitem.comment || '-' }}
123+ </ div >
124+ </ td > }
125+ @if (tripTableSelectedColumns.includes('LatLng')) {< td class ="font-mono text-sm ">
126+ < div class ="print:max-w-full truncate ">
107127 @if (tripitem.lat) { {{ tripitem.lat }}, {{ tripitem.lng }} }
108128 @else {-}
109129 </ div >
110- </ td >
111- < td class ="truncate "> @if (tripitem.price) {< span
130+ </ td > }
131+ @if (tripTableSelectedColumns.includes('price')) { < td class ="truncate "> @if (tripitem.price) {< span
112132 class ="bg-gray-100 text-gray-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded "> {{
113- tripitem.price }} {{ currency$ | async }}</ span > }</ td >
114- < td class ="truncate "> @if (tripitem.status) {< span [style.background] ="tripitem.status.color+'1A' "
115- [style.color] ="tripitem.status.color " class ="text-xs font-medium me-2 px-2.5 py-0.5 rounded "> {{
116- tripitem.status.label }}</ span > }</ td >
133+ tripitem.price }} {{ currency$ | async }}</ span > }</ td > }
134+ @if (tripTableSelectedColumns.includes('status')) {< td class ="truncate "> @if (tripitem.status) {< span
135+ [style.background] ="tripitem.status.color+'1A' " [style.color] ="tripitem.status.color "
136+ class ="text-xs font-medium me-2 px-2.5 py-0.5 rounded "> {{
137+ tripitem.status.label }}</ span > }</ td > }
117138 </ tr >
118139 </ ng-template >
119140 }
120141 @else {
121142 < ng-template #body let-tripitem let-rowgroup ="rowgroup " let-rowspan ="rowspan ">
122143 < tr class ="h-12 cursor-pointer " [class.font-bold] ="selectedItem?.id === tripitem.id "
123144 (click) ="onRowClick(tripitem) ">
124- @if (rowgroup) {
145+ @if (tripTableSelectedColumns.includes('day') && rowgroup) {
125146 < td [attr.rowspan] ="rowspan " class ="font-normal! max-w-20 truncate cursor-pointer "
126147 [class.text-blue-500] ="tripMapAntLayerDayID == tripitem.day_id "
127148 (click) ="toggleTripDayHighlightPathDay(tripitem.day_id); $event.stopPropagation() ">
128149 < div class ="truncate "> {{tripitem.td_label }}</ div >
129150 </ td >
130151 }
131- < td class ="font-mono text-sm "> {{ tripitem.time }}</ td >
132- < td class ="relative max-w-60 truncate ">
133- < div class ="relative ">
134- {{ tripitem.text }}
135- @if (tripitem.status) {< div class ="block xl:hidden absolute top-0 -left-1.5 size-1.5 rounded-full "
152+ @if (tripTableSelectedColumns.includes('time')) {< td class ="font-mono text-sm "> {{ tripitem.time }}</ td > }
153+ @if (tripTableSelectedColumns.includes('text')) {< td class ="relative max-w-60 ">
154+ < div class ="truncate ">
155+ @if (tripitem.status) {< div class ="block absolute top-3 left-1.5 size-2 rounded-full "
136156 [style.background] ="tripitem.status.color "> </ div > }
157+ {{ tripitem.text }}
137158 </ div >
138- </ td >
139- < td class ="relative ">
159+ </ td > }
160+ @if (tripTableSelectedColumns.includes('place')) { < td class ="relative ">
140161 @if (tripitem.place) {
141162 < div class ="ml-7 print:ml-0 max-w-24 truncate print:whitespace-normal ">
142163 < img [src] ="tripitem.place.image || tripitem.place.category.image "
143164 class ="absolute left-0 top-1/2 -translate-y-1/2 w-9 rounded-full object-cover print:hidden " /> {{
144165 tripitem.place.name }}
145166 </ div >
146167 } @else {-}
147- </ td >
148- < td class ="max-w-20 truncate print:whitespace-pre-line "> {{ tripitem.comment || '-' }}</ td >
149- < td class ="font-mono text-sm ">
168+ </ td > }
169+ @if (tripTableSelectedColumns.includes('comment')) {< td >
170+ < div class ="line-clamp-1 whitespace-pre-line print:line-clamp-none ">
171+ {{ tripitem.comment || '-' }}
172+ </ div >
173+ </ td > }
174+ @if (tripTableSelectedColumns.includes('LatLng')) {< td class ="font-mono text-sm ">
150175 < div class ="max-w-20 print:max-w-full truncate ">
151176 @if (tripitem.lat) { {{ tripitem.lat }}, {{ tripitem.lng }} }
152177 @else {-}
153178 </ div >
154- </ td >
155- < td class ="truncate "> @if (tripitem.price) {< span
179+ </ td > }
180+ @if (tripTableSelectedColumns.includes('price')) { < td class ="truncate "> @if (tripitem.price) {< span
156181 class ="bg-gray-100 text-gray-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded "> {{
157- tripitem.price }} {{ currency$ | async }}</ span > }</ td >
158- < td class ="truncate "> @if (tripitem.status) {< span [style.background] ="tripitem.status.color+'1A' "
159- [style.color] ="tripitem.status.color " class ="text-xs font-medium me-2 px-2.5 py-0.5 rounded "> {{
160- tripitem.status.label }}</ span > }</ td >
182+ tripitem.price }} {{ currency$ | async }}</ span > }</ td > }
183+ @if (tripTableSelectedColumns.includes('status')) {< td class ="truncate "> @if (tripitem.status) {< span
184+ [style.background] ="tripitem.status.color+'1A' " [style.color] ="tripitem.status.color "
185+ class ="text-xs font-medium me-2 px-2.5 py-0.5 rounded "> {{
186+ tripitem.status.label }}</ span > }</ td > }
161187 </ tr >
162188 </ ng-template >
163189 }
@@ -181,7 +207,8 @@ <h2 class="mb-0 text-4xl text-center tracking-tight font-extrabold text-gray-900
181207 }
182208 </ div >
183209
184- < div class ="flex flex-col gap-4 sticky top-4 self-start max-w-screen print:hidden ">
210+ < div [ngClass] ="{ 'grid col-span-full grid-cols-4': isExpanded, 'flex flex-col sticky': !isExpanded } "
211+ class ="gap-4 top-4 self-start max-w-screen print:hidden min-w-0 ">
185212 @if (selectedItem) {
186213 < div class ="p-4 w-full max-w-full min-h-20 md:max-h-[600px] rounded-md shadow text-center ">
187214 < div class ="flex justify-between items-center mb-3 ">
@@ -263,8 +290,9 @@ <h1 class="font-semibold tracking-tight text-xl">Map</h1>
263290 </ div >
264291
265292 < div class ="flex gap-2 ">
266- < p-button icon ="pi pi-window-maximize " (click) ="toggleMapFullscreen() " text />
267- < p-button icon ="pi pi-refresh " [disabled] ="!places.length " (click) ="resetMapBounds() " text />
293+ < p-button pTooltip ="Fullscreen " icon ="pi pi-window-maximize " (click) ="toggleMapFullscreen() " text />
294+ < p-button pTooltip ="Reset bounds " icon ="pi pi-refresh " [disabled] ="!places.length " (click) ="resetMapBounds() "
295+ text />
268296 </ div >
269297 </ div >
270298
@@ -297,7 +325,7 @@ <h1 class="font-semibold tracking-tight text-xl">Places</h1>
297325 </ div >
298326
299327 @if (!collapsedTripPlaces) {
300- < div class =" max-h-[25vh ] overflow-y-auto ">
328+ < div [ class.max-h-64!] =" !isExpanded " class =" max-h-[340px ] overflow-y-auto ">
301329 @defer {
302330 @for (p of places; track p.id) {
303331 < div class ="flex items-center gap-4 py-2 px-4 hover:bg-gray-50 rounded-md overflow-auto dark:hover:bg-gray-800 "
@@ -360,7 +388,7 @@ <h1 class="font-semibold tracking-tight text-xl">Days</h1>
360388 </ div >
361389
362390 @if (!collapsedTripDays) {
363- < div class =" max-h-[20vh ] overflow-y-auto ">
391+ < div [ class.max-h-64!] =" !isExpanded " class =" max-h-[340px ] overflow-y-auto ">
364392 @defer {
365393 @for (d of trip.days; track d.id) {
366394 < div class ="flex items-center gap-4 rounded-md justify-between h-10 px-4 py-2 w-full max-w-full ">
@@ -399,7 +427,7 @@ <h1 class="font-semibold tracking-tight text-xl">Watchlist</h1>
399427 </ div >
400428
401429 @if (!collapsedTripStatuses) {
402- < div class =" max-h-[20vh ] overflow-y-auto ">
430+ < div [ class.max-h-40!] =" !isExpanded " class =" max-h-[340px ] overflow-y-auto ">
403431 @defer {
404432 @for (item of getWatchlistData; track item.id) {
405433 < div class ="flex items-center gap-2 h-10 px-4 py-2 w-full max-w-full ">
@@ -451,4 +479,30 @@ <h1 class="text-2xl font-semibold text-gray-800 tracking-tight dark:text-white m
451479 < p-button text label ="itskovacs/trip " icon ="pi pi-github " (click) ="toGithub() " />
452480</ section >
453481}
454- }
482+ }
483+
484+ < p-dialog header ="Packing list " [draggable] ="false " [dismissableMask] ="true " [modal] ="true "
485+ [(visible)] ="packingDialogVisible " styleClass ="w-[95%] md:w-[70%] lg:w-[50%] ">
486+ < section class ="md:max-w-3/4 md:mx-auto max-h-[80%] md:max-h-[600px] ">
487+ < div class ="grid gap-2 mt-4 pb-4 ">
488+ @for (c of dispPackingList | keyvalue; track c.key) {
489+ < div class ="mt-4 text-md font-semibold capitalize "> {{ c.key }}</ div >
490+
491+ < div class ="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 ">
492+ @for (item of c.value; track item.id) {
493+ < div class ="relative flex items-center gap-3 rounded-md p-2 hover:bg-gray-100 dark:hover:bg-white/5 ">
494+ < label [for] ="item.id " [class.line-through] ="item.packed "
495+ class ="flex items-center gap-2 w-full cursor-pointer ">
496+ < p-checkbox disabled [binary] ="true " [inputId] ="item.id.toString() " [(ngModel)] ="item.packed " />
497+ < div class ="pr-6 md:pr-0 truncate select-none flex-1 ">
498+ @if (item.qt) {< span class ="text-gray-400 mr-0.5 "> {{ item.qt }}</ span > }
499+ < span > {{ item.text }}</ span >
500+ </ div >
501+ </ label >
502+ </ div >
503+ }
504+ </ div >
505+ }
506+ </ div >
507+ </ section >
508+ </ p-dialog >
0 commit comments