From ea0f008dcf0e25b36aff8b4c3fbad366d4173119 Mon Sep 17 00:00:00 2001 From: jld3103 Date: Sat, 4 Nov 2023 10:48:37 +0100 Subject: [PATCH] fix(neon_dashboard): Remove scrolling inside dashboard widgets Signed-off-by: jld3103 --- .../neon_dashboard/lib/src/pages/main.dart | 134 +++++++++++++++++- .../lib/src/widgets/dry_intrinsic_height.dart | 33 +++++ .../lib/src/widgets/widget.dart | 85 ++--------- .../neon_dashboard/test/goldens/widget.png | Bin 6318 -> 6244 bytes .../test/goldens/widget_not_round.png | Bin 5971 -> 5903 bytes .../test/goldens/widget_with_empty.png | Bin 6473 -> 6414 bytes .../test/goldens/widget_with_half_empty.png | Bin 6491 -> 6428 bytes .../test/goldens/widget_without_buttons.png | Bin 5201 -> 4558 bytes .../test/goldens/widget_without_items.png | Bin 5619 -> 5526 bytes .../neon/neon_dashboard/test/widget_test.dart | 88 +++++++++--- 10 files changed, 238 insertions(+), 102 deletions(-) create mode 100644 packages/neon/neon_dashboard/lib/src/widgets/dry_intrinsic_height.dart diff --git a/packages/neon/neon_dashboard/lib/src/pages/main.dart b/packages/neon/neon_dashboard/lib/src/pages/main.dart index d06b21e2..fd629743 100644 --- a/packages/neon/neon_dashboard/lib/src/pages/main.dart +++ b/packages/neon/neon_dashboard/lib/src/pages/main.dart @@ -1,9 +1,17 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:neon/blocs.dart'; +import 'package:neon/theme.dart'; import 'package:neon/utils.dart'; import 'package:neon/widgets.dart'; +import 'package:neon_dashboard/l10n/localizations.dart'; import 'package:neon_dashboard/src/blocs/dashboard.dart'; +import 'package:neon_dashboard/src/widgets/dry_intrinsic_height.dart'; import 'package:neon_dashboard/src/widgets/widget.dart'; +import 'package:neon_dashboard/src/widgets/widget_button.dart'; +import 'package:neon_dashboard/src/widgets/widget_item.dart'; +import 'package:nextcloud/dashboard.dart' as dashboard; /// Displays the whole dashboard page layout. class DashboardMainPage extends StatelessWidget { @@ -21,15 +29,37 @@ class DashboardMainPage extends StatelessWidget { builder: (final context, final snapshot) { Widget? child; if (snapshot.hasData) { + var minHeight = 504.0; + + final children = []; + for (final widget in snapshot.requireData.entries) { + final items = buildWidgetItems( + context: context, + widget: widget.key, + items: widget.value, + ).toList(); + + final height = items.map((final i) => i.height!).reduce((final a, final b) => a + b); + minHeight = max(minHeight, height); + + children.add( + DashboardWidget( + widget: widget.key, + children: items, + ), + ); + } + child = Wrap( alignment: WrapAlignment.center, spacing: 8, runSpacing: 8, - children: snapshot.requireData.entries + children: children .map( - (final widget) => DashboardWidget( - widget: widget.key, - items: widget.value, + (final widget) => SizedBox( + width: 320, + height: minHeight + 24, + child: widget, ), ) .toList(), @@ -53,4 +83,100 @@ class DashboardMainPage extends StatelessWidget { }, ); } + + /// Builds the list of messages, [items] and buttons for a [widget]. + @visibleForTesting + static Iterable buildWidgetItems({ + required final BuildContext context, + required final dashboard.Widget widget, + required final dashboard.WidgetItems? items, + }) sync* { + yield SizedBox( + height: 64, + child: DryIntrinsicHeight( + child: ListTile( + title: Text( + widget.title, + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + leading: SizedBox.square( + dimension: largeIconSize, + child: NeonUrlImage( + url: widget.iconUrl, + svgColorFilter: ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn), + size: const Size.square(largeIconSize), + ), + ), + ), + ), + ); + + yield const SizedBox( + height: 20, + ); + + final halfEmptyContentMessage = _buildMessage(items?.halfEmptyContentMessage); + final emptyContentMessage = _buildMessage(items?.emptyContentMessage); + if (halfEmptyContentMessage != null) { + yield halfEmptyContentMessage; + } + if (emptyContentMessage != null) { + yield emptyContentMessage; + } + if (halfEmptyContentMessage == null && emptyContentMessage == null && (items?.items.isEmpty ?? true)) { + yield _buildMessage(DashboardLocalizations.of(context).noEntries)!; + } + + if (items?.items != null) { + for (final item in items!.items) { + yield SizedBox( + height: 64, + child: DryIntrinsicHeight( + child: DashboardWidgetItem( + item: item, + roundIcon: widget.itemIconsRound, + ), + ), + ); + } + } + + yield const SizedBox( + height: 20, + ); + + if (widget.buttons != null) { + for (final button in widget.buttons!) { + yield SizedBox( + height: 32, + child: DashboardWidgetButton( + button: button, + ), + ); + } + } + } + + static SizedBox? _buildMessage(final String? message) { + if (message == null || message.isEmpty) { + return null; + } + + return SizedBox( + height: 60, + child: Center( + child: Column( + children: [ + const Icon( + Icons.check, + size: largeIconSize, + ), + Text(message), + ], + ), + ), + ); + } } diff --git a/packages/neon/neon_dashboard/lib/src/widgets/dry_intrinsic_height.dart b/packages/neon/neon_dashboard/lib/src/widgets/dry_intrinsic_height.dart new file mode 100644 index 00000000..896a07f9 --- /dev/null +++ b/packages/neon/neon_dashboard/lib/src/widgets/dry_intrinsic_height.dart @@ -0,0 +1,33 @@ +// ignore_for_file: public_member_api_docs +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; + +/// NOTE ref: https://github.com/flutter/flutter/issues/71687 & https://gist.github.com/matthew-carroll/65411529a5fafa1b527a25b7130187c6 +/// Same as `IntrinsicHeight` except that when this widget is instructed +/// to `computeDryLayout()`, it doesn't invoke that on its child, instead +/// it computes the child's intrinsic height. +/// +/// This widget is useful in situations where the `child` does not +/// support dry layout, e.g., `TextField` as of 01/02/2021. +class DryIntrinsicHeight extends SingleChildRenderObjectWidget { + const DryIntrinsicHeight({ + super.key, + super.child, + }); + + @override + RenderDryIntrinsicHeight createRenderObject(final BuildContext context) => RenderDryIntrinsicHeight(); +} + +class RenderDryIntrinsicHeight extends RenderIntrinsicHeight { + @override + Size computeDryLayout(final BoxConstraints constraints) { + if (child != null) { + final height = child!.computeMinIntrinsicHeight(constraints.maxWidth); + final width = child!.computeMinIntrinsicWidth(height); + return Size(width, height); + } else { + return Size.zero; + } + } +} diff --git a/packages/neon/neon_dashboard/lib/src/widgets/widget.dart b/packages/neon/neon_dashboard/lib/src/widgets/widget.dart index d2559c62..3680a3c5 100644 --- a/packages/neon/neon_dashboard/lib/src/widgets/widget.dart +++ b/packages/neon/neon_dashboard/lib/src/widgets/widget.dart @@ -1,10 +1,5 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; -import 'package:neon/theme.dart'; -import 'package:neon/widgets.dart'; -import 'package:neon_dashboard/l10n/localizations.dart'; -import 'package:neon_dashboard/src/widgets/widget_button.dart'; -import 'package:neon_dashboard/src/widgets/widget_item.dart'; import 'package:nextcloud/dashboard.dart' as dashboard; /// Displays a single dashboard widget and its items. @@ -12,7 +7,7 @@ class DashboardWidget extends StatelessWidget { /// Creates a new dashboard widget items. const DashboardWidget({ required this.widget, - required this.items, + required this.children, super.key, }); @@ -20,83 +15,19 @@ class DashboardWidget extends StatelessWidget { final dashboard.Widget widget; /// The items of the widget to be displayed. - final dashboard.WidgetItems? items; + final List children; @override - Widget build(final BuildContext context) { - final halfEmptyContentMessage = _renderMessage(items?.halfEmptyContentMessage); - final emptyContentMessage = _renderMessage(items?.emptyContentMessage); - - return SizedBox( - width: 320, - height: 560, - child: Card( + Widget build(final BuildContext context) => Card( child: InkWell( onTap: widget.widgetUrl != null && widget.widgetUrl!.isNotEmpty ? () => context.go(widget.widgetUrl!) : null, borderRadius: const BorderRadius.all(Radius.circular(12)), - child: ListView( + child: Padding( padding: const EdgeInsets.all(8), - key: PageStorageKey('dashboard-${widget.id}'), - children: [ - ListTile( - title: Text( - widget.title, - style: const TextStyle( - fontWeight: FontWeight.bold, - ), - ), - leading: SizedBox.square( - dimension: largeIconSize, - child: NeonUrlImage( - url: widget.iconUrl, - svgColorFilter: ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn), - size: const Size.square(largeIconSize), - ), - ), - ), - const SizedBox( - height: 20, - ), - if (halfEmptyContentMessage != null) halfEmptyContentMessage, - if (emptyContentMessage != null) emptyContentMessage, - if (halfEmptyContentMessage == null && emptyContentMessage == null && (items?.items.isEmpty ?? true)) - _renderMessage(DashboardLocalizations.of(context).noEntries)!, - ...?items?.items.map( - (final item) => DashboardWidgetItem( - item: item, - roundIcon: widget.itemIconsRound, - ), - ), - const SizedBox( - height: 20, - ), - ...?widget.buttons?.map( - (final button) => DashboardWidgetButton( - button: button, - ), - ), - ], + child: Column( + children: children, + ), ), ), - ), - ); - } - - Widget? _renderMessage(final String? message) { - if (message == null || message.isEmpty) { - return null; - } - - return Center( - child: Column( - children: [ - const Icon( - Icons.check, - size: largeIconSize, - ), - Text(message), - ], - ), - ); - } + ); } diff --git a/packages/neon/neon_dashboard/test/goldens/widget.png b/packages/neon/neon_dashboard/test/goldens/widget.png index 614120d9d5e1ec392184f11acb91e9b376f1a38d..3b27e2ab14dbdfbb46159054f3aed8a4c654f72b 100644 GIT binary patch literal 6244 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 N&-U&p+kWKyKLBW!kVpUk literal 5971 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 F?eCHt>P`Rv diff --git a/packages/neon/neon_dashboard/test/goldens/widget_with_empty.png b/packages/neon/neon_dashboard/test/goldens/widget_with_empty.png index 8460bc589153924a4572471aadfb0a0590621366..d3bd285b2293218041a44aff5606f0fabc593b73 100644 GIT binary patch literal 6414 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 diff --git a/packages/neon/neon_dashboard/test/goldens/widget_with_half_empty.png b/packages/neon/neon_dashboard/test/goldens/widget_with_half_empty.png index 2028f4f81ee996060f52ec85ad46043fa33fa73d..3761f377c96cedcad066d4029aa50f2eba372a25 100644 GIT binary patch literal 6428 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 literal 6491 zcmeHLXH=8f);^&L79b!UfeBZz0iz&A2t*A6gNQR!>BTD|Dn@z&Bm;_}1*|C2R6r+? z01^c03JMmgLa5=Ih!BC$LP;R-y*T%N_s{(^Yg~7I>s#~w$$8(Lv-duGKf5NLJYltM zv+`yDz&0Ce^e+GiYXBhRDlP_n$qbLX1pUB5ez7_NsO_q3=tU&th>fE-^hArFCIX-& zYJ)!P7@0LSj7!fBi)opiE)US_zj7s6Mm*xYXk1g$s54qO+bw9D#GaGxn^TBB6^BUj zK@_HOQ=gJ$F{!64>DfcP>!6SwVe_rt%MK#GGW!%SNuRtdb>!*0Gvyf{EQEFpi@fLL z%nP!SV+)y|(zZpl^R5h=m;~pHWy!)IfxbPB22KvEf@Dpng zR(}ar`-Bqj?%$SqaJE&mh{YeJx1<^kOLtt1T6|4hMxo8zuF_v%@6^TCvn%kr;Es6pQXiop1WB; z!_!MBS8F`qO&@g04q1G@-+X`UxM#%30uGL`L#JdgL_uvNA$rArB%Co(!siA&BGWeg zxZ>y}7myWx%#1g$E#>k2+-R_6bHg|Ce3{~qc4I*b{uE|7wQG1d+gv>F`Y|gjmd;p~ zT%};?LV#uSTsIEneF&Rk(y5UhxeYGS;KGB)kF^>5pkIott1fdP3hwATL~J@@kJ zmg(5lE^SY&C@mFRr&eM-SL#}MaaaP5@n$1I=NqkD*ePspw^6cG9t9H0He+8h(YTx| z55_}p3V&V>=`gQsl_s3Qu9ZzKcbh_N?IhFVH;H+9o)$;xBiH-Ft=T(3CtGV%>w^&f zm+eYIoyR*Yp6&3!ZUUjzZ}b+QNChkHJ|L3U&sX4DMr!W^yUw`;H*Eo+bGwiT0M?o) z00;(uX8FMri>f(QajqwYq+XI{MIj$NYZnl#sHk|iYc{BtnrNqD)HZH-=IxRYIBO)7 z|7$|!wwC^2(|}`@Ws~m<%2pHPwz+-mS8+y`9^j90?N^ougBy^#>&-0zG~dE#JwOO& z$?O9_BNadh?-rN-E=#+E>qB}V}e*db#75hq?(PB<9wMVSR& zp=;)mr#wtjS-NKHaaF62GVFO(MB-laD9f+8vt)a`)*T&B!%-Gut|84xx8Vm;7mLC_95eUDBUTOU1`SldKzh5-s>%z-; z7$9WRLJ3gxt6)%{ghg2PIMt0$Pmsw(oAp>GPg-fj93FNMf|t&Nox-25&Wv*?b}NR} z=bS=&&UFpDCznmJjzAD~L)nU2Yrgb%sm9?CqF>*~M)k_&)*`69UZck`s~Pn(uOd5E z*8B!qyd&2{;c&w&{9%u^u6K`PqS4KoY34Gvcd|_$ZG(@lo6=q;+>3<*&tlgvdPk-? zMF-8yW2Y8zL0!Z2U)ms_-%+qrD4&eLjxC}ok9i^Ike*$pmD*$lyp03|$-n8qHIM>i zm(#nwaa1=sXc@S)2|$U<42As?`uKIr7D#mNdyI)Z0H^mTYgFV=Z@r_sEv&(y=)N7d z=;=hkh&>EA5#i`14PAP7lBjir_dH|j9Jv~oEea`Xt7T4H&VC*N^`VzLF=Ba!5Y z(zlrKuXbanYz2T;gn<3R^eliX!&%W1>W>{4j+^Eq$f?w1|2?or?Vdt?86qRIVO zCiYs$mnFl6#ejUZvJ01RY&q0TuHJZZ9}go1tZ(5ZoRI=GNLcynY8ngJ33=<^8J*NX zJ)OoZRm>RzaCTEWVKvE_0aaI18WyP6?n^eY{}e|}gXJ&VAMt$9?RTb}Nz-EckB`iM zP9qmpFeK)$dg?FyX78!Av^vAstzLP)zuUDw+HwG+ogMj-7T*53kA1Ojd56NQ8$0m^ zkh38e*hO{wiKp)a1X7x0N*PR6_S(c{Z1UhuA$1Oa#BtC-xsOP-aO4cbJ+Vf@{V< z@>+u8pC}DYsPzdQ>?0{$?dTqa(B|b9!G_&TO*_%tynHrvsrO;;hr8z3Pp>%lGNPaZ zra{j^V&ClHtB(d>`<>5E;?z^0EPO1)Xu|y;vG&);yu7wm2%wVBz5!8(>%7vsF0l4j zUohKnImkU-D0|6!5M&~mytck%iG=+5u3|0`x&mUl81jx<+PQA}!Y3U~%LHKHz8+Uk z%vN6l1hmcqA{0_loy7Oa;NP_z_*29}Gt@fShQ-6mX=bz^dd+yp&FV0_41<-EQYXZ0 zJ040b4&!5MCr3m4b7RI{!LCipS*h0jD6gC8jg!e;PhIv8UK37fSw}(O@^mXLB!-?w8`6`D>>I_$Fi>Ie zHbgAn#*nI#Qe+X4vFtODBN)9DJrxr1Dxt#N)*c4VD#E%&1{17UdvohF6P_Kq-~4{- z#T|*zZkO}8i!|lHc|m)&B%lg}XYG(#2|)+O-RJsL%L88qnp`%_ny2190Xz!JxAl zjl8(FbnT~(JiFnitDo*FmSp6>z>k{41)FF$r}5KeeYL(%d@GH5-aSzc?xF%??s~k)pt7APW|l-qkf*#XA&WaaK3rFd+1|LoB1PA41AT`!5s(9Df(ukp*4F z;LH1|dvll#abp&rxv=uu;ih4?_ikN?c<-AJlAk;8! zkl%#oI_9J0XehUN=`uWU|GkO*w5UrgkWuFQCoUJ$Bb*O?L-T&!# zfdn3|Z8!2)NmhU)xJ!X(?d$t+^YCTfJz;QWZ|)Ta5QN|!*3=Yzn!ZxeQ9sXoM;Dwr z8ho=qxP2&RJookEa$!Id3P34;ZaliQ2clCp@{qStiyglY0@M9TrlnkwLsxPS0w2Q= z$grv*L%(90BGj^Gr#x_N!kDRpQU*Tosh^4V--JjPN1MkD3?tx@6+UXiPlLOtnP<{t3Ko$S?K|ufj?};EV zk4oLc;P$%Q&N+PFZBbjetHx0AC~WltP9*# zzs9R!DQsAEb9w8pP(YZjp8V)qO3&(c82D+ORDNTv1c2>-L&=;UF;^Q|?UrJ`SfSs7 zc+X_slqAjTn!NbCi=74vF%Uw8e^1l1y~0Z!&r zeu6T<_iEDqR8;;>jpAQ2{AJDWJ9_vFQGX%ozlW&flIahwUx(&gAd}s%({T*F^$r6D zvM*jH6ni)L#$5jaw9#S(d?K-;AOh+!?yG7{I8)tDZA=#_v8ThXK&gQV4HuD>BeND8 z1^oxgdXz1?8Tqf>BT;L5frMw5-%*UL(5oT;8b(SvTRi30y9d`)v?>zLxMEmIk<2&R z91>CeHbV$xQwLs^)NxuhNwut;8cu3`eLeRuNHsWcK&IqSIL2(@qeF{jv!GxJlBft8 zv*rxdM$MZ;!$gxn_KgB|JWytLM|jIb;MX}t2&PIwB>**&=|rNt3)PL6u!kIf!gPW5 z5u$jRr)@6p{hY5JD-9pBMAvcEfDb*xr_RS0JyaX|rrW<^u?Jt=G2*{wEAS%RDchJi zPfb^qRP7S1mjkcK~|R$*T0G=wnAdhAB(b_dBe(uTRi_nEww z;&md?;b=5K+4g6bD?6dHk+~rvF+@*dwK+F2g%Q@^cx^`!{NB1Rb^rSj` zUKzRB$7tItlD!fB0ODdIF-Viy1x@n*Z#-^;>#$o5mh>^tw-y@`*;t-HQ;+z>{ST?= B-4_4= diff --git a/packages/neon/neon_dashboard/test/goldens/widget_without_buttons.png b/packages/neon/neon_dashboard/test/goldens/widget_without_buttons.png index 409ce159d901558053cc99b4c553e398d186fd7c..1fa76c61b41bb953b66de3ad0af876544fcc5902 100644 GIT binary patch literal 4558 zcmeHKZBSEZ7Jd^b(#{}toetYV36`N?DYEryKmvrKl``GdwqsWq%Ey2txR4?QNJvOR z>9p9ff^AnZ8j{)FQD)>D4Jd@bj-a5ITop+OkOUhOG=W?oBq1Lpd$FDIkNu%-|8#i& z+_}%3bI&=?`MB@-_T!II{9bzPB>;e5>ihdX1;8r=0DPLS4~Cqrs5y!~aP&`8l0lm+ z=n?kfO;1ie=!=~y-^0fM*uqTR_wGTaU_q7LqPAoXE+L`Ad#{PYvUYjp^LA;GzrXcK zcfN8pZ`ZAz5kw%VjN1Z({myiX{?B>8*e-(r3!d#mLqJ@k>g+ z9X{U5>pU|_gnFcCKgymHaqb_FqzX$eEMlS585YND4{?|B2@tM55tjHfA82)|m$D8nP1Wxz0O;nM(|$9)>mUf!!%e#)7UP(;Y+da1}+$ zF5M~7UjUdqC}f+i+6Tpl5S6FQHUZJ64K^tnVI(^v2VBiRc>xf+qe;jzxbEH{zXQ>= zEqhkd*!X1`#)-<4T_10dM`B61(%RAj`-?mmDqTxAG(^asi#n#Zo_zff${bk5yprc* zUe!gmo#kIGwOGWs(xr06=M8=@08o^L^b8L-x3~J8r1uniI*UR8$T72|QR)uI)D)=H z9{Hdt-wP{*a|$!9#AGNeBv{ibt+z{wF9XnVm6lL=gz_09XaQNo10Z?B+ZTY7Td;2= z?XSk{zKX-p!_NpRyY6@u5!p6VrotT>nWF#K@b>V6vp=%GS(xr=FZ4*)ocdYD<~AcF zzg3I_MMV4qZr76-K~u?(EOT1sANsawQ3%cV1xZ)xRgw& zr9p!SlSMN%Sp3iG+^@$*>C{_pUaCDEbNJ*~E~@S~PVo-wMg(24I`0qZrAPJhePYi0Y2gPaZ<_VQ-tj+HeD5n0ki_l5{qam)%Kz^s zFgu}ZosOP-xCKlO37%HlPx6mtEXS;5$?w7!O-J$1(E(42j2{)400x_t89U<9D^|`b zmG^~owSiXxJ1bNbPJ!)oo<~+osARTXG2F~kGbHpjDryl)xQRA9^14}??Rj9KkC)6( zALD74+;t$_D?H>k_2y&G{*XwYYg9ZTYD4`Qr|brGPix}+8{lu6R~v1((T2anA7-Ns zpXcJdG17nE>75=Jg1j9aT|9zS^q_wE-oKkD6k!&JMyn2rT^#!I=T#~0=`&qKrNI(Vr${dSWj9XS9(U@FX0||93!*F)1 zw40bDb=$R$?(uc0 z>&wf_u7~dh$nxqFtXm;7+N>ezB8&vi@@P0ON8{$8lO@A-lw|BuI=;FZo=CKLjB7Cn zENbVV1-P9MT_Nmet1q1y_RnOEo^PKo!-Bm~a_xjjNOow+E(2UuK>3GU%DbG=A*D{k zRh2hhA?_yLSPHZRfM6v^LKCQX#oQq zwd+C*vS&^JQ3c%VFTNHC08`9%@SCU}_nP@cF*h%`YO&CKiY?vgDb@7b#^4XJEjmco z-8@le>Aq;D>b=aW&{HumY^3T}v}e}!X)KD=IdF~~2Qg%@W(*DujN1Z!IfJA3dAM96 V?_9&s*U{@(>U$sUYfH|l`9Dbzz}Nr) literal 5201 zcmeHLX;f3!7CuQpp$IrF6rKXhR(-2lumXZ0grb%D5KzcPrZ5PVk_bUD41qu#>QD;Q z_NfJAuuvkGxs)kkvRETUW^YmmBt|SlLI@BNhCuSJzIMG|Z@t&oKd)=Cf84vyzWbc} z-S6&ipS91eQy#ARZ<)LW0MI}2(J?OoaOMDDeRbBMp6s|QG3X5w>*eYKD!O+}q64j1 zmlFgX)RJ|=ZvwDIb>i3ugoOLj5#r~83q+1cm^HYKearinUa4-8r8!dm#YwHi)5w_i zW!Q`3;kNl*xNaBys!@aUyMOgm-4M36xTm(|LNG< zLX8q0@_}R}@V-*9K1A*Ko1u2h36TmlmmC{b9}P81$cmSJ+v0r? z3WQh@d)9;d5*O?%!$Z--i;cpiXEH8FwwU1H;E+@u;SP3_W%PyT@*aF@ zJVbvW$pQ>BCF%X@YS=VcmLyPRw5sQD((7)vI)*Q7L_g1lNjXjzTx-I{GaMl*8QM8X z+XG&FFWPs+iErKYcD`mfmq(w?Y$bHlK;`ZltD3H;dO=X(?1X!!qx$C_9|Q;4h-nt! z#U0$MeXT2(4b?03)J0dsdI*;wjm$2NW{HaJXI61|R=iM<{}4`{dcFRNTU9iB@=1<5 zl!KR*m6Vh$I)i#yG-JmEL%@p`b){Q4lO?zsFC^rp5cAfO}~UNewt*A`o*cCK*DY>% z$_=P%@k|C=zKzTtVtpI{Azj2CEFh1(1dYqe0E#SpBLlfK)+`lQi~~k(^aVy>W1`%X zdQhj0WG@#epZw--iX53@d91_uxK0^sH*a{!z_|M#KiU)>ODUHI^Q&F9luM13^dw4oaD7S#Up837oNkinb!LY)HW`7oqG~O@{{qSH0A1`i zFHt`3YxG!`wN<5*25^;yafJ4B4K4#^QsYAuK~tI3(A3`7H6F)tX zM_*}LFZ0}ueWqsk`4y}7>})9%ivexf{b?XF8_wdn^I~WUjsgc+v70pKAy;#|yg|8R7)>`_(8B=v3>1~_{$F$eFP9=l6a zP&EKlaWBQqk65qT;ofhKhE29zLzQ{6y{>|;f=Q&GDSFoH zhpJU)q6q6FuW`Bydq#u<5aLDMY)%|jh&2P8EOgla7*}L$jcizsuM+YaQOB2$ap87I zJ{fN$k)H?PfbL7zVS14G`Fz450KV2*(#*+bM~a7aQO)_BQJZ{WYBsu%_~ucXVIzNw z>$nf~hUCz*GO^s!Er2?=SW>|RJ{`-Q=SsWjLL9g<=T{l$9gZ|r@@rjRqom4V!z`qb6 zZ74t2Tj>y*mrHJ(ZX6fTUgGncCZu&ye1Cqu>}FK_NG)%FWcM%U+0Xs(%035D=iT6j z2`LPx%yNVM`{O3@qZflXJt@k1OBx$qX+?f%$^dPzo(iwm!%rNK47`|H4?tOq2R1yk zC3U^3(0esU7lr1&7t^1?_qVeVpXH6$#*kha_@avMJ;5O4I!(xaWPVeRly1iY#tE(; zgAibYukRh4?#aeC_GWHGy*34GPy+X@Gz`=j>M@U7IIRba0uNjfObU%Aj2bwBn5F|2 zpB{FrLd}V9HjNsPri4XNAOm)2|WdX7l=F6vF&W((uH(axs8ognP~o}`M$xlk*_+N(E1*$ zuyBSwQcsCiIzILPnoJ_aoob&HZO$tqg{BY+y~E57qB3&q>jZ~O(HG(m!%JTknrz51 zIjN5-jW9rfybadAd|!@*c9#Ac^caswXu`s zI^d0WL^BryAzO$&m^W?slFABSgxT{`JG=EXq(FY_x05B4tDg8;)$Nho4Y(?kxT)dO zLWh}VPN}$+m8Xp&7(0^LOdbfZbzFWN=E@%>Y@Pk8mE;t_~i^!h+%z$o~d`eM%+MBxxOov_HPY=#FFy%o<-0=GKJ z10r?IQ6hn;^jn5t;*Q?o(mn$69;C>MZ?Qn diff --git a/packages/neon/neon_dashboard/test/goldens/widget_without_items.png b/packages/neon/neon_dashboard/test/goldens/widget_without_items.png index 6b0c3927e997d8278db1247d38057b992bb90f7c..2672129e95a16e1449e59cfba15610423b3e1415 100644 GIT binary patch delta 2747 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 LZd(|e{Ez<&x`q}V diff --git a/packages/neon/neon_dashboard/test/widget_test.dart b/packages/neon/neon_dashboard/test/widget_test.dart index 045b6f45..8ed3bc11 100644 --- a/packages/neon/neon_dashboard/test/widget_test.dart +++ b/packages/neon/neon_dashboard/test/widget_test.dart @@ -9,6 +9,7 @@ import 'package:neon/theme.dart'; import 'package:neon/utils.dart'; import 'package:neon/widgets.dart'; import 'package:neon_dashboard/l10n/localizations.dart'; +import 'package:neon_dashboard/src/pages/main.dart'; import 'package:neon_dashboard/src/widgets/widget.dart'; import 'package:neon_dashboard/src/widgets/widget_button.dart'; import 'package:neon_dashboard/src/widgets/widget_item.dart'; @@ -263,9 +264,15 @@ void main() { await tester.pumpWidget( wrapWidget( accountsBloc, - DashboardWidget( - widget: widget, - items: items, + Builder( + builder: (final context) => DashboardWidget( + widget: widget, + children: DashboardMainPage.buildWidgetItems( + context: context, + widget: widget, + items: items, + ).toList(), + ), ), ), ); @@ -299,12 +306,19 @@ void main() { }); testWidgets('Without widgetUrl', (final tester) async { + final widgetEmptyURL = widget.rebuild((final b) => b.widgetUrl = ''); await tester.pumpWidget( wrapWidget( accountsBloc, - DashboardWidget( - widget: widget.rebuild((final b) => b.widgetUrl = ''), - items: items, + Builder( + builder: (final context) => DashboardWidget( + widget: widgetEmptyURL, + children: DashboardMainPage.buildWidgetItems( + context: context, + widget: widgetEmptyURL, + items: items, + ).toList(), + ), ), ), ); @@ -320,12 +334,19 @@ void main() { }); testWidgets('Not round', (final tester) async { + final widgetNotRound = widget.rebuild((final b) => b.itemIconsRound = false); await tester.pumpWidget( wrapWidget( accountsBloc, - DashboardWidget( - widget: widget.rebuild((final b) => b.itemIconsRound = false), - items: items, + Builder( + builder: (final context) => DashboardWidget( + widget: widgetNotRound, + children: DashboardMainPage.buildWidgetItems( + context: context, + widget: widgetNotRound, + items: items, + ).toList(), + ), ), ), ); @@ -346,9 +367,15 @@ void main() { await tester.pumpWidget( wrapWidget( accountsBloc, - DashboardWidget( - widget: widget, - items: items.rebuild((final b) => b.halfEmptyContentMessage = 'Half empty'), + Builder( + builder: (final context) => DashboardWidget( + widget: widget, + children: DashboardMainPage.buildWidgetItems( + context: context, + widget: widget, + items: items.rebuild((final b) => b.halfEmptyContentMessage = 'Half empty'), + ).toList(), + ), ), ), ); @@ -363,9 +390,15 @@ void main() { await tester.pumpWidget( wrapWidget( accountsBloc, - DashboardWidget( - widget: widget, - items: items.rebuild((final b) => b.emptyContentMessage = 'Empty'), + Builder( + builder: (final context) => DashboardWidget( + widget: widget, + children: DashboardMainPage.buildWidgetItems( + context: context, + widget: widget, + items: items.rebuild((final b) => b.emptyContentMessage = 'Empty'), + ).toList(), + ), ), ), ); @@ -380,9 +413,15 @@ void main() { await tester.pumpWidget( wrapWidget( accountsBloc, - DashboardWidget( - widget: widget, - items: null, + Builder( + builder: (final context) => DashboardWidget( + widget: widget, + children: DashboardMainPage.buildWidgetItems( + context: context, + widget: widget, + items: null, + ).toList(), + ), ), ), ); @@ -394,12 +433,19 @@ void main() { }); testWidgets('Without buttons', (final tester) async { + final widgetWithoutButtons = widget.rebuild((final b) => b.buttons.clear()); await tester.pumpWidget( wrapWidget( accountsBloc, - DashboardWidget( - widget: widget.rebuild((final b) => b.buttons.clear()), - items: items, + Builder( + builder: (final context) => DashboardWidget( + widget: widgetWithoutButtons, + children: DashboardMainPage.buildWidgetItems( + context: context, + widget: widgetWithoutButtons, + items: null, + ).toList(), + ), ), ), );