EditAlbum.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <script setup lang="ts">
  2. import Toast from "toasters";
  3. import { defineAsyncComponent, ref, onMounted } from "vue";
  4. import { GenericResponse } from "@musare_types/actions/GenericActions";
  5. import { useForm } from "@/composables/useForm";
  6. import { useWebsocketsStore } from "@/stores/websockets";
  7. import { useModalsStore } from "@/stores/modals";
  8. const Modal = defineAsyncComponent(() => import("@/components/Modal.vue"));
  9. const SaveButton = defineAsyncComponent(
  10. () => import("@/components/SaveButton.vue")
  11. );
  12. const props = defineProps({
  13. modalUuid: { type: String, required: true },
  14. createArtist: { type: Boolean, default: false },
  15. artistId: { type: String, default: null },
  16. sector: { type: String, default: "admin" }
  17. });
  18. const { socket } = useWebsocketsStore();
  19. const { closeCurrentModal } = useModalsStore();
  20. const createdBy = ref();
  21. const createdAt = ref(0);
  22. const { inputs, save, setOriginalValue } = useForm(
  23. {
  24. name: {
  25. value: ""
  26. },
  27. musicbrainzIdentifier: {
  28. value: ""
  29. }
  30. },
  31. ({ status, messages, values }, resolve, reject) => {
  32. if (status === "success") {
  33. const data = {
  34. name: values.name,
  35. musicbrainzIdentifier: values.musicbrainzIdentifier
  36. };
  37. const cb = (res: GenericResponse) => {
  38. new Toast(res.message);
  39. if (res.status === "success") resolve();
  40. else reject(new Error(res.message));
  41. };
  42. if (props.createArtist) socket.dispatch("artists.create", data, cb);
  43. else socket.dispatch("artists.update", props.artistId, data, cb);
  44. } else {
  45. if (status === "unchanged") new Toast(messages.unchanged);
  46. else if (status === "error")
  47. Object.values(messages).forEach(message => {
  48. new Toast({ content: message, timeout: 8000 });
  49. });
  50. resolve();
  51. }
  52. },
  53. {
  54. modalUuid: props.modalUuid
  55. }
  56. );
  57. onMounted(() => {
  58. socket.onConnect(() => {
  59. if (props.artistId && !props.createArtist) {
  60. socket.dispatch(`artists.getArtistFromId`, props.artistId, res => {
  61. // res: GetArtistResponse
  62. if (res.status === "success") {
  63. setOriginalValue({
  64. name: res.data.artist.name,
  65. musicbrainzIdentifier:
  66. res.data.artist.musicbrainzIdentifier
  67. });
  68. createdBy.value = res.data.artist.createdBy;
  69. createdAt.value = res.data.artist.createdAt;
  70. } else {
  71. new Toast("Artist with that ID not found.");
  72. closeCurrentModal();
  73. }
  74. });
  75. }
  76. });
  77. });
  78. const saveArtist = (close?: boolean) => {
  79. save(() => {
  80. if (close) {
  81. closeCurrentModal();
  82. }
  83. });
  84. };
  85. </script>
  86. <template>
  87. <modal
  88. class="edit-artist-modal"
  89. :title="createArtist ? 'Create Artist' : 'Edit Artist'"
  90. :size="'wide'"
  91. :split="true"
  92. >
  93. <template #body>
  94. <div class="control is-grouped">
  95. <div class="name-container">
  96. <label class="label">Name</label>
  97. <p class="control has-addons">
  98. <input
  99. class="input"
  100. type="text"
  101. :ref="el => (inputs['name'].ref = el)"
  102. v-model="inputs['name'].value"
  103. placeholder="Enter artist name..."
  104. />
  105. </p>
  106. </div>
  107. </div>
  108. <div class="control is-grouped">
  109. <div class="musicbrainz-identifier-container">
  110. <label class="label">MusicBrainz identifier</label>
  111. <p class="control has-addons">
  112. <input
  113. class="input"
  114. type="text"
  115. :ref="
  116. el => (inputs['musicbrainzIdentifier'].ref = el)
  117. "
  118. v-model="inputs['musicbrainzIdentifier'].value"
  119. placeholder="Enter MusicBrainz identifier..."
  120. />
  121. </p>
  122. </div>
  123. </div>
  124. <div>
  125. <p>MusicBrainz data</p>
  126. </div>
  127. </template>
  128. <template #footer>
  129. <div>
  130. <save-button
  131. :default-message="`${createArtist ? 'Create' : 'Update'} Artist`"
  132. @clicked="saveArtist()"
  133. />
  134. <save-button
  135. :default-message="`${createArtist ? 'Create' : 'Update'} and close`"
  136. @clicked="saveArtist(true)"
  137. />
  138. </div>
  139. </template>
  140. </modal>
  141. </template>
  142. <style lang="less"></style>
  143. <style lang="less" scoped></style>