LocationEditor.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <script setup lang="ts">
  2. import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
  3. import Draggable from 'vuedraggable'
  4. import CodeEditor from '@/components/CodeEditor'
  5. import type { NgxConfig, NgxLocation } from '@/api/ngx'
  6. const props = defineProps<{
  7. locations?: NgxLocation[]
  8. readonly?: boolean
  9. currentServerIndex?: number
  10. }>()
  11. const ngx_config = inject('ngx_config') as NgxConfig
  12. const location = reactive({
  13. comments: '',
  14. path: '',
  15. content: '',
  16. })
  17. const adding = ref(false)
  18. function add() {
  19. adding.value = true
  20. location.comments = ''
  21. location.path = ''
  22. location.content = ''
  23. }
  24. function save() {
  25. adding.value = false
  26. ngx_config.servers[props.currentServerIndex!].locations?.push({
  27. ...location,
  28. })
  29. }
  30. function remove(index: number) {
  31. ngx_config.servers[props.currentServerIndex!].locations?.splice(index, 1)
  32. }
  33. </script>
  34. <template>
  35. <h3>{{ $gettext('Locations') }}</h3>
  36. <AEmpty v-if="!locations" />
  37. <Draggable
  38. v-else
  39. :list="locations"
  40. item-key="name"
  41. class="list-group"
  42. ghost-class="ghost"
  43. handle=".ant-collapse-header"
  44. >
  45. <template #item="{ element: v, index }">
  46. <ACollapse :bordered="false">
  47. <ACollapsePanel>
  48. <template #header>
  49. <div>
  50. <HolderOutlined />
  51. {{ $gettext('Location') }}
  52. {{ v.path }}
  53. </div>
  54. </template>
  55. <template
  56. v-if="!readonly"
  57. #extra
  58. >
  59. <APopconfirm
  60. :title="$gettext('Are you sure you want to remove this location?')"
  61. :ok-text="$gettext('Yes')"
  62. :cancel-text="$gettext('No')"
  63. @confirm="remove(index)"
  64. >
  65. <AButton
  66. type="text"
  67. size="small"
  68. >
  69. <template #icon>
  70. <DeleteOutlined style="font-size: 14px;" />
  71. </template>
  72. </AButton>
  73. </APopconfirm>
  74. </template>
  75. <AForm layout="vertical">
  76. <AFormItem :label="$gettext('Comments')">
  77. <ATextarea
  78. v-model:value="v.comments"
  79. :bordered="false"
  80. />
  81. </AFormItem>
  82. <AFormItem :label="$gettext('Path')">
  83. <AInput
  84. v-model:value="v.path"
  85. addon-before="location"
  86. />
  87. </AFormItem>
  88. <AFormItem :label="$gettext('Content')">
  89. <CodeEditor
  90. v-model:content="v.content"
  91. default-height="200px"
  92. style="width: 100%;"
  93. />
  94. </AFormItem>
  95. </AForm>
  96. </ACollapsePanel>
  97. </ACollapse>
  98. </template>
  99. </Draggable>
  100. <AModal
  101. v-model:open="adding"
  102. :title="$gettext('Add Location')"
  103. @ok="save"
  104. >
  105. <AForm layout="vertical">
  106. <AFormItem :label="$gettext('Comments')">
  107. <ATextarea v-model:value="location.comments" />
  108. </AFormItem>
  109. <AFormItem :label="$gettext('Path')">
  110. <AInput
  111. v-model:value="location.path"
  112. addon-before="location"
  113. />
  114. </AFormItem>
  115. <AFormItem :label="$gettext('Content')">
  116. <CodeEditor
  117. v-model:content="location.content"
  118. default-height="200px"
  119. />
  120. </AFormItem>
  121. </AForm>
  122. </AModal>
  123. <div v-if="!readonly">
  124. <AButton
  125. block
  126. @click="add"
  127. >
  128. {{ $gettext('Add Location') }}
  129. </AButton>
  130. </div>
  131. </template>
  132. <style lang="less" scoped>
  133. .ant-collapse {
  134. margin: 10px 0;
  135. }
  136. .ant-collapse-item {
  137. border: 0 !important;
  138. }
  139. .ant-collapse-header {
  140. align-items: center;
  141. }
  142. </style>