News.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <div>
  3. <page-metadata title="Admin | News" />
  4. <div class="container">
  5. <div class="button-row">
  6. <button
  7. class="is-primary button"
  8. @click="
  9. openModal({
  10. modal: 'editNews',
  11. data: { createNews: true }
  12. })
  13. "
  14. >
  15. Create News Item
  16. </button>
  17. </div>
  18. <advanced-table
  19. :column-default="columnDefault"
  20. :columns="columns"
  21. :filters="filters"
  22. data-action="news.getData"
  23. name="admin-news"
  24. :max-width="1200"
  25. :events="events"
  26. >
  27. <template #column-options="slotProps">
  28. <div class="row-options">
  29. <button
  30. class="button is-primary icon-with-button material-icons"
  31. @click="
  32. openModal({
  33. modal: 'editNews',
  34. data: { newsId: slotProps.item._id }
  35. })
  36. "
  37. content="Edit News"
  38. v-tippy
  39. >
  40. edit
  41. </button>
  42. <quick-confirm
  43. @confirm="remove(slotProps.item._id)"
  44. :disabled="slotProps.item.removed"
  45. >
  46. <button
  47. class="button is-danger icon-with-button material-icons"
  48. content="Remove News"
  49. v-tippy
  50. >
  51. delete_forever
  52. </button>
  53. </quick-confirm>
  54. </div>
  55. </template>
  56. <template #column-status="slotProps">
  57. <span :title="slotProps.item.status">{{
  58. slotProps.item.status
  59. }}</span>
  60. </template>
  61. <template #column-showToNewUsers="slotProps">
  62. <span :title="slotProps.item.showToNewUsers">{{
  63. slotProps.item.showToNewUsers
  64. }}</span>
  65. </template>
  66. <template #column-title="slotProps">
  67. <span :title="slotProps.item.title">{{
  68. slotProps.item.title
  69. }}</span>
  70. </template>
  71. <template #column-createdBy="slotProps">
  72. <user-id-to-username
  73. :user-id="slotProps.item.createdBy"
  74. :alt="slotProps.item.createdBy"
  75. :link="true"
  76. />
  77. </template>
  78. <template #column-markdown="slotProps">
  79. <span :title="slotProps.item.markdown">{{
  80. slotProps.item.markdown
  81. }}</span>
  82. </template>
  83. </advanced-table>
  84. </div>
  85. </div>
  86. </template>
  87. <script>
  88. import { mapActions, mapGetters } from "vuex";
  89. import Toast from "toasters";
  90. import AdvancedTable from "@/components/AdvancedTable.vue";
  91. export default {
  92. components: {
  93. AdvancedTable
  94. },
  95. data() {
  96. return {
  97. editingNewsId: "",
  98. columnDefault: {
  99. sortable: true,
  100. hidable: true,
  101. defaultVisibility: "shown",
  102. draggable: true,
  103. resizable: true,
  104. minWidth: 150,
  105. maxWidth: 600
  106. },
  107. columns: [
  108. {
  109. name: "options",
  110. displayName: "Options",
  111. properties: ["_id"],
  112. sortable: false,
  113. hidable: false,
  114. resizable: false,
  115. minWidth: 85,
  116. defaultWidth: 85
  117. },
  118. {
  119. name: "status",
  120. displayName: "Status",
  121. properties: ["status"],
  122. sortProperty: "status",
  123. defaultWidth: 150
  124. },
  125. {
  126. name: "showToNewUsers",
  127. displayName: "Show to new users",
  128. properties: ["showToNewUsers"],
  129. sortProperty: "showToNewUsers",
  130. defaultWidth: 180
  131. },
  132. {
  133. name: "title",
  134. displayName: "Title",
  135. properties: ["title"],
  136. sortProperty: "title"
  137. },
  138. {
  139. name: "createdBy",
  140. displayName: "Created By",
  141. properties: ["createdBy"],
  142. sortProperty: "createdBy",
  143. defaultWidth: 150
  144. },
  145. {
  146. name: "markdown",
  147. displayName: "Markdown",
  148. properties: ["markdown"],
  149. sortProperty: "markdown"
  150. }
  151. ],
  152. filters: [
  153. {
  154. name: "status",
  155. displayName: "Status",
  156. property: "status",
  157. filterTypes: ["contains", "exact", "regex"],
  158. defaultFilterType: "contains"
  159. },
  160. {
  161. name: "showToNewUsers",
  162. displayName: "Show to new users",
  163. property: "showToNewUsers",
  164. filterTypes: ["boolean"],
  165. defaultFilterType: "boolean"
  166. },
  167. {
  168. name: "title",
  169. displayName: "Title",
  170. property: "title",
  171. filterTypes: ["contains", "exact", "regex"],
  172. defaultFilterType: "contains"
  173. },
  174. {
  175. name: "createdBy",
  176. displayName: "Created By",
  177. property: "createdBy",
  178. filterTypes: ["contains", "exact", "regex"],
  179. defaultFilterType: "contains"
  180. },
  181. {
  182. name: "markdown",
  183. displayName: "Markdown",
  184. property: "markdown",
  185. filterTypes: ["contains", "exact", "regex"],
  186. defaultFilterType: "contains"
  187. }
  188. ],
  189. events: {
  190. adminRoom: "news",
  191. updated: {
  192. event: "admin.news.updated",
  193. id: "news._id",
  194. item: "news"
  195. },
  196. removed: {
  197. event: "admin.news.deleted",
  198. id: "newsId"
  199. }
  200. }
  201. };
  202. },
  203. computed: {
  204. ...mapGetters({
  205. socket: "websockets/getSocket"
  206. })
  207. },
  208. methods: {
  209. remove(id) {
  210. this.socket.dispatch(
  211. "news.remove",
  212. id,
  213. res => new Toast(res.message)
  214. );
  215. },
  216. ...mapActions("modalVisibility", ["openModal"])
  217. }
  218. };
  219. </script>