todo.blade.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. @push('css')
  2. <link href="{{ csset('/css/cal-type1.css') }}" rel="stylesheet" type="text/css">
  3. @endpush
  4. <div class="{{ $calType1['FormVars']['Display']['SelectPopup'] }} flex-column mb-2">
  5. <label class="m-0">{{ $calType1['FormVars']['Title']['SelectPopup'] }}</label>
  6. <select class="rounded w-100" id="select-popup-select">
  7. @foreach ($calType1['SelectPopupOptions'] as $popupOption)
  8. <option value="{{ $popupOption['Caption'] }}" data-component="{{ $popupOption['ModalClassName'] }}"
  9. data-type="{{ $popupOption['ParameterType'] }}" data-unique="{{ $popupOption['Unique'] }}">
  10. {{ $popupOption['Caption'] }}
  11. </option>
  12. @endforeach
  13. </select>
  14. </div>
  15. <div class="row">
  16. <div class="col-xl-8">
  17. <div id='calendar'></div>
  18. </div>
  19. <div class="col-xl-4">
  20. <div class="callendar_cont card border-light" style="overflow-y: scroll; height: 735px;">
  21. <div class="d-flex align-items-center date justify-content-between">
  22. <div class="current-date"></div>
  23. <button class="btn btn-sm btn-primary cal-type1-bd-act" data-value="add">
  24. {{ $calType1['FormVars']['Title']['AddNewBdButton'] ?? '일정 등록' }}
  25. </button>
  26. </div>
  27. <ul>
  28. <li v-for="(todo, index) in todoDetails" class="todo-Details position-relative">
  29. <div>
  30. <div class="d-flex align-items-center">
  31. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event pr-1"
  32. @click="showSelectPopup(todo['Id'], todo['C1'])"
  33. :class="statusBgColor(todo['C6'])">
  34. <div class="fc-daygrid-event-dot"
  35. :style="{borderColor: convertColor(todo['C5'])}">
  36. </div>
  37. <div class="fc-event-title">@{{ todo['C2'] }} (@{{ convertSort(todo['C5']) }}) (@{{ convertStatus(todo['C6']) }})</div>
  38. </div>
  39. </div>
  40. <strong class="mb-1">@{{ todo['C3'] }}</strong>
  41. <div style="line-height: 1.3715">
  42. @{{ todo['C4'] }}
  43. </div>
  44. </div>
  45. <button type="button"
  46. @click="showSelectPopup(todo['Id'], todo['C1'])"
  47. class="position-absolute top-0 right-0 text-danger color-danger bg-white">
  48. <i class="fas fa-edit fa-2x"></i>
  49. </button>
  50. </li>
  51. </ul>
  52. </div>
  53. </div>
  54. </div>
  55. <div class="color-desc d-flex justify-content-between col-8">
  56. <div class="d-flex">
  57. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2">
  58. <div class="fc-daygrid-event-dot"></div>
  59. <div class="fc-event-title">업무마감</div>
  60. </div>
  61. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2">
  62. <div class="fc-daygrid-event-dot" style="border-color: green;"></div>
  63. <div class="fc-event-title">내부회의</div>
  64. </div>
  65. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2">
  66. <div class="fc-daygrid-event-dot" style="border-color: orange;"></div>
  67. <div class="fc-event-title">방문미팅</div>
  68. </div>
  69. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2">
  70. <div class="fc-daygrid-event-dot" style="border-color: purple;"></div>
  71. <div class="fc-event-title">외부미팅</div>
  72. </div>
  73. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2">
  74. <div class="fc-daygrid-event-dot" style="border-color: red;"></div>
  75. <div class="fc-event-title">중요회의</div>
  76. </div>
  77. </div>
  78. <div class="d-flex status-color">
  79. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2 bg-wh">
  80. <div class="fc-event-title">계획</div>
  81. </div>
  82. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2 bg-lightgray">
  83. <div class="fc-event-title">완료</div>
  84. </div>
  85. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2 bg-darkgray">
  86. <div class="fc-event-title">미결</div>
  87. </div>
  88. <div tabindex="0" class="fc-daygrid-event fc-daygrid-dot-event mr-2 bg-blackgray">
  89. <div class="fc-event-title">취소</div>
  90. </div>
  91. </div>
  92. </div>
  93. @foreach ($calType1['SelectPopupOptions'] as $popupOption)
  94. {{-- @php dd($calType1['SelectPopupOptions']); @endphp;--}}
  95. @if (! empty($popupOption['Caption']))
  96. @push('modal')
  97. @include('front.outline.static.select-popup', [
  98. 'popupOption' => $popupOption,
  99. 'attachClassName' => $calType1['General']['PageApi']
  100. ])
  101. @endpush
  102. @endif
  103. @endforeach
  104. @push('js')
  105. <script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js'></script>
  106. <script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.8.0/locales-all.min.js'></script>
  107. <script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.0/locale/ko.js'></script>
  108. <script>
  109. var vm = new Vue({
  110. el: '.callendar_cont',
  111. data: function () {
  112. return {
  113. todoDetails: [],
  114. deleteId: 0,
  115. deleteDate: new Date(),
  116. addDate: new Date(),
  117. };
  118. },
  119. methods: {
  120. showSelectPopup: function (id, date) {
  121. this.deleteId = id
  122. this.deleteDate = date
  123. show_select_popup(id, '')
  124. },
  125. },
  126. });
  127. $(document).ready(function() {
  128. $('.callendar_cont').find('.current-date').text(moment().format('YYYY년 MM월 DD일 (dd)'))
  129. showDetails(new Date())
  130. $('.cal-type1-bd-act').on('click', function () {
  131. switch( $(this).data('value') ) {
  132. case 'add': type1_new(); break;
  133. }
  134. });
  135. $(document).on('add.todo', '#modal-select-popup', function (event, todo) {
  136. const is_update_event = calendar.getEventById(todo['Id'])
  137. if (is_update_event) {
  138. is_update_event.remove()
  139. }
  140. const date = moment(todo['TodoDate']).format('YYYY-MM-DD')
  141. calendar.addEvent({
  142. id: todo['Id'],
  143. title: todo['TodoTitle'],
  144. start: date + 'T' + todo['TodoTime'],
  145. color: convertColor(todo['Sort']),
  146. className: statusBgColor(todo['Status'])
  147. })
  148. calendar.unselect()
  149. calendar.gotoDate( date );
  150. showDetails(new Date(date))
  151. });
  152. $(document).on('delete.todo', '#modal-select-popup', function (event) {
  153. calendar.getEventById(vm.deleteId).remove()
  154. const todoDate = vm.deleteDate
  155. const date = moment(todoDate).format('YYYY-MM-DD')
  156. calendar.gotoDate( date );
  157. showDetails(new Date(date))
  158. });
  159. });
  160. document.addEventListener('DOMContentLoaded', async function() {
  161. const response = await getPage()
  162. console.log(response)
  163. const todo = convertPage(response.data.Page ?? [])
  164. var calendarEl = document.getElementById('calendar');
  165. calendar = new FullCalendar.Calendar(calendarEl, {
  166. height: '735px',
  167. headerToolbar: {
  168. left: 'prev,next today',
  169. center: 'title',
  170. right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
  171. },
  172. initialView: 'dayGridMonth',
  173. navLinks: true, // 날짜를 선택하면 Day 캘린더나 Week 캘린더로 링크
  174. editable: false, // 수정 가능?
  175. // selectable: true, // 달력 일자 드래그 설정가능
  176. nowIndicator: true, // 현재 시간 마크
  177. dayMaxEvents: true, // 이벤트가 오버되면 높이 제한 (+ 몇 개식으로 표현)
  178. locale: 'ko', // 한국어 설정
  179. navLinkDayClick: function(date, jsEvent) {
  180. vm.addDate = date
  181. calendar.gotoDate( date );
  182. showDetails(date)
  183. },
  184. eventClick: function(info) {
  185. vm.showSelectPopup(info.event.id, moment(info.event.start).format('YYYYMMDD'))
  186. },
  187. eventAdd: function(obj) { // 이벤트가 추가되면 발생하는 이벤트
  188. console.log(obj);
  189. },
  190. eventChange: function(obj) { // 이벤트가 수정되면 발생하는 이벤트
  191. console.log(obj);
  192. },
  193. eventRemove: function(obj){ // 이벤트가 삭제되면 발생하는 이벤트
  194. console.log(obj);
  195. },
  196. select: function(arg) { // 캘린더에서 드래그로 이벤트를 생성할 수 있다.
  197. console.log(arg)
  198. },
  199. mouseEnterInfo: function (obj) {
  200. console.log(obj)
  201. },
  202. // 이벤트
  203. events: todo
  204. });
  205. calendar.render();
  206. });
  207. async function showDetails(date) {
  208. const filter_data = moment(date).format('YYYYMMDD')
  209. const response = await getPage(filter_data)
  210. console.log(response)
  211. vm.todoDetails = response.data.Page
  212. $('.callendar_cont').find('.current-date').text(moment(date).format('YYYY년 MM월 DD일 (dd)'))
  213. }
  214. function convertStatus(status) {
  215. return format_conver_for(status, calType1.ListVars['Format']['C1']);
  216. }
  217. function convertSort(sort) {
  218. return format_conver_for(sort, calType1.ListVars['Format']['C2']);
  219. }
  220. function convertPage(page) {
  221. return page.map(todo => {
  222. return {
  223. id: todo['Id'],
  224. title: todo['C3'],
  225. start: moment(todo['C1']).format('YYYY-MM-DD') + 'T' + todo['C2'],
  226. color: convertColor(todo['C5']),
  227. className: statusBgColor(todo['C6'])
  228. }
  229. })
  230. }
  231. function statusBgColor(status) {
  232. switch (status) {
  233. case '0':
  234. return 'bg-wh'
  235. case '1':
  236. return 'bg-lightgray'
  237. case '2':
  238. return 'bg-darkgray'
  239. case '3':
  240. return 'bg-blackgray'
  241. }
  242. }
  243. function convertColor(status) {
  244. let color = ''
  245. switch (status) {
  246. case '1':
  247. color = 'green'
  248. break;
  249. case '2':
  250. color = 'orange'
  251. break;
  252. case '3':
  253. color = 'purple'
  254. break;
  255. case '4':
  256. color = 'red'
  257. break;
  258. }
  259. return color
  260. }
  261. async function getPage(date = '') {
  262. return await get_api_data(calType1['General']['PageApi'], {
  263. QueryVars: {
  264. QueryName: calType1['QueryVars']['QueryName'],
  265. FilterName: calType1['QueryVars']['FilterName'],
  266. FilterValue: calType1['QueryVars']['FilterValue'],
  267. SimpleFilter: calType1['QueryVars']['SimpleFilter'],
  268. SubSimpleFilter: calType1['QueryVars']['SubSimpleFilter'],
  269. IsntPagination: false,
  270. // TestMode: "query"
  271. },
  272. ListType1Vars: {
  273. FilterDate: calType1['QueryVars']['FilterDate'],
  274. StartDate: date,
  275. EndDate: date,
  276. ListFilterName: $('.cal-type1').find('#filter-name-select').val(),
  277. ListFilterValue: $('.cal-type1').find('#filter-value-txt').data('value'),
  278. },
  279. PageVars: {
  280. Limit: 10000000000,
  281. Offset: 0,
  282. }
  283. })
  284. }
  285. function type1_new() {
  286. const modal_class_name = $('#select-popup-select option:selected').data('component');
  287. eval(capitalize(camelCase(modal_class_name))).btn_act_new_callback(vm.addDate)
  288. $(`#modal-select-popup.${modal_class_name}`).addClass('list-update')
  289. $(`#modal-select-popup.${modal_class_name}`).modal('show')
  290. }
  291. async function show_select_popup(id, c1) {
  292. if (c1.toLowerCase() == 'total') return;
  293. let modal_class_name = $('#select-popup-select option:selected').data('component');
  294. let parameter_type = $('#select-popup-select option:selected').data('type');
  295. let unique = $('#select-popup-select option:selected').data('unique');
  296. if (isEmpty(modal_class_name)) return;
  297. // console.log(modal_class_name)
  298. // console.log(unique)
  299. // console.log(capitalize(camelCase(modal_class_name)))
  300. await eval(capitalize(camelCase(modal_class_name))).show_popup_callback(id, c1, {
  301. start_date: $('#type1-start-date').val(),
  302. end_date: $('#type1-end-date').val(),
  303. range_val: $('input:radio[name=type1-date-range]:checked').val()
  304. }
  305. )
  306. // hide => 업데이트 유무
  307. // if (parameter_type != 'list1') {
  308. // $(`#modal-select-popup.${modal_class_name}`).addClass('list-update')
  309. // } else {
  310. // $(`#modal-select-popup.${modal_class_name}`).removeClass('list-update')
  311. // }
  312. $(`#modal-select-popup.${modal_class_name}`).modal('show')
  313. }
  314. var calendar
  315. const calType1 = {!! json_encode($calType1) !!};
  316. </script>
  317. @endpush