@dssp/project 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/dist-client/bootstrap.d.ts +0 -0
  2. package/dist-client/bootstrap.js +2 -0
  3. package/dist-client/bootstrap.js.map +1 -0
  4. package/dist-client/index.d.ts +1 -0
  5. package/dist-client/index.js +2 -0
  6. package/dist-client/index.js.map +1 -0
  7. package/dist-client/pages/lib/chatbot-widget.d.ts +53 -0
  8. package/dist-client/pages/lib/chatbot-widget.js +631 -0
  9. package/dist-client/pages/lib/chatbot-widget.js.map +1 -0
  10. package/dist-client/pages/lib/select2-component.d.ts +23 -0
  11. package/dist-client/pages/lib/select2-component.js +181 -0
  12. package/dist-client/pages/lib/select2-component.js.map +1 -0
  13. package/dist-client/pages/lib/waether.d.ts +7 -0
  14. package/dist-client/pages/lib/waether.js +156 -0
  15. package/dist-client/pages/lib/waether.js.map +1 -0
  16. package/dist-client/pages/project/component/pagenation.d.ts +18 -0
  17. package/dist-client/pages/project/component/pagenation.js +142 -0
  18. package/dist-client/pages/project/component/pagenation.js.map +1 -0
  19. package/dist-client/pages/project/component/project-update-header.d.ts +1 -0
  20. package/dist-client/pages/project/component/project-update-header.js +121 -0
  21. package/dist-client/pages/project/component/project-update-header.js.map +1 -0
  22. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.d.ts +1 -0
  23. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.js +308 -0
  24. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.js.map +1 -0
  25. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.d.ts +1 -0
  26. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.js +356 -0
  27. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.js.map +1 -0
  28. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.d.ts +1 -0
  29. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.js +682 -0
  30. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.js.map +1 -0
  31. package/dist-client/pages/project/popup/checklist/task-checklist-view.d.ts +33 -0
  32. package/dist-client/pages/project/popup/checklist/task-checklist-view.js +676 -0
  33. package/dist-client/pages/project/popup/checklist/task-checklist-view.js.map +1 -0
  34. package/dist-client/pages/project/popup/popup-plan-export.d.ts +10 -0
  35. package/dist-client/pages/project/popup/popup-plan-export.js +242 -0
  36. package/dist-client/pages/project/popup/popup-plan-export.js.map +1 -0
  37. package/dist-client/pages/project/popup/popup-plan-upload.d.ts +13 -0
  38. package/dist-client/pages/project/popup/popup-plan-upload.js +265 -0
  39. package/dist-client/pages/project/popup/popup-plan-upload.js.map +1 -0
  40. package/dist-client/pages/project/popup/popup-project-create.d.ts +12 -0
  41. package/dist-client/pages/project/popup/popup-project-create.js +152 -0
  42. package/dist-client/pages/project/popup/popup-project-create.js.map +1 -0
  43. package/dist-client/pages/project/popup/popup-task-upload.d.ts +9 -0
  44. package/dist-client/pages/project/popup/popup-task-upload.js +105 -0
  45. package/dist-client/pages/project/popup/popup-task-upload.js.map +1 -0
  46. package/dist-client/pages/project/project-completed-list.d.ts +23 -0
  47. package/dist-client/pages/project/project-completed-list.js +322 -0
  48. package/dist-client/pages/project/project-completed-list.js.map +1 -0
  49. package/dist-client/pages/project/project-detail.d.ts +47 -0
  50. package/dist-client/pages/project/project-detail.js +1065 -0
  51. package/dist-client/pages/project/project-detail.js.map +1 -0
  52. package/dist-client/pages/project/project-list.d.ts +201 -0
  53. package/dist-client/pages/project/project-list.js +410 -0
  54. package/dist-client/pages/project/project-list.js.map +1 -0
  55. package/dist-client/pages/project/project-plan-management.d.ts +33 -0
  56. package/dist-client/pages/project/project-plan-management.js +492 -0
  57. package/dist-client/pages/project/project-plan-management.js.map +1 -0
  58. package/dist-client/pages/project/project-setting-list.d.ts +31 -0
  59. package/dist-client/pages/project/project-setting-list.js +456 -0
  60. package/dist-client/pages/project/project-setting-list.js.map +1 -0
  61. package/dist-client/pages/project/project-task-list.d.ts +18 -0
  62. package/dist-client/pages/project/project-task-list.js +306 -0
  63. package/dist-client/pages/project/project-task-list.js.map +1 -0
  64. package/dist-client/pages/project/project-task.d.ts +51 -0
  65. package/dist-client/pages/project/project-task.js +692 -0
  66. package/dist-client/pages/project/project-task.js.map +1 -0
  67. package/dist-client/pages/project/project-update.d.ts +81 -0
  68. package/dist-client/pages/project/project-update.js +1477 -0
  69. package/dist-client/pages/project/project-update.js.map +1 -0
  70. package/dist-client/pages/resource/construction-detail-type-popup.d.ts +2 -0
  71. package/dist-client/pages/resource/construction-detail-type-popup.js +197 -0
  72. package/dist-client/pages/resource/construction-detail-type-popup.js.map +1 -0
  73. package/dist-client/pages/resource/construction-type-management.d.ts +34 -0
  74. package/dist-client/pages/resource/construction-type-management.js +214 -0
  75. package/dist-client/pages/resource/construction-type-management.js.map +1 -0
  76. package/dist-client/pages/resource/inspection-drawing-type-management.d.ts +48 -0
  77. package/dist-client/pages/resource/inspection-drawing-type-management.js +234 -0
  78. package/dist-client/pages/resource/inspection-drawing-type-management.js.map +1 -0
  79. package/dist-client/pages/resource/inspection-part-popup.d.ts +2 -0
  80. package/dist-client/pages/resource/inspection-part-popup.js +197 -0
  81. package/dist-client/pages/resource/inspection-part-popup.js.map +1 -0
  82. package/dist-client/pages/resource/resource-importer.d.ts +10 -0
  83. package/dist-client/pages/resource/resource-importer.js +101 -0
  84. package/dist-client/pages/resource/resource-importer.js.map +1 -0
  85. package/dist-client/pages/resource/resource-list-page.d.ts +62 -0
  86. package/dist-client/pages/resource/resource-list-page.js +331 -0
  87. package/dist-client/pages/resource/resource-list-page.js.map +1 -0
  88. package/dist-client/pages/resource/worker-type-management.d.ts +34 -0
  89. package/dist-client/pages/resource/worker-type-management.js +180 -0
  90. package/dist-client/pages/resource/worker-type-management.js.map +1 -0
  91. package/dist-client/pages/task/task-importer.d.ts +10 -0
  92. package/dist-client/pages/task/task-importer.js +101 -0
  93. package/dist-client/pages/task/task-importer.js.map +1 -0
  94. package/dist-client/pages/task/task-list-page.d.ts +62 -0
  95. package/dist-client/pages/task/task-list-page.js +322 -0
  96. package/dist-client/pages/task/task-list-page.js.map +1 -0
  97. package/dist-client/pages/task-resource/task-resource-importer.d.ts +10 -0
  98. package/dist-client/pages/task-resource/task-resource-importer.js +101 -0
  99. package/dist-client/pages/task-resource/task-resource-importer.js.map +1 -0
  100. package/dist-client/pages/task-resource/task-resource-list-page.d.ts +62 -0
  101. package/dist-client/pages/task-resource/task-resource-list-page.js +331 -0
  102. package/dist-client/pages/task-resource/task-resource-list-page.js.map +1 -0
  103. package/dist-client/route.d.ts +1 -0
  104. package/dist-client/route.js +44 -0
  105. package/dist-client/route.js.map +1 -0
  106. package/dist-client/shared/domain-context.d.ts +18 -0
  107. package/dist-client/shared/domain-context.js +28 -0
  108. package/dist-client/shared/domain-context.js.map +1 -0
  109. package/dist-client/tsconfig.tsbuildinfo +1 -0
  110. package/dist-client/viewparts/domain-switch.d.ts +19 -0
  111. package/dist-client/viewparts/domain-switch.js +274 -0
  112. package/dist-client/viewparts/domain-switch.js.map +1 -0
  113. package/dist-server/controllers/export-tasks.d.ts +7 -0
  114. package/dist-server/controllers/export-tasks.js +29 -0
  115. package/dist-server/controllers/export-tasks.js.map +1 -0
  116. package/dist-server/controllers/import-task.d.ts +3 -0
  117. package/dist-server/controllers/import-task.js +113 -0
  118. package/dist-server/controllers/import-task.js.map +1 -0
  119. package/dist-server/controllers/index.d.ts +0 -0
  120. package/dist-server/controllers/index.js +1 -0
  121. package/dist-server/controllers/index.js.map +1 -0
  122. package/dist-server/controllers/parse-excel.d.ts +2 -0
  123. package/dist-server/controllers/parse-excel.js +74 -0
  124. package/dist-server/controllers/parse-excel.js.map +1 -0
  125. package/dist-server/controllers/types.d.ts +18 -0
  126. package/dist-server/controllers/types.js +3 -0
  127. package/dist-server/controllers/types.js.map +1 -0
  128. package/dist-server/index.d.ts +3 -0
  129. package/dist-server/index.js +7 -0
  130. package/dist-server/index.js.map +1 -0
  131. package/dist-server/middlewares/index.d.ts +1 -0
  132. package/dist-server/middlewares/index.js +7 -0
  133. package/dist-server/middlewares/index.js.map +1 -0
  134. package/dist-server/migrations/1723861466413-seed-roles.d.ts +5 -0
  135. package/dist-server/migrations/1723861466413-seed-roles.js +117 -0
  136. package/dist-server/migrations/1723861466413-seed-roles.js.map +1 -0
  137. package/dist-server/migrations/1723861466414-seed-codes.d.ts +5 -0
  138. package/dist-server/migrations/1723861466414-seed-codes.js +150 -0
  139. package/dist-server/migrations/1723861466414-seed-codes.js.map +1 -0
  140. package/dist-server/migrations/1723861476419-seed-resources.d.ts +5 -0
  141. package/dist-server/migrations/1723861476419-seed-resources.js +57 -0
  142. package/dist-server/migrations/1723861476419-seed-resources.js.map +1 -0
  143. package/dist-server/migrations/1723861478420-seed-/bsample-project.d.ts +5 -0
  144. package/dist-server/migrations/1723861478420-seed-/bsample-project.js +68 -0
  145. package/dist-server/migrations/1723861478420-seed-/bsample-project.js.map +1 -0
  146. package/dist-server/migrations/1723861478421-seed-/bsample-tasks.d.ts +5 -0
  147. package/dist-server/migrations/1723861478421-seed-/bsample-tasks.js +189 -0
  148. package/dist-server/migrations/1723861478421-seed-/bsample-tasks.js.map +1 -0
  149. package/dist-server/migrations/index.d.ts +1 -0
  150. package/dist-server/migrations/index.js +12 -0
  151. package/dist-server/migrations/index.js.map +1 -0
  152. package/dist-server/routes.d.ts +1 -0
  153. package/dist-server/routes.js +105 -0
  154. package/dist-server/routes.js.map +1 -0
  155. package/dist-server/service/construction-detail-type/construction-detail-type-mutation.d.ts +6 -0
  156. package/dist-server/service/construction-detail-type/construction-detail-type-mutation.js +56 -0
  157. package/dist-server/service/construction-detail-type/construction-detail-type-mutation.js.map +1 -0
  158. package/dist-server/service/construction-detail-type/construction-detail-type-query.d.ts +9 -0
  159. package/dist-server/service/construction-detail-type/construction-detail-type-query.js +53 -0
  160. package/dist-server/service/construction-detail-type/construction-detail-type-query.js.map +1 -0
  161. package/dist-server/service/construction-detail-type/construction-detail-type-type.d.ts +11 -0
  162. package/dist-server/service/construction-detail-type/construction-detail-type-type.js +43 -0
  163. package/dist-server/service/construction-detail-type/construction-detail-type-type.js.map +1 -0
  164. package/dist-server/service/construction-detail-type/construction-detail-type.d.ts +15 -0
  165. package/dist-server/service/construction-detail-type/construction-detail-type.js +69 -0
  166. package/dist-server/service/construction-detail-type/construction-detail-type.js.map +1 -0
  167. package/dist-server/service/construction-detail-type/index.d.ts +5 -0
  168. package/dist-server/service/construction-detail-type/index.js +9 -0
  169. package/dist-server/service/construction-detail-type/index.js.map +1 -0
  170. package/dist-server/service/construction-type/construction-type-mutation.d.ts +6 -0
  171. package/dist-server/service/construction-type/construction-type-mutation.js +64 -0
  172. package/dist-server/service/construction-type/construction-type-mutation.js.map +1 -0
  173. package/dist-server/service/construction-type/construction-type-query.d.ts +13 -0
  174. package/dist-server/service/construction-type/construction-type-query.js +87 -0
  175. package/dist-server/service/construction-type/construction-type-query.js.map +1 -0
  176. package/dist-server/service/construction-type/construction-type-type.d.ts +12 -0
  177. package/dist-server/service/construction-type/construction-type-type.js +47 -0
  178. package/dist-server/service/construction-type/construction-type-type.js.map +1 -0
  179. package/dist-server/service/construction-type/construction-type.d.ts +19 -0
  180. package/dist-server/service/construction-type/construction-type.js +88 -0
  181. package/dist-server/service/construction-type/construction-type.js.map +1 -0
  182. package/dist-server/service/construction-type/index.d.ts +5 -0
  183. package/dist-server/service/construction-type/index.js +9 -0
  184. package/dist-server/service/construction-type/index.js.map +1 -0
  185. package/dist-server/service/index.d.ts +15 -0
  186. package/dist-server/service/index.js +59 -0
  187. package/dist-server/service/index.js.map +1 -0
  188. package/dist-server/service/inspection-drawing-type/index.d.ts +5 -0
  189. package/dist-server/service/inspection-drawing-type/index.js +9 -0
  190. package/dist-server/service/inspection-drawing-type/index.js.map +1 -0
  191. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-mutation.d.ts +6 -0
  192. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-mutation.js +64 -0
  193. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-mutation.js.map +1 -0
  194. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.d.ts +12 -0
  195. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.js +78 -0
  196. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.js.map +1 -0
  197. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-type.d.ts +10 -0
  198. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-type.js +39 -0
  199. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-type.js.map +1 -0
  200. package/dist-server/service/inspection-drawing-type/inspection-drawing-type.d.ts +16 -0
  201. package/dist-server/service/inspection-drawing-type/inspection-drawing-type.js +72 -0
  202. package/dist-server/service/inspection-drawing-type/inspection-drawing-type.js.map +1 -0
  203. package/dist-server/service/inspection-part/index.d.ts +5 -0
  204. package/dist-server/service/inspection-part/index.js +9 -0
  205. package/dist-server/service/inspection-part/index.js.map +1 -0
  206. package/dist-server/service/inspection-part/inspection-part-mutation.d.ts +6 -0
  207. package/dist-server/service/inspection-part/inspection-part-mutation.js +55 -0
  208. package/dist-server/service/inspection-part/inspection-part-mutation.js.map +1 -0
  209. package/dist-server/service/inspection-part/inspection-part-query.d.ts +10 -0
  210. package/dist-server/service/inspection-part/inspection-part-query.js +66 -0
  211. package/dist-server/service/inspection-part/inspection-part-query.js.map +1 -0
  212. package/dist-server/service/inspection-part/inspection-part-type.d.ts +11 -0
  213. package/dist-server/service/inspection-part/inspection-part-type.js +43 -0
  214. package/dist-server/service/inspection-part/inspection-part-type.js.map +1 -0
  215. package/dist-server/service/inspection-part/inspection-part.d.ts +15 -0
  216. package/dist-server/service/inspection-part/inspection-part.js +69 -0
  217. package/dist-server/service/inspection-part/inspection-part.js.map +1 -0
  218. package/dist-server/service/manager/index.d.ts +7 -0
  219. package/dist-server/service/manager/index.js +11 -0
  220. package/dist-server/service/manager/index.js.map +1 -0
  221. package/dist-server/service/manager/manager-mutation.d.ts +5 -0
  222. package/dist-server/service/manager/manager-mutation.js +39 -0
  223. package/dist-server/service/manager/manager-mutation.js.map +1 -0
  224. package/dist-server/service/manager/manager-query.d.ts +4 -0
  225. package/dist-server/service/manager/manager-query.js +35 -0
  226. package/dist-server/service/manager/manager-query.js.map +1 -0
  227. package/dist-server/service/manager/manager-type.d.ts +15 -0
  228. package/dist-server/service/manager/manager-type.js +62 -0
  229. package/dist-server/service/manager/manager-type.js.map +1 -0
  230. package/dist-server/service/manager/manager.d.ts +8 -0
  231. package/dist-server/service/manager/manager.js +41 -0
  232. package/dist-server/service/manager/manager.js.map +1 -0
  233. package/dist-server/service/project/index.d.ts +5 -0
  234. package/dist-server/service/project/index.js +9 -0
  235. package/dist-server/service/project/index.js.map +1 -0
  236. package/dist-server/service/project/issue-project-code.d.ts +7 -0
  237. package/dist-server/service/project/issue-project-code.js +27 -0
  238. package/dist-server/service/project/issue-project-code.js.map +1 -0
  239. package/dist-server/service/project/project-mutation.d.ts +28 -0
  240. package/dist-server/service/project/project-mutation.js +499 -0
  241. package/dist-server/service/project/project-mutation.js.map +1 -0
  242. package/dist-server/service/project/project-query.d.ts +31 -0
  243. package/dist-server/service/project/project-query.js +307 -0
  244. package/dist-server/service/project/project-query.js.map +1 -0
  245. package/dist-server/service/project/project-type.d.ts +42 -0
  246. package/dist-server/service/project/project-type.js +152 -0
  247. package/dist-server/service/project/project-type.js.map +1 -0
  248. package/dist-server/service/project/project.d.ts +66 -0
  249. package/dist-server/service/project/project.js +247 -0
  250. package/dist-server/service/project/project.js.map +1 -0
  251. package/dist-server/service/resource/index.d.ts +6 -0
  252. package/dist-server/service/resource/index.js +10 -0
  253. package/dist-server/service/resource/index.js.map +1 -0
  254. package/dist-server/service/resource/resource-mutation.d.ts +10 -0
  255. package/dist-server/service/resource/resource-mutation.js +131 -0
  256. package/dist-server/service/resource/resource-mutation.js.map +1 -0
  257. package/dist-server/service/resource/resource-query.d.ts +11 -0
  258. package/dist-server/service/resource/resource-query.js +76 -0
  259. package/dist-server/service/resource/resource-query.js.map +1 -0
  260. package/dist-server/service/resource/resource-type.d.ts +17 -0
  261. package/dist-server/service/resource/resource-type.js +65 -0
  262. package/dist-server/service/resource/resource-type.js.map +1 -0
  263. package/dist-server/service/resource/resource.d.ts +24 -0
  264. package/dist-server/service/resource/resource.js +93 -0
  265. package/dist-server/service/resource/resource.js.map +1 -0
  266. package/dist-server/service/task/index.d.ts +5 -0
  267. package/dist-server/service/task/index.js +9 -0
  268. package/dist-server/service/task/index.js.map +1 -0
  269. package/dist-server/service/task/task-mutation.d.ts +10 -0
  270. package/dist-server/service/task/task-mutation.js +135 -0
  271. package/dist-server/service/task/task-mutation.js.map +1 -0
  272. package/dist-server/service/task/task-query.d.ts +21 -0
  273. package/dist-server/service/task/task-query.js +219 -0
  274. package/dist-server/service/task/task-query.js.map +1 -0
  275. package/dist-server/service/task/task-type.d.ts +31 -0
  276. package/dist-server/service/task/task-type.js +114 -0
  277. package/dist-server/service/task/task-type.js.map +1 -0
  278. package/dist-server/service/task/task.d.ts +35 -0
  279. package/dist-server/service/task/task.js +151 -0
  280. package/dist-server/service/task/task.js.map +1 -0
  281. package/dist-server/service/task-checklist-binding/index.d.ts +5 -0
  282. package/dist-server/service/task-checklist-binding/index.js +9 -0
  283. package/dist-server/service/task-checklist-binding/index.js.map +1 -0
  284. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.d.ts +5 -0
  285. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js +188 -0
  286. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js.map +1 -0
  287. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.d.ts +8 -0
  288. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.js +61 -0
  289. package/dist-server/service/task-checklist-binding/task-checklist-binding-query.js.map +1 -0
  290. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.d.ts +15 -0
  291. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.js +57 -0
  292. package/dist-server/service/task-checklist-binding/task-checklist-binding-type.js.map +1 -0
  293. package/dist-server/service/task-checklist-binding/task-checklist-binding.d.ts +22 -0
  294. package/dist-server/service/task-checklist-binding/task-checklist-binding.js +106 -0
  295. package/dist-server/service/task-checklist-binding/task-checklist-binding.js.map +1 -0
  296. package/dist-server/service/task-resource/index.d.ts +6 -0
  297. package/dist-server/service/task-resource/index.js +10 -0
  298. package/dist-server/service/task-resource/index.js.map +1 -0
  299. package/dist-server/service/task-resource/task-resource-mutation.d.ts +10 -0
  300. package/dist-server/service/task-resource/task-resource-mutation.js +132 -0
  301. package/dist-server/service/task-resource/task-resource-mutation.js.map +1 -0
  302. package/dist-server/service/task-resource/task-resource-query.d.ts +7 -0
  303. package/dist-server/service/task-resource/task-resource-query.js +45 -0
  304. package/dist-server/service/task-resource/task-resource-query.js.map +1 -0
  305. package/dist-server/service/task-resource/task-resource-type.d.ts +17 -0
  306. package/dist-server/service/task-resource/task-resource-type.js +65 -0
  307. package/dist-server/service/task-resource/task-resource-type.js.map +1 -0
  308. package/dist-server/service/task-resource/task-resource.d.ts +13 -0
  309. package/dist-server/service/task-resource/task-resource.js +59 -0
  310. package/dist-server/service/task-resource/task-resource.js.map +1 -0
  311. package/dist-server/service/worker-type/index.d.ts +5 -0
  312. package/dist-server/service/worker-type/index.js +9 -0
  313. package/dist-server/service/worker-type/index.js.map +1 -0
  314. package/dist-server/service/worker-type/worker-type-mutation.d.ts +6 -0
  315. package/dist-server/service/worker-type/worker-type-mutation.js +64 -0
  316. package/dist-server/service/worker-type/worker-type-mutation.js.map +1 -0
  317. package/dist-server/service/worker-type/worker-type-query.d.ts +11 -0
  318. package/dist-server/service/worker-type/worker-type-query.js +73 -0
  319. package/dist-server/service/worker-type/worker-type-query.js.map +1 -0
  320. package/dist-server/service/worker-type/worker-type-type.d.ts +11 -0
  321. package/dist-server/service/worker-type/worker-type-type.js +43 -0
  322. package/dist-server/service/worker-type/worker-type-type.js.map +1 -0
  323. package/dist-server/service/worker-type/worker-type.d.ts +16 -0
  324. package/dist-server/service/worker-type/worker-type.js +77 -0
  325. package/dist-server/service/worker-type/worker-type.js.map +1 -0
  326. package/dist-server/tsconfig.tsbuildinfo +1 -0
  327. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatbot-widget.js","sourceRoot":"","sources":["../../../client/pages/lib/chatbot-widget.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css } from 'lit'\n\n// API 상수\nconst CHATBOT_API_URL = 'https://korea-uni-chat-ui.ettisoft.com/chat'\n\ninterface SourceItem {\n title: string\n url: string\n}\n\ninterface ChatMessage {\n id: string\n text: string\n isUser: boolean\n timestamp: Date\n sources?: SourceItem[]\n}\n\nexport class ChatbotWidget extends LitElement {\n static styles = css`\n :host {\n position: fixed;\n bottom: 40px;\n right: 20px;\n z-index: 1000;\n }\n\n .chatbot-container {\n position: relative;\n }\n\n .chatbot-icon {\n width: 60px;\n height: 60px;\n background: linear-gradient(135deg, var(--md-sys-color-tertiary, #b85d5a) 0%, var(--md-sys-color-primary) 100%);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n transition: all 0.3s ease;\n border: none;\n outline: none;\n }\n\n .chatbot-icon:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 25px rgba(0, 0, 0, 0.2);\n }\n\n .chatbot-icon svg {\n width: 28px;\n height: 28px;\n fill: white;\n }\n\n .chat-window {\n position: absolute;\n bottom: 80px;\n right: 0;\n width: 350px;\n height: 500px;\n background: white;\n border-radius: 20px;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transform: translateY(20px) scale(0.95);\n opacity: 0;\n transition: all 0.3s ease;\n border: 1px solid #e1e5e9;\n pointer-events: none; /* 닫혀있을 때 클릭 차단 해제 */\n }\n\n .chat-window.open {\n transform: translateY(0) scale(1);\n opacity: 1;\n pointer-events: auto; /* 열렸을 때 클릭 가능 */\n }\n\n .chat-header {\n background: linear-gradient(135deg, var(--md-sys-color-tertiary, #b85d5a) 0%, var(--md-sys-color-primary) 100%);\n color: white;\n padding: 15px 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .chat-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n }\n\n .close-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n font-size: 32px;\n padding: 0;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n transition: background-color 0.2s ease;\n }\n\n .close-btn:hover {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n .messages-container {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n display: flex;\n flex-direction: column;\n gap: 15px;\n }\n\n .message {\n display: flex;\n align-items: flex-end;\n gap: 10px;\n max-width: 80%;\n }\n\n .message.user {\n align-self: flex-end;\n flex-direction: row-reverse;\n }\n\n .message.bot {\n align-self: flex-start;\n }\n\n .message-bubble {\n padding: 12px 16px;\n border-radius: 18px;\n font-size: 14px;\n line-height: 1.4;\n word-wrap: break-word;\n position: relative;\n }\n\n .message.user .message-bubble {\n background: linear-gradient(135deg, var(--md-sys-color-tertiary, #b85d5a) 0%, var(--md-sys-color-primary) 100%);\n color: white;\n border-bottom-right-radius: 4px;\n }\n\n .message.bot .message-bubble {\n background: #f1f3f4;\n color: #333;\n border-bottom-left-radius: 4px;\n }\n\n .message-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n flex-shrink: 0;\n }\n\n .message.user .message-avatar {\n background: linear-gradient(135deg, var(--md-sys-color-tertiary, #b85d5a) 0%, var(--md-sys-color-primary) 100%);\n color: white;\n }\n\n .message.bot .message-avatar {\n background: #e8eaf0;\n color: #666;\n }\n\n .input-container {\n padding: 20px;\n border-top: 1px solid #e1e5e9;\n display: flex;\n gap: 10px;\n align-items: center;\n }\n\n .message-input {\n flex: 1;\n border: 1px solid #e1e5e9;\n border-radius: 25px;\n padding: 12px 16px;\n font-size: 14px;\n outline: none;\n transition: border-color 0.2s ease;\n }\n\n .message-input:focus {\n border-color: var(--md-sys-color-primary);\n }\n\n .send-btn {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(135deg, var(--md-sys-color-tertiary, #b85d5a) 0%, var(--md-sys-color-primary) 100%);\n border: none;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n }\n\n .send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n }\n\n .send-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .loading-indicator {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #666;\n font-size: 12px;\n }\n\n .loading-dots {\n display: flex;\n gap: 4px;\n }\n\n .loading-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--md-sys-color-primary);\n animation: loading 1.4s infinite ease-in-out;\n }\n\n .loading-dot:nth-child(1) {\n animation-delay: -0.32s;\n }\n .loading-dot:nth-child(2) {\n animation-delay: -0.16s;\n }\n\n @keyframes loading {\n 0%,\n 80%,\n 100% {\n transform: scale(0);\n }\n 40% {\n transform: scale(1);\n }\n }\n\n /* 스크롤바 스타일링 */\n .messages-container::-webkit-scrollbar {\n width: 6px;\n }\n\n .messages-container::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 3px;\n }\n\n .messages-container::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 3px;\n }\n\n .messages-container::-webkit-scrollbar-thumb:hover {\n background: #a8a8a8;\n }\n\n /* 근거 버튼 */\n .evidence-btn {\n margin-top: 8px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n border: 1px solid #d6daf0;\n background: #ffffff;\n color: #3b4cca;\n border-radius: 14px;\n padding: 6px 10px;\n font-size: 12px;\n cursor: pointer;\n transition:\n background-color 0.2s ease,\n border-color 0.2s ease;\n }\n\n .evidence-btn:hover {\n background-color: #f4f6ff;\n border-color: #c2c8ef;\n }\n\n /* 오버레이 */\n .overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.35);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s ease;\n z-index: 1100; /* 챗봇보다 위 */\n }\n\n .overlay.open {\n opacity: 1;\n pointer-events: auto;\n }\n\n .overlay-panel {\n width: min(520px, calc(100vw - 40px));\n max-height: min(70vh, 560px);\n background: #ffffff;\n border-radius: 14px;\n box-shadow: 0 18px 60px rgba(0, 0, 0, 0.18);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .overlay-header {\n padding: 14px 16px;\n background: linear-gradient(135deg, var(--md-sys-color-tertiary, #b85d5a) 0%, var(--md-sys-color-primary) 100%);\n color: #ffffff;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .overlay-title {\n font-weight: 600;\n font-size: 16px;\n }\n\n .overlay-close {\n background: none;\n border: none;\n color: #ffffff;\n font-size: 26px;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n cursor: pointer;\n }\n\n .overlay-body {\n padding: 12px 16px 16px 16px;\n overflow-y: auto;\n }\n\n .source-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .source-item {\n border: 1px solid #e6e9f2;\n border-radius: 10px;\n padding: 10px 12px;\n background: #f9fafc;\n }\n\n .source-link {\n color: #1e3a8a;\n text-decoration: none;\n display: block;\n word-break: break-all;\n }\n\n .source-link:hover {\n text-decoration: underline;\n }\n `\n\n static get properties() {\n return {\n isOpen: { type: Boolean },\n messages: { type: Array },\n inputValue: { type: String },\n isLoading: { type: Boolean },\n isSourcesOpen: { type: Boolean },\n currentSources: { type: Array }\n }\n }\n\n isOpen = false\n messages: ChatMessage[] = []\n inputValue = ''\n isLoading = false\n isSourcesOpen = false\n currentSources: SourceItem[] = []\n\n render() {\n return html`\n <div class=\"chatbot-container\">\n <!-- 챗봇 아이콘 -->\n <button class=\"chatbot-icon\" @click=\"${this.toggleChat}\">\n <svg viewBox=\"0 0 24 24\">\n <path\n d=\"M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4l4 4 4-4h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z\"\n />\n </svg>\n </button>\n\n <!-- 대화창 -->\n <div class=\"chat-window ${this.isOpen ? 'open' : ''}\">\n <!-- 헤더 -->\n <div class=\"chat-header\">\n <h3>챗봇 도우미</h3>\n <button class=\"close-btn\" @click=\"${this.toggleChat}\">×</button>\n </div>\n\n <!-- 메시지 영역 -->\n <div class=\"messages-container\">\n ${this.messages.length === 0\n ? html`\n <div class=\"message bot\">\n <div class=\"message-avatar\">🤖</div>\n <div class=\"message-bubble\">안녕하세요! 무엇을 도와드릴까요?</div>\n </div>\n `\n : ''}\n ${this.messages.map(\n message => html`\n <div class=\"message ${message.isUser ? 'user' : 'bot'}\">\n <div class=\"message-avatar\">${message.isUser ? '👤' : '🤖'}</div>\n <div class=\"message-bubble\">\n ${message.text}\n ${!message.isUser && message.sources && message.sources.length\n ? html`\n <div>\n <button class=\"evidence-btn\" @click=\"${() => this.openSourcesOverlay(message.sources || [])}\">\n 근거 ${message.sources.length}개 보기\n </button>\n </div>\n `\n : ''}\n </div>\n </div>\n `\n )}\n ${this.isLoading\n ? html`\n <div class=\"message bot\">\n <div class=\"message-avatar\">🤖</div>\n <div class=\"message-bubble\">\n <div class=\"loading-indicator\">\n <span>답변 중</span>\n <div class=\"loading-dots\">\n <div class=\"loading-dot\"></div>\n <div class=\"loading-dot\"></div>\n <div class=\"loading-dot\"></div>\n </div>\n </div>\n </div>\n </div>\n `\n : ''}\n </div>\n\n <!-- 입력 영역 -->\n <div class=\"input-container\">\n <input\n class=\"message-input\"\n type=\"text\"\n placeholder=\"메시지를 입력하세요...\"\n .value=\"${this.inputValue}\"\n @input=\"${(e: Event) => (this.inputValue = (e.target as HTMLInputElement).value)}\"\n @keypress=\"${this.handleKeyPress}\"\n ?disabled=\"${this.isLoading}\"\n />\n <button class=\"send-btn\" @click=\"${this.sendMessage}\" ?disabled=\"${this.isLoading || !this.inputValue.trim()}\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n </button>\n </div>\n </div>\n <!-- 근거 오버레이 -->\n <div class=\"overlay ${this.isSourcesOpen ? 'open' : ''}\" @click=\"${this.closeSourcesOverlay}\">\n <div class=\"overlay-panel\" @click=\"${(e: Event) => e.stopPropagation()}\">\n <div class=\"overlay-header\">\n <div class=\"overlay-title\">근거 ${this.currentSources.length}개</div>\n <button class=\"overlay-close\" @click=\"${this.closeSourcesOverlay}\">×</button>\n </div>\n <div class=\"overlay-body\">\n <ul class=\"source-list\">\n ${this.currentSources.map(\n (s, idx) =>\n html` <li class=\"source-item\">\n <a class=\"source-link\" href=\"${s.url}\" target=\"_blank\" rel=\"noopener noreferrer\"\n >[#${idx + 1}] ${s.title}</a\n >\n </li>`\n )}\n </ul>\n </div>\n </div>\n </div>\n </div>\n `\n }\n\n private boundHandleEscapeKey = this.handleEscapeKey.bind(this)\n\n connectedCallback() {\n super.connectedCallback()\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n // 컴포넌트가 제거될 때 이벤트 리스너 정리\n document.removeEventListener('keydown', this.boundHandleEscapeKey)\n }\n\n handleEscapeKey(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n if (this.isSourcesOpen) {\n this.isSourcesOpen = false\n } else if (this.isOpen) {\n this.isOpen = false\n }\n }\n }\n\n toggleChat() {\n this.isOpen = !this.isOpen\n if (this.isOpen) {\n // 챗봇이 열릴 때 ESC 키 이벤트 리스너 추가\n document.addEventListener('keydown', this.boundHandleEscapeKey)\n // 챗봇이 열릴 때 스크롤을 맨 아래로\n this.requestUpdate()\n setTimeout(() => this.scrollToBottom(), 100)\n } else {\n // 챗봇이 닫힐 때 ESC 키 이벤트 리스너 제거\n document.removeEventListener('keydown', this.boundHandleEscapeKey)\n this.isSourcesOpen = false\n this.currentSources = []\n }\n }\n\n scrollToBottom() {\n const messagesContainer = this.shadowRoot?.querySelector('.messages-container') as HTMLElement\n if (messagesContainer) {\n messagesContainer.scrollTop = messagesContainer.scrollHeight\n }\n }\n\n async sendMessage() {\n if (!this.inputValue.trim() || this.isLoading) return\n\n const userMessage: ChatMessage = {\n id: Date.now().toString(),\n text: this.inputValue.trim(),\n isUser: true,\n timestamp: new Date()\n }\n\n this.messages = [...this.messages, userMessage]\n const messageText = this.inputValue.trim()\n this.inputValue = ''\n this.isLoading = true\n\n // 사용자 메시지 추가 후 스크롤을 맨 아래로\n setTimeout(() => this.scrollToBottom(), 50)\n\n // 포커스 유지를 위해 input 요소 참조 저장\n const input = this.shadowRoot?.querySelector('.message-input') as HTMLInputElement\n\n try {\n // API 호출\n const response = await fetch(CHATBOT_API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({ query: messageText, top_k: 6 })\n })\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`)\n }\n\n const data = await response.json()\n\n const botMessage: ChatMessage = {\n id: (Date.now() + 1).toString(),\n text: data?.answer?.trim() || '죄송합니다. 응답을 처리할 수 없습니다.',\n isUser: false,\n timestamp: new Date(),\n sources: data?.sources || []\n }\n\n this.messages = [...this.messages, botMessage]\n // 봇 메시지 추가 후 스크롤을 맨 아래로\n setTimeout(() => this.scrollToBottom(), 50)\n } catch (error) {\n const errorMessage: ChatMessage = {\n id: (Date.now() + 1).toString(),\n text: '죄송합니다. 일시적인 오류가 발생했습니다. 잠시 후 다시 시도해주세요.',\n isUser: false,\n timestamp: new Date()\n }\n this.messages = [...this.messages, errorMessage]\n // 에러 메시지 추가 후 스크롤을 맨 아래로\n setTimeout(() => this.scrollToBottom(), 50)\n } finally {\n this.isLoading = false\n // 로딩 완료 후 포커스 복원\n setTimeout(() => {\n if (input) {\n input.focus()\n }\n }, 100)\n }\n }\n\n openSourcesOverlay(sources: SourceItem[]) {\n if (!sources || sources.length === 0) return\n this.currentSources = sources\n this.isSourcesOpen = true\n }\n\n closeSourcesOverlay() {\n this.isSourcesOpen = false\n this.currentSources = []\n }\n\n handleKeyPress(event: KeyboardEvent) {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n this.sendMessage()\n }\n }\n}\n\ncustomElements.define('chatbot-widget', ChatbotWidget)\n"]}
@@ -0,0 +1,23 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class Select2Component extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ placeholder: string;
5
+ options: Array<{
6
+ name: string;
7
+ value: string;
8
+ }>;
9
+ selectedValues: string[];
10
+ showOptions: boolean;
11
+ get selectedItems(): ({
12
+ name: string;
13
+ value: string;
14
+ } | undefined)[];
15
+ render(): import("lit-html").TemplateResult<1>;
16
+ connectedCallback(): void;
17
+ disconnectedCallback(): void;
18
+ private _handleOutsideClick;
19
+ private _toggleOptions;
20
+ private _handleSelect;
21
+ private _handleRemove;
22
+ private _dispatchEvent;
23
+ }
@@ -0,0 +1,181 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { LitElement, html, css } from 'lit';
3
+ import { customElement, property, state } from 'lit/decorators.js';
4
+ let Select2Component = class Select2Component extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.placeholder = '';
8
+ this.options = [];
9
+ this.selectedValues = [];
10
+ this.showOptions = false;
11
+ this._handleOutsideClick = (event) => {
12
+ const path = event.composedPath();
13
+ if (!path.includes(this)) {
14
+ this.showOptions = false;
15
+ }
16
+ };
17
+ }
18
+ get selectedItems() {
19
+ return this.selectedValues.map(id => this.options.find(option => option.value === id)).filter(Boolean);
20
+ }
21
+ render() {
22
+ return html `
23
+ <div select-container>
24
+ <div tags @click="${this._toggleOptions}">${this.placeholder}</div>
25
+ ${this.showOptions
26
+ ? html `
27
+ <div options>
28
+ ${this.options.map(option => html `
29
+ <div
30
+ option
31
+ ?selected=${this.selectedValues.includes(option.value)}
32
+ @click=${() => this._handleSelect(option.value)}
33
+ >
34
+ ${option.name}
35
+ </div>
36
+ `)}
37
+ </div>
38
+ `
39
+ : ''}
40
+ </div>
41
+
42
+ <div selected-tags>
43
+ ${this.selectedItems.map((tag) => html `
44
+ <div tag @click=${() => this._handleRemove(tag.value)}>
45
+ ${tag.name}
46
+ <span tag-close>&times;</span>
47
+ </div>
48
+ `)}
49
+ </div>
50
+ `;
51
+ }
52
+ connectedCallback() {
53
+ super.connectedCallback();
54
+ document.addEventListener('click', this._handleOutsideClick);
55
+ }
56
+ disconnectedCallback() {
57
+ super.disconnectedCallback();
58
+ document.removeEventListener('click', this._handleOutsideClick);
59
+ }
60
+ _toggleOptions() {
61
+ this.showOptions = !this.showOptions;
62
+ }
63
+ _handleSelect(optionValue) {
64
+ if (this.selectedValues.includes(optionValue)) {
65
+ // 이미 선택된 옵션을 선택한 경우 해제
66
+ this.selectedValues = this.selectedValues.filter(value => value !== optionValue);
67
+ }
68
+ else {
69
+ // 선택되지 않은 옵션 추가
70
+ this.selectedValues = [...this.selectedValues, optionValue];
71
+ }
72
+ this.showOptions = false;
73
+ this._dispatchEvent(this.selectedValues);
74
+ }
75
+ _handleRemove(tagValue) {
76
+ this.selectedValues = this.selectedValues.filter(value => value !== tagValue);
77
+ this._dispatchEvent(this.selectedValues);
78
+ }
79
+ _dispatchEvent(selectedValues) {
80
+ this.dispatchEvent(new CustomEvent('selection-changed', {
81
+ detail: { selectedValues }, // ID 배열을 부모로 전달
82
+ bubbles: true,
83
+ composed: true
84
+ }));
85
+ }
86
+ };
87
+ Select2Component.styles = css `
88
+ div[select-container] {
89
+ position: relative;
90
+ border: 1px solid rgba(51, 51, 51, 0.2);
91
+ border-radius: 5px;
92
+ padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);
93
+ font-size: 14px;
94
+ color: var(--md-sys-color-primary);
95
+ }
96
+ div[select-container]:focus {
97
+ border: 1px solid #1f7fd9;
98
+ }
99
+
100
+ div[dropdown] {
101
+ border: 1px solid #ccc;
102
+ padding: var(--spacing-small, 4px);
103
+ cursor: pointer;
104
+ }
105
+
106
+ div[options] {
107
+ position: absolute;
108
+ left: 0;
109
+ top: 30px;
110
+ min-width: 50%;
111
+ border: 1px solid #ccc;
112
+ background-color: var(--md-sys-color-surface-tint);
113
+ color: var(--md-sys-color-on-primary);
114
+ max-height: 150px;
115
+ overflow-y: auto;
116
+ display: block;
117
+ z-index: 1;
118
+ }
119
+
120
+ div[option] {
121
+ padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);
122
+ cursor: pointer;
123
+ border-bottom: 1px solid rgba(0, 0, 0, 0.4);
124
+ }
125
+ div[option]:last-child {
126
+ border-bottom: none;
127
+ }
128
+
129
+ div[option]:hover {
130
+ background-color: var(--md-sys-color-tertiary-container);
131
+ }
132
+
133
+ div[option][selected] {
134
+ background-color: var(--md-sys-color-tertiary-container);
135
+ font-weight: bold;
136
+ color: var(--md-sys-color-on-primary);
137
+ }
138
+
139
+ div[selected-tags] {
140
+ display: flex;
141
+ flex-wrap: wrap;
142
+ gap: var(--spacing-small, 4px);
143
+ margin-top: var(--spacing-small, 4px);
144
+ }
145
+
146
+ div[tag] {
147
+ background-color: #2e79be;
148
+ color: white;
149
+ padding: var(--spacing-tiny, 2px) var(--spacing-medium, 8px);
150
+ border-radius: 20px;
151
+ font-size: 12px;
152
+ display: inline-flex;
153
+ align-items: center;
154
+ cursor: pointer;
155
+ }
156
+
157
+ span[tag-close] {
158
+ margin-left: var(--spacing-small, 4px);
159
+ }
160
+ `;
161
+ __decorate([
162
+ property({ type: String }),
163
+ __metadata("design:type", String)
164
+ ], Select2Component.prototype, "placeholder", void 0);
165
+ __decorate([
166
+ property({ type: Array }),
167
+ __metadata("design:type", Array)
168
+ ], Select2Component.prototype, "options", void 0);
169
+ __decorate([
170
+ property({ type: Array }),
171
+ __metadata("design:type", Array)
172
+ ], Select2Component.prototype, "selectedValues", void 0);
173
+ __decorate([
174
+ state(),
175
+ __metadata("design:type", Boolean)
176
+ ], Select2Component.prototype, "showOptions", void 0);
177
+ Select2Component = __decorate([
178
+ customElement('select2-component')
179
+ ], Select2Component);
180
+ export { Select2Component };
181
+ //# sourceMappingURL=select2-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select2-component.js","sourceRoot":"","sources":["../../../client/pages/lib/select2-component.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\n@customElement('select2-component')\nexport class Select2Component extends LitElement {\n static styles = css`\n div[select-container] {\n position: relative;\n border: 1px solid rgba(51, 51, 51, 0.2);\n border-radius: 5px;\n padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n font-size: 14px;\n color: var(--md-sys-color-primary);\n }\n div[select-container]:focus {\n border: 1px solid #1f7fd9;\n }\n\n div[dropdown] {\n border: 1px solid #ccc;\n padding: var(--spacing-small, 4px);\n cursor: pointer;\n }\n\n div[options] {\n position: absolute;\n left: 0;\n top: 30px;\n min-width: 50%;\n border: 1px solid #ccc;\n background-color: var(--md-sys-color-surface-tint);\n color: var(--md-sys-color-on-primary);\n max-height: 150px;\n overflow-y: auto;\n display: block;\n z-index: 1;\n }\n\n div[option] {\n padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n cursor: pointer;\n border-bottom: 1px solid rgba(0, 0, 0, 0.4);\n }\n div[option]:last-child {\n border-bottom: none;\n }\n\n div[option]:hover {\n background-color: var(--md-sys-color-tertiary-container);\n }\n\n div[option][selected] {\n background-color: var(--md-sys-color-tertiary-container);\n font-weight: bold;\n color: var(--md-sys-color-on-primary);\n }\n\n div[selected-tags] {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-small, 4px);\n margin-top: var(--spacing-small, 4px);\n }\n\n div[tag] {\n background-color: #2e79be;\n color: white;\n padding: var(--spacing-tiny, 2px) var(--spacing-medium, 8px);\n border-radius: 20px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n }\n\n span[tag-close] {\n margin-left: var(--spacing-small, 4px);\n }\n `\n\n @property({ type: String }) placeholder: string = ''\n @property({ type: Array }) options: Array<{ name: string; value: string }> = []\n @property({ type: Array }) selectedValues: string[] = []\n\n @state() showOptions: boolean = false\n\n get selectedItems() {\n return this.selectedValues.map(id => this.options.find(option => option.value === id)).filter(Boolean)\n }\n\n render() {\n return html`\n <div select-container>\n <div tags @click=\"${this._toggleOptions}\">${this.placeholder}</div>\n ${this.showOptions\n ? html`\n <div options>\n ${this.options.map(\n option => html`\n <div\n option\n ?selected=${this.selectedValues.includes(option.value)}\n @click=${() => this._handleSelect(option.value)}\n >\n ${option.name}\n </div>\n `\n )}\n </div>\n `\n : ''}\n </div>\n\n <div selected-tags>\n ${this.selectedItems.map(\n (tag: any) => html`\n <div tag @click=${() => this._handleRemove(tag.value)}>\n ${tag!.name}\n <span tag-close>&times;</span>\n </div>\n `\n )}\n </div>\n `\n }\n\n connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._handleOutsideClick)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._handleOutsideClick)\n }\n\n private _handleOutsideClick = (event: MouseEvent) => {\n const path = event.composedPath()\n if (!path.includes(this)) {\n this.showOptions = false\n }\n }\n\n private _toggleOptions() {\n this.showOptions = !this.showOptions\n }\n\n private _handleSelect(optionValue: string) {\n if (this.selectedValues.includes(optionValue)) {\n // 이미 선택된 옵션을 선택한 경우 해제\n this.selectedValues = this.selectedValues.filter(value => value !== optionValue)\n } else {\n // 선택되지 않은 옵션 추가\n this.selectedValues = [...this.selectedValues, optionValue]\n }\n\n this.showOptions = false\n this._dispatchEvent(this.selectedValues)\n }\n\n private _handleRemove(tagValue: string) {\n this.selectedValues = this.selectedValues.filter(value => value !== tagValue)\n this._dispatchEvent(this.selectedValues)\n }\n\n private _dispatchEvent(selectedValues: string[]) {\n this.dispatchEvent(\n new CustomEvent('selection-changed', {\n detail: { selectedValues }, // ID 배열을 부모로 전달\n bubbles: true,\n composed: true\n })\n )\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ export default function _getWeather(latitude: number, longitude: number): Promise<{
2
+ rain: number;
3
+ temperature: number;
4
+ humidity: number;
5
+ windDirection: string;
6
+ windSpeed: number;
7
+ }>;
@@ -0,0 +1,156 @@
1
+ const API_KEY = '9epdR01s19phfu%2B3%2F0elTxTi92Nibl3qEO1HSm2QydrWOlrDqyNn9qzeQRJ3jPOh3hV8TesHg1L%2BQ9D6UOPmWQ%3D%3D';
2
+ const URL = 'https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst';
3
+ const NUM_OF_ROWS = 12;
4
+ const DATA_TYPE = 'JSON';
5
+ export default async function _getWeather(latitude, longitude) {
6
+ var _a;
7
+ const { nx, ny } = _getIndexByLatAndLong(latitude, longitude);
8
+ const { base_date, base_time } = _getTodayAndHour();
9
+ const result = await fetch(`${URL}?serviceKey=${API_KEY}&base_date=${base_date}&base_time=${base_time}&nx=${nx}&ny=${ny}&pageNo=1&numOfRows=${NUM_OF_ROWS}&dataType=${DATA_TYPE}`);
10
+ let rain = 0;
11
+ let temperature = 0;
12
+ let humidity = 0;
13
+ let windDirection = '';
14
+ let windSpeed = 0;
15
+ if (result.status == 200) {
16
+ let weather = await result.json().then(data => { var _a; return (_a = data === null || data === void 0 ? void 0 : data.response) === null || _a === void 0 ? void 0 : _a.body; });
17
+ weather = (_a = weather === null || weather === void 0 ? void 0 : weather.items) === null || _a === void 0 ? void 0 : _a.item;
18
+ for (let key in weather) {
19
+ const data = (weather === null || weather === void 0 ? void 0 : weather[key]) || {};
20
+ if (data.category === 'POP') {
21
+ rain = data.fcstValue;
22
+ }
23
+ if (data.category === 'REH') {
24
+ humidity = data.fcstValue;
25
+ }
26
+ if (data.category === 'TMP') {
27
+ temperature = data.fcstValue;
28
+ }
29
+ if (data.category === 'VEC') {
30
+ windDirection = _getWindDirectionByValue(data.fcstValue);
31
+ }
32
+ if (data.category === 'WSD') {
33
+ windSpeed = data.fcstValue;
34
+ }
35
+ }
36
+ console.log('weather :', weather);
37
+ }
38
+ return { rain, temperature, humidity, windDirection, windSpeed };
39
+ }
40
+ const RE = 6371.00877; // 지구 반경(km)
41
+ const GRID = 5.0; // 격자 간격(km)
42
+ const SLAT1 = 30.0; // 투영 위도1(degree)
43
+ const SLAT2 = 60.0; // 투영 위도2(degree)
44
+ const OLON = 126.0; // 기준점 경도(degree)
45
+ const OLAT = 38.0; // 기준점 위도(degree)
46
+ const XO = 43; // 기준점 X좌표(GRID)
47
+ const YO = 136; // 기1준점 Y좌표(GRID)
48
+ // 위경도 -> 기상청 좌표
49
+ function _getIndexByLatAndLong(latitude, longitude) {
50
+ const DEGRAD = Math.PI / 180.0;
51
+ const re = RE / GRID;
52
+ const slat1 = SLAT1 * DEGRAD;
53
+ const slat2 = SLAT2 * DEGRAD;
54
+ const olon = OLON * DEGRAD;
55
+ const olat = OLAT * DEGRAD;
56
+ let sn = Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5);
57
+ sn = Math.log(Math.cos(slat1) / Math.cos(slat2)) / Math.log(sn);
58
+ let sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);
59
+ sf = (Math.pow(sf, sn) * Math.cos(slat1)) / sn;
60
+ let ro = Math.tan(Math.PI * 0.25 + olat * 0.5);
61
+ ro = (re * sf) / Math.pow(ro, sn);
62
+ let ra = Math.tan(Math.PI * 0.25 + latitude * DEGRAD * 0.5);
63
+ ra = (re * sf) / Math.pow(ra, sn);
64
+ let theta = longitude * DEGRAD - olon;
65
+ if (theta > Math.PI)
66
+ theta -= 2.0 * Math.PI;
67
+ if (theta < -Math.PI)
68
+ theta += 2.0 * Math.PI;
69
+ theta *= sn;
70
+ return {
71
+ nx: Math.floor(ra * Math.sin(theta) + XO + 0.5),
72
+ ny: Math.floor(ro - ra * Math.cos(theta) + YO + 0.5),
73
+ latitude,
74
+ longitude
75
+ };
76
+ }
77
+ function _getTodayAndHour() {
78
+ const now = new Date();
79
+ const todayDate = now.toISOString().slice(0, 10).replace(/-/g, '');
80
+ const yesterday = new Date(now);
81
+ yesterday.setDate(yesterday.getDate() - 1);
82
+ const yesterdayDate = yesterday.toISOString().slice(0, 10).replace(/-/g, '');
83
+ // 1일 총 8번 데이터가 업데이트 된다. (0200, 0500, 0800, 1100, 1400, 1700, 2000, 2300)
84
+ let base_date;
85
+ let base_time;
86
+ if (now.getHours() < 2 || (now.getHours() === 2 && now.getMinutes() <= 10)) {
87
+ base_date = yesterdayDate;
88
+ base_time = '2300';
89
+ }
90
+ else if (now.getHours() < 5 || (now.getHours() === 5 && now.getMinutes() <= 10)) {
91
+ base_date = todayDate;
92
+ base_time = '0200';
93
+ }
94
+ else if (now.getHours() < 8 || (now.getHours() === 8 && now.getMinutes() <= 10)) {
95
+ base_date = todayDate;
96
+ base_time = '0500';
97
+ }
98
+ else if (now.getHours() <= 11 || now.getMinutes() <= 10) {
99
+ base_date = todayDate;
100
+ base_time = '0800';
101
+ }
102
+ else if (now.getHours() < 14 || (now.getHours() === 14 && now.getMinutes() <= 10)) {
103
+ base_date = todayDate;
104
+ base_time = '1100';
105
+ }
106
+ else if (now.getHours() < 17 || (now.getHours() === 17 && now.getMinutes() <= 10)) {
107
+ base_date = todayDate;
108
+ base_time = '1400';
109
+ }
110
+ else if (now.getHours() < 20 || (now.getHours() === 20 && now.getMinutes() <= 10)) {
111
+ base_date = todayDate;
112
+ base_time = '1700';
113
+ }
114
+ else if (now.getHours() < 23 || (now.getHours() === 23 && now.getMinutes() <= 10)) {
115
+ base_date = todayDate;
116
+ base_time = '2000';
117
+ }
118
+ else {
119
+ base_date = todayDate;
120
+ base_time = '2300';
121
+ }
122
+ return { base_time, base_date };
123
+ }
124
+ const windTable = {
125
+ 0: 'N',
126
+ 1: 'NNE',
127
+ 2: 'NE',
128
+ 3: 'ENE',
129
+ 4: 'E',
130
+ 5: 'ESE',
131
+ 6: 'SE',
132
+ 7: 'SSE',
133
+ 8: 'S',
134
+ 9: 'SSW',
135
+ 10: 'SW',
136
+ 11: 'WSW',
137
+ 12: 'W',
138
+ 13: 'WNW',
139
+ 14: 'NW',
140
+ 15: 'NNW',
141
+ 16: 'N'
142
+ };
143
+ const directoinMapping = {
144
+ N: '북',
145
+ S: '남',
146
+ E: '동',
147
+ W: '서'
148
+ };
149
+ function _getWindDirectionByValue(value) {
150
+ var _a;
151
+ const calc = Math.floor((Number(value) + 22.5 * 0.5) / 22.5) || null;
152
+ if (calc === null)
153
+ return '';
154
+ return ((_a = windTable[calc]) === null || _a === void 0 ? void 0 : _a.replace(/[NSEW]/g, match => directoinMapping[match])) || '';
155
+ }
156
+ //# sourceMappingURL=waether.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waether.js","sourceRoot":"","sources":["../../../client/pages/lib/waether.ts"],"names":[],"mappings":"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","sourcesContent":["const API_KEY = '9epdR01s19phfu%2B3%2F0elTxTi92Nibl3qEO1HSm2QydrWOlrDqyNn9qzeQRJ3jPOh3hV8TesHg1L%2BQ9D6UOPmWQ%3D%3D'\nconst URL = 'https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst'\nconst NUM_OF_ROWS = 12\nconst DATA_TYPE = 'JSON'\n\nexport default async function _getWeather(latitude: number, longitude: number) {\n const { nx, ny } = _getIndexByLatAndLong(latitude, longitude)\n const { base_date, base_time } = _getTodayAndHour()\n const result = await fetch(\n `${URL}?serviceKey=${API_KEY}&base_date=${base_date}&base_time=${base_time}&nx=${nx}&ny=${ny}&pageNo=1&numOfRows=${NUM_OF_ROWS}&dataType=${DATA_TYPE}`\n )\n\n let rain = 0\n let temperature = 0\n let humidity = 0\n let windDirection = ''\n let windSpeed = 0\n\n if (result.status == 200) {\n let weather = await result.json().then(data => data?.response?.body)\n weather = weather?.items?.item\n\n for (let key in weather) {\n const data = weather?.[key] || {}\n\n if (data.category === 'POP') {\n rain = data.fcstValue\n }\n if (data.category === 'REH') {\n humidity = data.fcstValue\n }\n if (data.category === 'TMP') {\n temperature = data.fcstValue\n }\n if (data.category === 'VEC') {\n windDirection = _getWindDirectionByValue(data.fcstValue)\n }\n if (data.category === 'WSD') {\n windSpeed = data.fcstValue\n }\n }\n\n console.log('weather :', weather)\n }\n\n return { rain, temperature, humidity, windDirection, windSpeed }\n}\n\nconst RE = 6371.00877 // 지구 반경(km)\nconst GRID = 5.0 // 격자 간격(km)\nconst SLAT1 = 30.0 // 투영 위도1(degree)\nconst SLAT2 = 60.0 // 투영 위도2(degree)\nconst OLON = 126.0 // 기준점 경도(degree)\nconst OLAT = 38.0 // 기준점 위도(degree)\nconst XO = 43 // 기준점 X좌표(GRID)\nconst YO = 136 // 기1준점 Y좌표(GRID)\n\n// 위경도 -> 기상청 좌표\nfunction _getIndexByLatAndLong(latitude: number, longitude: number) {\n const DEGRAD = Math.PI / 180.0\n const re = RE / GRID\n const slat1 = SLAT1 * DEGRAD\n const slat2 = SLAT2 * DEGRAD\n const olon = OLON * DEGRAD\n const olat = OLAT * DEGRAD\n\n let sn = Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5)\n sn = Math.log(Math.cos(slat1) / Math.cos(slat2)) / Math.log(sn)\n let sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5)\n sf = (Math.pow(sf, sn) * Math.cos(slat1)) / sn\n let ro = Math.tan(Math.PI * 0.25 + olat * 0.5)\n ro = (re * sf) / Math.pow(ro, sn)\n let ra = Math.tan(Math.PI * 0.25 + latitude * DEGRAD * 0.5)\n ra = (re * sf) / Math.pow(ra, sn)\n let theta = longitude * DEGRAD - olon\n if (theta > Math.PI) theta -= 2.0 * Math.PI\n if (theta < -Math.PI) theta += 2.0 * Math.PI\n theta *= sn\n\n return {\n nx: Math.floor(ra * Math.sin(theta) + XO + 0.5),\n ny: Math.floor(ro - ra * Math.cos(theta) + YO + 0.5),\n latitude,\n longitude\n }\n}\n\nfunction _getTodayAndHour() {\n const now = new Date()\n const todayDate = now.toISOString().slice(0, 10).replace(/-/g, '')\n const yesterday = new Date(now)\n yesterday.setDate(yesterday.getDate() - 1)\n const yesterdayDate = yesterday.toISOString().slice(0, 10).replace(/-/g, '')\n\n // 1일 총 8번 데이터가 업데이트 된다. (0200, 0500, 0800, 1100, 1400, 1700, 2000, 2300)\n let base_date\n let base_time\n\n if (now.getHours() < 2 || (now.getHours() === 2 && now.getMinutes() <= 10)) {\n base_date = yesterdayDate\n base_time = '2300'\n } else if (now.getHours() < 5 || (now.getHours() === 5 && now.getMinutes() <= 10)) {\n base_date = todayDate\n base_time = '0200'\n } else if (now.getHours() < 8 || (now.getHours() === 8 && now.getMinutes() <= 10)) {\n base_date = todayDate\n base_time = '0500'\n } else if (now.getHours() <= 11 || now.getMinutes() <= 10) {\n base_date = todayDate\n base_time = '0800'\n } else if (now.getHours() < 14 || (now.getHours() === 14 && now.getMinutes() <= 10)) {\n base_date = todayDate\n base_time = '1100'\n } else if (now.getHours() < 17 || (now.getHours() === 17 && now.getMinutes() <= 10)) {\n base_date = todayDate\n base_time = '1400'\n } else if (now.getHours() < 20 || (now.getHours() === 20 && now.getMinutes() <= 10)) {\n base_date = todayDate\n base_time = '1700'\n } else if (now.getHours() < 23 || (now.getHours() === 23 && now.getMinutes() <= 10)) {\n base_date = todayDate\n base_time = '2000'\n } else {\n base_date = todayDate\n base_time = '2300'\n }\n\n return { base_time, base_date }\n}\n\nconst windTable = {\n 0: 'N',\n 1: 'NNE',\n 2: 'NE',\n 3: 'ENE',\n 4: 'E',\n 5: 'ESE',\n 6: 'SE',\n 7: 'SSE',\n 8: 'S',\n 9: 'SSW',\n 10: 'SW',\n 11: 'WSW',\n 12: 'W',\n 13: 'WNW',\n 14: 'NW',\n 15: 'NNW',\n 16: 'N'\n}\nconst directoinMapping = {\n N: '북',\n S: '남',\n E: '동',\n W: '서'\n}\n\nfunction _getWindDirectionByValue(value: number): string {\n const calc: number | null = Math.floor((Number(value) + 22.5 * 0.5) / 22.5) || null\n\n if (calc === null) return ''\n\n return windTable[calc]?.replace(/[NSEW]/g, match => directoinMapping[match]) || ''\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import '@material/web/button/outlined-button.js';
2
+ import '@material/web/icon/icon.js';
3
+ import { LitElement } from 'lit';
4
+ export declare class PagenationControl extends LitElement {
5
+ static styles: import("lit").CSSResult[];
6
+ currentPage: number;
7
+ totalItems: number;
8
+ pageLimit: number;
9
+ private get totalPages();
10
+ private get pageBlock();
11
+ render(): import("lit-html").TemplateResult<1>;
12
+ private _emitPageChange;
13
+ private _numberButtons;
14
+ private _onFirst;
15
+ private _onPrev;
16
+ private _onNext;
17
+ private _onLast;
18
+ }
@@ -0,0 +1,142 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@material/web/button/outlined-button.js';
3
+ import '@material/web/icon/icon.js';
4
+ import { css, html, LitElement } from 'lit';
5
+ import { customElement, property } from 'lit/decorators.js';
6
+ let PagenationControl = class PagenationControl extends LitElement {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.currentPage = 1;
10
+ this.totalItems = 0;
11
+ this.pageLimit = 20;
12
+ }
13
+ get totalPages() {
14
+ const totalPages = Math.ceil((this.totalItems || 0) / (this.pageLimit || 1));
15
+ return Math.max(1, totalPages);
16
+ }
17
+ get pageBlock() {
18
+ const blockSize = 10;
19
+ const blockIndex = Math.floor((this.currentPage - 1) / blockSize);
20
+ const start = blockIndex * blockSize + 1;
21
+ const end = Math.min(start + blockSize - 1, this.totalPages);
22
+ return { start, end };
23
+ }
24
+ render() {
25
+ return html `
26
+ <div pagination>
27
+ <md-outlined-button icon ?disabled=${this.currentPage <= 1} @click=${this._onFirst}>
28
+ <md-icon>first_page</md-icon>
29
+ </md-outlined-button>
30
+ <md-outlined-button icon ?disabled=${this.currentPage <= 1} @click=${this._onPrev}>
31
+ <md-icon>chevron_left</md-icon>
32
+ </md-outlined-button>
33
+
34
+ <div numbers>${this._numberButtons()}</div>
35
+
36
+ <md-outlined-button icon ?disabled=${this.currentPage >= this.totalPages} @click=${this._onNext}>
37
+ <md-icon>chevron_right</md-icon>
38
+ </md-outlined-button>
39
+ <md-outlined-button icon ?disabled=${this.currentPage >= this.totalPages} @click=${this._onLast}>
40
+ <md-icon>last_page</md-icon>
41
+ </md-outlined-button>
42
+ </div>
43
+ `;
44
+ }
45
+ _emitPageChange(nextPage) {
46
+ const bounded = Math.min(Math.max(1, nextPage), this.totalPages);
47
+ if (bounded !== this.currentPage) {
48
+ this.dispatchEvent(new CustomEvent('page-change', {
49
+ detail: { page: bounded },
50
+ bubbles: true,
51
+ composed: true
52
+ }));
53
+ }
54
+ }
55
+ _numberButtons() {
56
+ const { start, end } = this.pageBlock;
57
+ const buttons = [];
58
+ for (let page = start; page <= end; page++) {
59
+ const selected = page === this.currentPage;
60
+ buttons.push(html `<md-outlined-button data-page ?selected=${selected} @click=${() => this._emitPageChange(page)}
61
+ >${page}</md-outlined-button
62
+ >`);
63
+ }
64
+ return buttons;
65
+ }
66
+ _onFirst() {
67
+ this._emitPageChange(1);
68
+ }
69
+ _onPrev() {
70
+ this._emitPageChange(this.currentPage - 1);
71
+ }
72
+ _onNext() {
73
+ this._emitPageChange(this.currentPage + 1);
74
+ }
75
+ _onLast() {
76
+ this._emitPageChange(this.totalPages);
77
+ }
78
+ };
79
+ PagenationControl.styles = [
80
+ css `
81
+ div[pagination] {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+ gap: var(--spacing-medium, 8px);
86
+ margin: var(--spacing-large, 12px);
87
+
88
+ div[numbers] {
89
+ display: inline-flex;
90
+ gap: var(--spacing-tiny, 2px);
91
+ }
92
+
93
+ md-icon {
94
+ --md-icon-size: 18px;
95
+ }
96
+
97
+ md-outlined-button {
98
+ --md-outlined-button-container-height: 30px;
99
+ --md-outlined-button-label-text-size: 13px;
100
+ padding: 0 10px;
101
+ }
102
+
103
+ md-outlined-button[selected] {
104
+ --md-outlined-button-label-text-color: #ffffff;
105
+ --md-sys-color-outline: #0595e5;
106
+ background-color: #0595e5;
107
+ }
108
+
109
+ md-outlined-button[icon] {
110
+ min-width: 30px;
111
+ width: 30px;
112
+ padding: 0;
113
+ }
114
+
115
+ md-outlined-button[icon] md-icon {
116
+ margin-top: 5px;
117
+ }
118
+
119
+ md-outlined-button[data-page] {
120
+ min-width: 34px;
121
+ padding: 0 8px;
122
+ }
123
+ }
124
+ `
125
+ ];
126
+ __decorate([
127
+ property({ type: Number }),
128
+ __metadata("design:type", Number)
129
+ ], PagenationControl.prototype, "currentPage", void 0);
130
+ __decorate([
131
+ property({ type: Number }),
132
+ __metadata("design:type", Number)
133
+ ], PagenationControl.prototype, "totalItems", void 0);
134
+ __decorate([
135
+ property({ type: Number }),
136
+ __metadata("design:type", Number)
137
+ ], PagenationControl.prototype, "pageLimit", void 0);
138
+ PagenationControl = __decorate([
139
+ customElement('pagenation-control')
140
+ ], PagenationControl);
141
+ export { PagenationControl };
142
+ //# sourceMappingURL=pagenation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagenation.js","sourceRoot":"","sources":["../../../../client/pages/project/component/pagenation.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/button/outlined-button.js'\nimport '@material/web/icon/icon.js'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n@customElement('pagenation-control')\nexport class PagenationControl extends LitElement {\n static styles = [\n css`\n div[pagination] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-medium, 8px);\n margin: var(--spacing-large, 12px);\n\n div[numbers] {\n display: inline-flex;\n gap: var(--spacing-tiny, 2px);\n }\n\n md-icon {\n --md-icon-size: 18px;\n }\n\n md-outlined-button {\n --md-outlined-button-container-height: 30px;\n --md-outlined-button-label-text-size: 13px;\n padding: 0 10px;\n }\n\n md-outlined-button[selected] {\n --md-outlined-button-label-text-color: #ffffff;\n --md-sys-color-outline: #0595e5;\n background-color: #0595e5;\n }\n\n md-outlined-button[icon] {\n min-width: 30px;\n width: 30px;\n padding: 0;\n }\n\n md-outlined-button[icon] md-icon {\n margin-top: 5px;\n }\n\n md-outlined-button[data-page] {\n min-width: 34px;\n padding: 0 8px;\n }\n }\n `\n ]\n\n @property({ type: Number }) currentPage: number = 1\n @property({ type: Number }) totalItems: number = 0\n @property({ type: Number }) pageLimit: number = 20\n\n private get totalPages(): number {\n const totalPages = Math.ceil((this.totalItems || 0) / (this.pageLimit || 1))\n return Math.max(1, totalPages)\n }\n\n private get pageBlock(): { start: number; end: number } {\n const blockSize = 10\n const blockIndex = Math.floor((this.currentPage - 1) / blockSize)\n const start = blockIndex * blockSize + 1\n const end = Math.min(start + blockSize - 1, this.totalPages)\n return { start, end }\n }\n\n render() {\n return html`\n <div pagination>\n <md-outlined-button icon ?disabled=${this.currentPage <= 1} @click=${this._onFirst}>\n <md-icon>first_page</md-icon>\n </md-outlined-button>\n <md-outlined-button icon ?disabled=${this.currentPage <= 1} @click=${this._onPrev}>\n <md-icon>chevron_left</md-icon>\n </md-outlined-button>\n\n <div numbers>${this._numberButtons()}</div>\n\n <md-outlined-button icon ?disabled=${this.currentPage >= this.totalPages} @click=${this._onNext}>\n <md-icon>chevron_right</md-icon>\n </md-outlined-button>\n <md-outlined-button icon ?disabled=${this.currentPage >= this.totalPages} @click=${this._onLast}>\n <md-icon>last_page</md-icon>\n </md-outlined-button>\n </div>\n `\n }\n\n private _emitPageChange(nextPage: number) {\n const bounded = Math.min(Math.max(1, nextPage), this.totalPages)\n if (bounded !== this.currentPage) {\n this.dispatchEvent(\n new CustomEvent('page-change', {\n detail: { page: bounded },\n bubbles: true,\n composed: true\n })\n )\n }\n }\n\n private _numberButtons() {\n const { start, end } = this.pageBlock\n const buttons = [] as any[]\n for (let page = start; page <= end; page++) {\n const selected = page === this.currentPage\n buttons.push(\n html`<md-outlined-button data-page ?selected=${selected} @click=${() => this._emitPageChange(page)}\n >${page}</md-outlined-button\n >`\n )\n }\n return buttons\n }\n\n private _onFirst() {\n this._emitPageChange(1)\n }\n\n private _onPrev() {\n this._emitPageChange(this.currentPage - 1)\n }\n\n private _onNext() {\n this._emitPageChange(this.currentPage + 1)\n }\n\n private _onLast() {\n this._emitPageChange(this.totalPages)\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ import '@material/web/icon/icon.js';