functions.tmpl 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. {{ define "table" }}
  2. {{ $title:= get . "title" }}
  3. {{ $func:= get . "func" }}
  4. {{ $fields:= get . "fields" }}
  5. {{ $struct:= get . "struct" }}
  6. {{ $condition:= get . "condition" | default "" }}
  7. {{ $delete:= get . "delete" }}
  8. <div class="w-full px-4 md:px-0 md:mt-8 mb-16 text-gray-800 leading-normal"
  9. x-data="{{$func}}()"
  10. x-init="$interval(updateItems, 1500)"
  11. >
  12. <!-- Notification toast -->
  13. <div
  14. x-show="open"
  15. class="w-96 p-4 rounded h-32 fixed bottom-4 right-4 transform-gpu transition-transform duration-400 ease"
  16. x-class="success ? 'bg-green-500' : 'bg-red-500'"
  17. x-transition:enter-start="opacity-0 translate-y-full"
  18. x-transition:enter-end="opacity-100 translate-y-0"
  19. x-transition:leave-start="translate-y-0"
  20. x-transition:leave="transition transform ease-in duration-300"
  21. x-transition:leave-end="opacity-0 translate-y-full"
  22. >
  23. <div class="bg-white border-gray-300 dark:border-slate-800 dark:bg-slate-900 border p-3 flex items-start shadow-lg rounded-md space-x-2">
  24. <svg class="flex-shrink-0 h-6 w-6 text-green-400" stroke="currentColor" viewBox="0 0 20 20">
  25. <path stroke-width="1" d="M10.219,1.688c-4.471,0-8.094,3.623-8.094,8.094s3.623,8.094,8.094,8.094s8.094-3.623,8.094-8.094S14.689,1.688,10.219,1.688 M10.219,17.022c-3.994,0-7.242-3.247-7.242-7.241c0-3.994,3.248-7.242,7.242-7.242c3.994,0,7.241,3.248,7.241,7.242C17.46,13.775,14.213,17.022,10.219,17.022 M15.099,7.03c-0.167-0.167-0.438-0.167-0.604,0.002L9.062,12.48l-2.269-2.277c-0.166-0.167-0.437-0.167-0.603,0c-0.166,0.166-0.168,0.437-0.002,0.603l2.573,2.578c0.079,0.08,0.188,0.125,0.3,0.125s0.222-0.045,0.303-0.125l5.736-5.751C15.268,7.466,15.265,7.196,15.099,7.03"></path>
  26. </svg>
  27. <div class="flex-1 space-y-1">
  28. <p class="text-base leading-6 font-medium text-gray-700 dark:text-gray-400" x-text="title"></p>
  29. <p class="text-sm leading-5 text-gray-600 dark:text-gray-400" x-text="message"></p>
  30. </div>
  31. <svg class="flex-shrink-0 h-5 w-5 text-gray-400 cursor-pointer" x-on:click="isShow = false" stroke="currentColor" viewBox="0 0 20 20">
  32. <path stroke-width="1.2" d="M15.898,4.045c-0.271-0.272-0.713-0.272-0.986,0l-4.71,4.711L5.493,4.045c-0.272-0.272-0.714-0.272-0.986,0s-0.272,0.714,0,0.986l4.709,4.711l-4.71,4.711c-0.272,0.271-0.272,0.713,0,0.986c0.136,0.136,0.314,0.203,0.492,0.203c0.179,0,0.357-0.067,0.493-0.203l4.711-4.711l4.71,4.711c0.137,0.136,0.314,0.203,0.494,0.203c0.178,0,0.355-0.067,0.492-0.203c0.273-0.273,0.273-0.715,0-0.986l-4.711-4.711l4.711-4.711C16.172,4.759,16.172,4.317,15.898,4.045z"></path>
  33. </svg>
  34. </div>
  35. </div>
  36. <div class="w-full mt-12 p-3 dark:bg-gray-900 border dark:border-gray-800 rounded shadow">
  37. <div class="border-b bg-white-200 dark:bg-gray-900 dark:border-gray-800 p-3">
  38. <h5 class="font-bold uppercase dark:text-gray-600">{{$title}}</h5>
  39. </div>
  40. <br>
  41. <div class="relative mt-1 ">
  42. <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
  43. <svg class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 20 20"
  44. xmlns="http://www.w3.org/2000/svg">
  45. <path fill-rule="evenodd"
  46. d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
  47. clip-rule="evenodd"></path>
  48. </svg>
  49. </div>
  50. <input
  51. x-ref="searchField"
  52. x-model="search"
  53. x-on:click="viewPage(0)"
  54. x-on:keydown.window.prevent.slash=" viewPage(0), $refs.searchField.focus()"
  55. placeholder="Search..."
  56. type="search"
  57. 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 pl-10 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"
  58. />
  59. </div>
  60. <div class="overflow-auto">
  61. <table class="min-w-full bg-white-200 dark:bg-gray-900">
  62. <thead class="bg-slate-200 dark:bg-gray-800 dark:text-white">
  63. <tr>
  64. {{range $fields}}
  65. <th class="w-1/3 text-left py-3 px-4 uppercase font-semibold text-sm">{{.}}</th>
  66. {{end}}
  67. {{ if ne $delete "" }}
  68. <th class="w-1/3 text-left py-3 px-4 uppercase font-semibold text-sm"></th>
  69. {{ end }}
  70. </tr>
  71. </thead>
  72. <tbody class="text-black dark:text-white">
  73. <template x-for="(d, index) in filtered" :key="index">
  74. <tr
  75. {{ $condition }}
  76. >
  77. {{range $struct}}
  78. <td x-text="{{.}}" class="text-left py-3 px-4"></td>
  79. {{end}}
  80. {{ if ne $delete "" }}
  81. <!-- Action menu -->
  82. <td class="text-left py-3 px-4" >
  83. <button
  84. class="px-3 py-2 rounded"
  85. type="button"
  86. x-on:click="deleteItem({{$delete}})"
  87. >
  88. <i class="fa-solid fa-trash-can"></i>
  89. </button>
  90. </td>
  91. {{ end }}
  92. </tr>
  93. </template>
  94. </tbody>
  95. </table>
  96. <!--Pagination Buttons-->
  97. <div
  98. class="w-full md:w-1/2 mx-auto py-6 flex justify-between items-center"
  99. x-show="pageCount() > 1"
  100. >
  101. <!--First Button-->
  102. <button
  103. x-on:click="viewPage(0)"
  104. :disabled="pageNumber==0"
  105. :class="{ 'disabled cursor-not-allowed text-gray-600' : pageNumber==0 }"
  106. >
  107. <svg
  108. class="h-8 w-8 text-indigo-600"
  109. width="24"
  110. height="24"
  111. viewBox="0 0 24 24"
  112. fill="none"
  113. stroke="currentColor"
  114. stroke-width="2"
  115. stroke-linecap="round"
  116. stroke-linejoin="round"
  117. >
  118. <polygon points="19 20 9 12 19 4 19 20"></polygon>
  119. <line x1="5" y1="19" x2="5" y2="5"></line>
  120. </svg>
  121. </button>
  122. <!--Previous Button-->
  123. <button
  124. x-on:click="prevPage"
  125. :disabled="pageNumber==0"
  126. :class="{ 'disabled cursor-not-allowed text-gray-600' : pageNumber==0 }"
  127. >
  128. <svg
  129. class="h-8 w-8 text-indigo-600"
  130. width="24"
  131. height="24"
  132. viewBox="0 0 24 24"
  133. fill="none"
  134. stroke="currentColor"
  135. stroke-width="2"
  136. stroke-linecap="round"
  137. stroke-linejoin="round"
  138. >
  139. <polyline points="15 18 9 12 15 6"></polyline>
  140. </svg>
  141. </button>
  142. <!-- Display page numbers -->
  143. <template x-for="(page,index) in pages()" :key="page">
  144. <button
  145. class="px-3 py-2 rounded"
  146. :class="{ 'bg-indigo-600 text-white font-bold' : page === pageNumber }"
  147. type="button"
  148. x-on:click="viewPage(page)"
  149. >
  150. <span x-text="page" class="dark:text-white"></span>
  151. </button>
  152. </template>
  153. <!--Next Button-->
  154. <button
  155. x-on:click="nextPage"
  156. :disabled="pageNumber >= pageCount() -1"
  157. :class="{ 'disabled cursor-not-allowed text-gray-600' : pageNumber >= pageCount() -1 }"
  158. >
  159. <svg
  160. class="h-8 w-8 text-indigo-600"
  161. width="24"
  162. height="24"
  163. viewBox="0 0 24 24"
  164. fill="none"
  165. stroke="currentColor"
  166. stroke-width="2"
  167. stroke-linecap="round"
  168. stroke-linejoin="round"
  169. >
  170. <polyline points="9 18 15 12 9 6"></polyline>
  171. </svg>
  172. </button>
  173. <!--Last Button-->
  174. <button
  175. x-on:click="viewPage(Math.ceil(total/size)-1)"
  176. :disabled="pageNumber >= pageCount() -1"
  177. :class="{ 'disabled cursor-not-allowed text-gray-600' : pageNumber >= pageCount() -1 }"
  178. >
  179. <svg
  180. class="h-8 w-8 text-indigo-600"
  181. width="24"
  182. height="24"
  183. viewBox="0 0 24 24"
  184. fill="none"
  185. stroke="currentColor"
  186. stroke-width="2"
  187. stroke-linecap="round"
  188. stroke-linejoin="round"
  189. >
  190. <polygon points="5 4 15 12 5 20 5 4"></polygon>
  191. <line x1="19" y1="5" x2="19" y2="19"></line>
  192. </svg>
  193. </button>
  194. </div>
  195. <!-- /Pagination Buttons-->
  196. </div>
  197. </div>
  198. </div>
  199. {{end}}
  200. {{ define "table_js" }}
  201. {{ $func:= get . "func" }}
  202. {{ $endpoint:= get . "endpoint" }}
  203. {{ $sort:= get . "sort" }}
  204. {{ $delete:= get . "delete" }}
  205. function {{$func}}(){
  206. return {
  207. data: [
  208. ],
  209. open: false,
  210. title: "",
  211. message: "",
  212. success: false,
  213. openToast(title, message, success) {
  214. this.title = title
  215. this.message = message
  216. this.success = success
  217. this.open = true
  218. setTimeout(() => {
  219. this.open = false
  220. }, 5000)
  221. },
  222. {{ if ne $delete "" }}
  223. deleteItem(item) {
  224. fetch('/api/ledger/{{$delete}}/'.concat("",item), {
  225. method: 'DELETE',
  226. });
  227. this.openToast("Delete", "Announcing deletion to the blockchain, please wait", true);
  228. },
  229. {{ end }}
  230. updateItems() {
  231. fetch('/api/{{$endpoint}}')
  232. .then(response => response.json())
  233. .then(data => {
  234. data.sort(sortData("{{$sort}}","asc"));
  235. this.data = data;
  236. } )
  237. },
  238. search: "",
  239. pageNumber: 0,
  240. size: 10,
  241. total: "",
  242. get filtered() {return filter(this, "{{$sort}}") },
  243. //Create array of all pages (for loop to display page numbers)
  244. pages() {
  245. return calcPages(this.pageNumber, this.total, this.size)
  246. },
  247. //Next Page
  248. nextPage() {
  249. this.pageNumber++;
  250. },
  251. //Previous Page
  252. prevPage() {
  253. this.pageNumber--;
  254. },
  255. //Total number of pages
  256. pageCount() {
  257. return Math.ceil(this.total / this.size);
  258. },
  259. //Return the start range of the paginated results
  260. startResults() {
  261. return this.pageNumber * this.size + 1;
  262. },
  263. //Return the end range of the paginated results
  264. endResults() {
  265. return endRes(this)
  266. },
  267. //Link to navigate to page
  268. viewPage(index) {
  269. this.pageNumber = index;
  270. },
  271. };
  272. }
  273. {{end}}
  274. {{ define "menu_entry" }}
  275. {{ $page:= get . "page" }}
  276. {{ $name:= get . "name" }}
  277. {{ $icon:= get . "icon" }}
  278. {{ $anchor:= $page }}
  279. {{ if eq $anchor "" }}
  280. {{ $anchor = "#" }}
  281. {{ end }}
  282. <li class="mr-6 my-2 md:my-0">
  283. <a href="{{$anchor}}"
  284. x-bind:class="page === '{{$page}}' ? 'text-blue-400 border-blue-400 hover:border-blue-400' : 'text-gray-500 dark:hover:text-gray-100 dark:hover:border-violet-900 hover:text-gray-900 border-sky-100 dark:border-sky-900 hover:border-pink-400'"
  285. class="block py-1 md:py-3 pl-1 align-middle no-underline border-b-2">
  286. <i
  287. x-bind:class="page === '{{$page}}' ? 'text-blue-400' : '' "
  288. class="fas {{$icon}} fa-fw mr-3"></i><span class="pb-1 md:pb-0 text-sm">{{$name}}</span>
  289. </a>
  290. </li>
  291. {{ end }}
  292. {{ define "metric_card" }}
  293. {{ $color:= get . "color" }}
  294. {{ $name:= get . "name" }}
  295. {{ $field:= get . "field" }}
  296. {{ $icon:= get . "icon" }}
  297. <div class="w-full md:w-1/2 xl:w-1/3 p-3">
  298. <!--Metric Card-->
  299. <div class="dark:bg-gray-900 bg-white-100 dark:border-gray-800 dark:border-gray-600 border-b-4 rounded shadow p-2">
  300. <div class="flex flex-row items-center">
  301. <div class="flex-shrink pr-4">
  302. <div class="rounded p-3 {{$color}}"><i class="{{$icon}} fa-2x fa-fw fa-inverse"></i></div>
  303. </div>
  304. <div class="flex-1 text-right md:text-center">
  305. <h5 class="font-bold uppercase text-gray-400">{{$name}}</h5>
  306. <h3 class="font-bold text-3xl text-gray-600" x-text="{{$field}}"></h3>
  307. </div>
  308. </div>
  309. </div>
  310. <!--/Metric Card-->
  311. </div>
  312. {{ end }}
  313. {{ define "readme_badge" }}
  314. {{ $url:= get . "url" }}
  315. {{ $text:= get . "text" }}
  316. <div class="px-4 md:px-0 md:mt-8 mb-20 leading-normal " >
  317. <div class="relative " >
  318. <a class="mr-2 bg-sky-300 dark:bg-sky-600 text-white p-2 rounded leading-none items-center absolute top-10 right-1 " href="{{$url}}" target=_blank>
  319. <i class="fa-solid fa-book fa-fw pr-1"></i> {{$text}}
  320. </a>
  321. </div>
  322. </div>
  323. {{end}}