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.

206 lines
4.7 KiB

3 years ago
  1. <template>
  2. <v-data-table
  3. :headers="headers"
  4. :items="value"
  5. >
  6. <template v-slot: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 v-slot: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 v-slot:[`item.actions`]="{ item }">
  92. <v-icon
  93. small
  94. class="mr-2"
  95. @click="editItem(item)"
  96. >
  97. mdi-pencil
  98. </v-icon>
  99. <v-icon
  100. small
  101. @click="deleteItem(item)"
  102. >
  103. mdi-delete
  104. </v-icon>
  105. </template>
  106. </v-data-table>
  107. </template>
  108. <script lang="ts">
  109. import Vue from 'vue'
  110. export default Vue.extend({
  111. props: {
  112. value: {
  113. type: Array,
  114. default: () => [],
  115. required: true
  116. },
  117. title: {
  118. type: String,
  119. default: '',
  120. required: true
  121. }
  122. },
  123. data() {
  124. return {
  125. headers: [
  126. {
  127. text: 'Key',
  128. align: 'left',
  129. value: 'key',
  130. sortable: false
  131. },
  132. {
  133. text: 'Value',
  134. align: 'left',
  135. value: 'value',
  136. sortable: false
  137. },
  138. {
  139. text: 'Actions',
  140. value: 'actions',
  141. sortable: false
  142. }
  143. ],
  144. dialog: false,
  145. valid: false,
  146. editedIndex: -1,
  147. editedItem: {
  148. 'key': '',
  149. 'value': ''
  150. },
  151. defaultItem: {
  152. 'key': '',
  153. 'value': ''
  154. },
  155. items: [] as string[],
  156. }
  157. },
  158. methods: {
  159. editItem(item: {'key': string, 'value': string}) {
  160. this.editedIndex = this.value.indexOf(item)
  161. this.editedItem = Object.assign({}, item)
  162. this.dialog = true
  163. },
  164. deleteItem(item: {'key': string, 'value': string}) {
  165. this.editedIndex = this.value.indexOf(item)
  166. this.editedItem = Object.assign({}, item)
  167. const items = Object.assign([], this.value)
  168. items.splice(this.editedIndex, 1)
  169. this.editedItem = Object.assign({}, this.defaultItem)
  170. this.editedIndex = -1
  171. this.$emit('input', items)
  172. },
  173. close() {
  174. this.dialog = false
  175. this.$nextTick(() => {
  176. this.editedItem = Object.assign({}, this.defaultItem)
  177. this.editedIndex = -1
  178. })
  179. },
  180. save() {
  181. const items = Object.assign([], this.value)
  182. if (this.editedIndex > -1) {
  183. Object.assign(items[this.editedIndex], this.editedItem)
  184. } else {
  185. items.push(this.editedItem)
  186. }
  187. this.close()
  188. this.$emit('input', items)
  189. }
  190. }
  191. })
  192. </script>
  193. <style scoped>
  194. .toolbar-control >>> .v-toolbar__content {
  195. padding: 0px !important;
  196. }
  197. </style>