News.vue 4.9 KB

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