Reports.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <template>
  2. <div>
  3. <page-metadata title="Admin | Reports" />
  4. <div class="container">
  5. <advanced-table
  6. :column-default="columnDefault"
  7. :columns="columns"
  8. :filters="filters"
  9. data-action="reports.getData"
  10. name="admin-reports"
  11. max-width="1200"
  12. >
  13. <template #column-options="slotProps">
  14. <div class="row-options">
  15. <button
  16. class="
  17. button
  18. is-primary
  19. icon-with-button
  20. material-icons
  21. "
  22. @click="view(slotProps.item._id)"
  23. content="View Report"
  24. v-tippy
  25. >
  26. open_in_full
  27. </button>
  28. <button
  29. class="
  30. button
  31. is-success
  32. icon-with-button
  33. material-icons
  34. "
  35. @click="resolve(slotProps.item._id)"
  36. content="Resolve Report"
  37. v-tippy
  38. >
  39. done_all
  40. </button>
  41. </div>
  42. </template>
  43. <template #column-_id="slotProps">
  44. <span :title="slotProps.item._id">{{
  45. slotProps.item._id
  46. }}</span>
  47. </template>
  48. <template #column-songId="slotProps">
  49. <span :title="slotProps.item.song._id">{{
  50. slotProps.item.song._id
  51. }}</span>
  52. </template>
  53. <template #column-songYoutubeId="slotProps">
  54. <a
  55. :href="
  56. 'https://www.youtube.com/watch?v=' +
  57. `${slotProps.item.song.youtubeId}`
  58. "
  59. target="_blank"
  60. >
  61. {{ slotProps.item.song.youtubeId }}
  62. </a>
  63. </template>
  64. <template #column-categories="slotProps">
  65. <span
  66. :title="
  67. slotProps.item.issues
  68. .map(issue => issue.category)
  69. .join(', ')
  70. "
  71. >{{
  72. slotProps.item.issues
  73. .map(issue => issue.category)
  74. .join(", ")
  75. }}</span
  76. >
  77. </template>
  78. <template #column-createdBy="slotProps">
  79. <span v-if="slotProps.item.createdBy === 'Musare'"
  80. >Musare</span
  81. >
  82. <user-id-to-username
  83. v-else
  84. :user-id="slotProps.item.createdBy"
  85. :link="true"
  86. />
  87. </template>
  88. <template #column-createdAt="slotProps">
  89. <span :title="new Date(slotProps.item.createdAt)">{{
  90. getDateFormatted(slotProps.item.createdAt)
  91. }}</span>
  92. </template>
  93. </advanced-table>
  94. </div>
  95. <view-report v-if="modals.viewReport" sector="admin" />
  96. <edit-song v-if="modals.editSong" song-type="songs" />
  97. <report v-if="modals.report" />
  98. </div>
  99. </template>
  100. <script>
  101. import { mapState, mapActions, mapGetters } from "vuex";
  102. import { defineAsyncComponent } from "vue";
  103. import Toast from "toasters";
  104. import AdvancedTable from "@/components/AdvancedTable.vue";
  105. import UserIdToUsername from "@/components/UserIdToUsername.vue";
  106. export default {
  107. components: {
  108. ViewReport: defineAsyncComponent(() =>
  109. import("@/components/modals/ViewReport.vue")
  110. ),
  111. Report: defineAsyncComponent(() =>
  112. import("@/components/modals/Report.vue")
  113. ),
  114. EditSong: defineAsyncComponent(() =>
  115. import("@/components/modals/EditSong/index.vue")
  116. ),
  117. AdvancedTable,
  118. UserIdToUsername
  119. },
  120. data() {
  121. return {
  122. columnDefault: {
  123. sortable: true,
  124. hidable: true,
  125. defaultVisibility: "shown",
  126. draggable: true,
  127. resizable: true,
  128. minWidth: 150,
  129. maxWidth: 600
  130. },
  131. columns: [
  132. {
  133. name: "options",
  134. displayName: "Edit",
  135. properties: ["_id"],
  136. sortable: false,
  137. hidable: false,
  138. resizable: false,
  139. minWidth: 85,
  140. defaultWidth: 85
  141. },
  142. {
  143. name: "_id",
  144. displayName: "Report ID",
  145. properties: ["_id"],
  146. sortProperty: "_id",
  147. minWidth: 215,
  148. defaultWidth: 215
  149. },
  150. {
  151. name: "songId",
  152. displayName: "Song ID",
  153. properties: ["song"],
  154. sortProperty: "song._id",
  155. minWidth: 215,
  156. defaultWidth: 215
  157. },
  158. {
  159. name: "songYoutubeId",
  160. displayName: "Song YouTube ID",
  161. properties: ["song"],
  162. sortProperty: "song.youtubeId",
  163. minWidth: 165,
  164. defaultWidth: 165
  165. },
  166. {
  167. name: "categories",
  168. displayName: "Categories",
  169. properties: ["issues"],
  170. sortable: false
  171. },
  172. {
  173. name: "createdBy",
  174. displayName: "Created By",
  175. properties: ["createdBy"],
  176. sortProperty: "createdBy",
  177. defaultWidth: 150
  178. },
  179. {
  180. name: "createdAt",
  181. displayName: "Created At",
  182. properties: ["createdAt"],
  183. sortProperty: "createdAt",
  184. defaultWidth: 150
  185. }
  186. ],
  187. filters: [
  188. {
  189. name: "_id",
  190. displayName: "Report ID",
  191. property: "_id",
  192. filterTypes: ["exact"],
  193. defaultFilterType: "exact"
  194. },
  195. {
  196. name: "songId",
  197. displayName: "Song ID",
  198. property: "song._id",
  199. filterTypes: ["exact"],
  200. defaultFilterType: "exact"
  201. },
  202. {
  203. name: "songYoutubeId",
  204. displayName: "Song YouTube ID",
  205. property: "song.youtubeId",
  206. filterTypes: ["contains", "exact", "regex"],
  207. defaultFilterType: "contains"
  208. },
  209. {
  210. name: "categories",
  211. displayName: "Categories",
  212. property: "issues.category",
  213. filterTypes: ["contains", "exact", "regex"],
  214. defaultFilterType: "contains"
  215. },
  216. {
  217. name: "createdBy",
  218. displayName: "Created By",
  219. property: "createdBy",
  220. filterTypes: ["contains", "exact", "regex"],
  221. defaultFilterType: "contains"
  222. },
  223. {
  224. name: "createdAt",
  225. displayName: "Created At",
  226. property: "createdAt",
  227. filterTypes: ["contains", "exact", "regex"],
  228. defaultFilterType: "contains"
  229. }
  230. ]
  231. };
  232. },
  233. computed: {
  234. ...mapState("modalVisibility", {
  235. modals: state => state.modals
  236. }),
  237. ...mapGetters({
  238. socket: "websockets/getSocket"
  239. })
  240. },
  241. mounted() {
  242. // ws.onConnect(this.init);
  243. // this.socket.on("event:admin.report.resolved", res => {
  244. // this.reports = this.reports.filter(
  245. // report => report._id !== res.data.reportId
  246. // );
  247. // });
  248. // this.socket.on("event:admin.report.created", res =>
  249. // this.reports.unshift(res.data.report)
  250. // );
  251. },
  252. methods: {
  253. // init() {
  254. // this.socket.dispatch("apis.joinAdminRoom", "reports", () => {});
  255. // },
  256. view(reportId) {
  257. this.viewReport(reportId);
  258. this.openModal("viewReport");
  259. },
  260. resolve(reportId) {
  261. return this.resolveReport(reportId)
  262. .then(res => {
  263. if (res.status === "success" && this.modals.viewReport)
  264. this.closeModal("viewReport");
  265. })
  266. .catch(err => new Toast(err.message));
  267. },
  268. getDateFormatted(createdAt) {
  269. const date = new Date(createdAt);
  270. const year = date.getFullYear();
  271. const month = `${date.getMonth() + 1}`.padStart(2, 0);
  272. const day = `${date.getDate()}`.padStart(2, 0);
  273. const hour = `${date.getHours()}`.padStart(2, 0);
  274. const minute = `${date.getMinutes()}`.padStart(2, 0);
  275. return `${year}-${month}-${day} ${hour}:${minute}`;
  276. },
  277. ...mapActions("modalVisibility", ["openModal", "closeModal"]),
  278. ...mapActions("admin/reports", ["resolveReport"]),
  279. ...mapActions("modals/viewReport", ["viewReport"])
  280. }
  281. };
  282. </script>