You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
4.7 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. <template>
  2. <v-data-table
  3. :headers="headers"
  4. :items="value"
  5. >
  6. <template #top>
  7. <v-toolbar
  8. class="toolbar-control"
  9. flat
  10. >
  11. <v-toolbar-title class="text-capitalize">
  12. {{ title }}
  13. </v-toolbar-title>
  14. <v-spacer />
  15. <v-dialog
  16. v-model="dialog"
  17. max-width="800px"
  18. >
  19. <template #activator="{ on, attrs }">
  20. <v-btn
  21. color="primary"
  22. dark
  23. class="text-none"
  24. v-bind="attrs"
  25. v-on="on"
  26. >
  27. Add
  28. </v-btn>
  29. </template>
  30. <v-card>
  31. <v-card-title>
  32. <span class="headline">Add a new field</span>
  33. </v-card-title>
  34. <v-card-text>
  35. <v-container>
  36. <v-form
  37. ref="form"
  38. v-model="valid"
  39. >
  40. <v-row>
  41. <v-col
  42. cols="12"
  43. sm="12"
  44. class="pa-0"
  45. >
  46. <v-text-field
  47. v-model="editedItem.key"
  48. label="Key"
  49. outlined
  50. />
  51. </v-col>
  52. <v-col
  53. cols="12"
  54. sm="12"
  55. class="pa-0"
  56. >
  57. <v-text-field
  58. v-model="editedItem.value"
  59. label="Value"
  60. outlined
  61. />
  62. </v-col>
  63. </v-row>
  64. </v-form>
  65. </v-container>
  66. </v-card-text>
  67. <v-card-actions>
  68. <v-spacer />
  69. <v-btn
  70. color="blue darken-1"
  71. class="text-capitalize"
  72. text
  73. @click="close"
  74. >
  75. Cancel
  76. </v-btn>
  77. <v-btn
  78. :disabled="!valid"
  79. color="blue darken-1"
  80. class="text-capitalize"
  81. text
  82. @click="save"
  83. >
  84. Save
  85. </v-btn>
  86. </v-card-actions>
  87. </v-card>
  88. </v-dialog>
  89. </v-toolbar>
  90. </template>
  91. <template #[`item.actions`]="{ item }">
  92. <v-icon
  93. small
  94. class="mr-2"
  95. @click="editItem(item)"
  96. >
  97. {{ mdiPencil }}
  98. </v-icon>
  99. <v-icon
  100. small
  101. @click="deleteItem(item)"
  102. >
  103. {{ mdiDelete }}
  104. </v-icon>
  105. </template>
  106. </v-data-table>
  107. </template>
  108. <script lang="ts">
  109. import Vue from 'vue'
  110. import { mdiPencil, mdiDelete } from '@mdi/js'
  111. export default Vue.extend({
  112. props: {
  113. value: {
  114. type: Array,
  115. default: () => [],
  116. required: true
  117. },
  118. title: {
  119. type: String,
  120. default: '',
  121. required: true
  122. }
  123. },
  124. data() {
  125. return {
  126. headers: [
  127. {
  128. text: 'Key',
  129. align: 'left',
  130. value: 'key',
  131. sortable: false
  132. },
  133. {
  134. text: 'Value',
  135. align: 'left',
  136. value: 'value',
  137. sortable: false
  138. },
  139. {
  140. text: 'Actions',
  141. value: 'actions',
  142. sortable: false
  143. }
  144. ],
  145. dialog: false,
  146. valid: false,
  147. editedIndex: -1,
  148. editedItem: {
  149. 'key': '',
  150. 'value': ''
  151. },
  152. defaultItem: {
  153. 'key': '',
  154. 'value': ''
  155. },
  156. items: [] as string[],
  157. mdiPencil,
  158. mdiDelete
  159. }
  160. },
  161. methods: {
  162. editItem(item: {'key': string, 'value': string}) {
  163. this.editedIndex = this.value.indexOf(item)
  164. this.editedItem = Object.assign({}, item)
  165. this.dialog = true
  166. },
  167. deleteItem(item: {'key': string, 'value': string}) {
  168. this.editedIndex = this.value.indexOf(item)
  169. this.editedItem = Object.assign({}, item)
  170. const items = Object.assign([], this.value)
  171. items.splice(this.editedIndex, 1)
  172. this.editedItem = Object.assign({}, this.defaultItem)
  173. this.editedIndex = -1
  174. this.$emit('input', items)
  175. },
  176. close() {
  177. this.dialog = false
  178. this.$nextTick(() => {
  179. this.editedItem = Object.assign({}, this.defaultItem)
  180. this.editedIndex = -1
  181. })
  182. },
  183. save() {
  184. const items = Object.assign([], this.value)
  185. if (this.editedIndex > -1) {
  186. Object.assign(items[this.editedIndex], this.editedItem)
  187. } else {
  188. items.push(this.editedItem)
  189. }
  190. this.close()
  191. this.$emit('input', items)
  192. }
  193. }
  194. })
  195. </script>
  196. <style scoped>
  197. .toolbar-control >>> .v-toolbar__content {
  198. padding: 0px !important;
  199. }
  200. </style>