LocationEditor.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <script setup lang="ts">
  2. import CodeEditor from '@/components/CodeEditor'
  3. import {useGettext} from 'vue3-gettext'
  4. import {reactive, ref} from 'vue'
  5. import {DeleteOutlined, HolderOutlined} from '@ant-design/icons-vue'
  6. import draggable from 'vuedraggable'
  7. const {$gettext} = useGettext()
  8. const props = defineProps(['locations', 'readonly'])
  9. let location = reactive({
  10. comments: '',
  11. path: '',
  12. content: ''
  13. })
  14. const adding = ref(false)
  15. function add() {
  16. adding.value = true
  17. location.comments = ''
  18. location.path = ''
  19. location.content = ''
  20. }
  21. function save() {
  22. adding.value = false
  23. props.locations?.push({
  24. ...location
  25. })
  26. }
  27. function remove(index: number) {
  28. props.locations?.splice(index, 1)
  29. }
  30. </script>
  31. <template>
  32. <h2 v-translate>Locations</h2>
  33. <a-empty v-if="!locations"/>
  34. <draggable
  35. v-else
  36. :list="locations"
  37. item-key="name"
  38. class="list-group"
  39. ghost-class="ghost"
  40. handle=".ant-collapse-header"
  41. >
  42. <template #item="{ element: v, index }">
  43. <a-collapse :bordered="false">
  44. <a-collapse-panel>
  45. <template #header>
  46. <div>
  47. <HolderOutlined/>
  48. {{ $gettext('Location') }}
  49. {{ v.path }}
  50. </div>
  51. </template>
  52. <template #extra v-if="!readonly">
  53. <a-popconfirm @confirm="remove(index)"
  54. :title="$gettext('Are you sure you want to remove this location?')"
  55. :ok-text="$gettext('Yes')"
  56. :cancel-text="$gettext('No')">
  57. <a-button type="text" size="small">
  58. <template #icon>
  59. <DeleteOutlined style="font-size: 14px;"/>
  60. </template>
  61. </a-button>
  62. </a-popconfirm>
  63. </template>
  64. <a-form layout="vertical">
  65. <a-form-item :label="$gettext('Comments')">
  66. <a-textarea v-model:value="v.comments" :bordered="false"/>
  67. </a-form-item>
  68. <a-form-item :label="$gettext('Path')">
  69. <a-input addon-before="location" v-model:value="v.path"/>
  70. </a-form-item>
  71. <a-form-item :label="$gettext('Content')">
  72. <code-editor v-model:content="v.content" default-height="200px" style="width: 100%;"/>
  73. </a-form-item>
  74. </a-form>
  75. </a-collapse-panel>
  76. </a-collapse>
  77. </template>
  78. </draggable>
  79. <a-modal :title="$gettext('Add Location')" v-model:visible="adding" @ok="save">
  80. <a-form layout="vertical">
  81. <a-form-item :label="$gettext('Comments')">
  82. <a-textarea v-model:value="location.comments"/>
  83. </a-form-item>
  84. <a-form-item :label="$gettext('Path')">
  85. <a-input addon-before="location" v-model:value="location.path"/>
  86. </a-form-item>
  87. <a-form-item :label="$gettext('Content')">
  88. <code-editor v-model:content="location.content" default-height="200px"/>
  89. </a-form-item>
  90. </a-form>
  91. </a-modal>
  92. <div v-if="!readonly">
  93. <a-button block @click="add">{{ $gettext('Add Location') }}</a-button>
  94. </div>
  95. </template>
  96. <style lang="less" scoped>
  97. .ant-collapse {
  98. margin: 10px 0;
  99. }
  100. .ant-collapse-item {
  101. border: 0 !important;
  102. }
  103. .ant-collapse-header {
  104. align-items: center;
  105. }
  106. </style>