Card.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. namespace Dcat\Admin\Widgets\DataCard;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Widgets\Dropdown;
  5. use Dcat\Admin\Widgets\HasAjaxRequest;
  6. use Dcat\Admin\Widgets\Widget;
  7. use Illuminate\Contracts\Support\Renderable;
  8. use Illuminate\Support\Str;
  9. class Card extends Widget
  10. {
  11. use HasAjaxRequest;
  12. public static $js = [
  13. 'waypoints',
  14. 'jquery.counterup',
  15. ];
  16. public static $css = [
  17. 'waypoints',
  18. 'jquery.counterup',
  19. ];
  20. protected $view = 'admin::widgets.data-card';
  21. protected $options = [
  22. 'title' => null,
  23. 'description' => null,
  24. 'tools' => [],
  25. 'progress' => [],
  26. 'content' => ['left' => '', 'right' => ''],
  27. 'show_tool_shadow' => false,
  28. ];
  29. public function __construct($title = null, $description = null)
  30. {
  31. $this->title($title);
  32. $this->description($description);
  33. $this->class('card-box')
  34. ->style('height:160px')
  35. ->id('smc_'.Str::random(8));
  36. }
  37. public function showToolShadow()
  38. {
  39. $this->options['show_tool_shadow'] = true;
  40. return $this;
  41. }
  42. public function title($title)
  43. {
  44. $this->options['title'] = $title;
  45. return $this;
  46. }
  47. public function description($content)
  48. {
  49. $this->options['description'] = $content;
  50. return $this;
  51. }
  52. /**
  53. * @param $number
  54. *
  55. * @return $this
  56. */
  57. public function number($number)
  58. {
  59. return $this->content("<number>$number</number>");
  60. }
  61. /**
  62. * @param string|\Closure|Renderable $content
  63. * @param string $position
  64. *
  65. * @return $this
  66. */
  67. public function content($content, string $position = 'left')
  68. {
  69. $this->options['content'][$position] = $this->toString($content);
  70. return $this;
  71. }
  72. /**
  73. * @param string|\Closure|Renderable $content
  74. *
  75. * @return $this
  76. */
  77. public function rightContent($content)
  78. {
  79. return $this->content($content, 'right');
  80. }
  81. /**
  82. * @param int $number
  83. * @param string $style
  84. *
  85. * @return $this
  86. */
  87. public function progress($number, $style = 'primary')
  88. {
  89. $this->options['progress'] = [
  90. 'percent' => $number,
  91. 'style' => $style,
  92. ];
  93. return $this;
  94. }
  95. /**
  96. * @param string|\Closure|Renderable $content
  97. *
  98. * @return $this
  99. */
  100. public function tool($content)
  101. {
  102. $this->options['tools'][] = $this->toString($content);
  103. return $this;
  104. }
  105. /**
  106. * @param array $options
  107. * @param \Closure $builder
  108. * @param string|null $defaultLabel
  109. *
  110. * @return $this
  111. */
  112. public function dropdown(array $options, \Closure $builder, ?string $defaultLabel = null)
  113. {
  114. return $this->tool(
  115. Dropdown::make($options)
  116. ->click()
  117. ->button($defaultLabel)
  118. ->buttonClass('btn btn-xs btn-light')
  119. ->map($builder)
  120. );
  121. }
  122. /**
  123. * Setup scripts.
  124. *
  125. * @return string
  126. */
  127. protected function script()
  128. {
  129. if (! $this->allowBuildRequestScript()) {
  130. return;
  131. }
  132. $this->setupFetchScript();
  133. return $this->buildRequestScript();
  134. }
  135. /**
  136. * @return void
  137. */
  138. protected function setupFetchScript()
  139. {
  140. $id = $this->getHtmlAttribute('id');
  141. $this->fetching(
  142. <<<JS
  143. var card = $('#{$id}');
  144. card.loading({style:'bottom:20px'})
  145. JS
  146. );
  147. $this->fetched(
  148. <<<'JS'
  149. if (!response.status) {
  150. return Dcat.error(response.message || 'Server internal error.');
  151. }
  152. var w = (response.progress || 0) + '%', pg = card.find('.progress-bar');
  153. card.loading(false)
  154. card.find('.right-content').html(response.content.right || '');
  155. card.find('.main-content').html(response.content.left || '');
  156. pg.css({width: 0});
  157. setTimeout(function(){ pg.css({width: w});}, 150);
  158. card.find('number').counterUp({time: 550});
  159. JS
  160. );
  161. }
  162. /**
  163. * @return string
  164. */
  165. public function render()
  166. {
  167. $this->script = $this->script();
  168. return parent::render(); // TODO: Change the autogenerated stub
  169. }
  170. /**
  171. * @return array
  172. */
  173. public function buildJsonResponseArray()
  174. {
  175. return [
  176. 'status' => 1,
  177. 'content' => &$this->options['content'],
  178. 'progress' => $this->options['progress']['percent'] ?? 0,
  179. ];
  180. }
  181. /**
  182. * Return JsonResponse instance.
  183. *
  184. * @param array $data
  185. *
  186. * @return \Illuminate\Http\JsonResponse
  187. */
  188. public function toJsonResponse(array $data = [])
  189. {
  190. return response()->json(array_merge($this->buildJsonResponseArray(), $data));
  191. }
  192. }