DirectiveAdd.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <script setup lang="ts">
  2. import type { DirectiveMap, NgxDirective } from '@/api/ngx'
  3. import CodeEditor from '@/components/CodeEditor'
  4. import { DeleteOutlined } from '@ant-design/icons-vue'
  5. const props = defineProps<{
  6. idx?: number
  7. nginxDirectivesMap?: DirectiveMap
  8. }>()
  9. const emit = defineEmits(['save'])
  10. const ngx_directives = inject('ngx_directives') as ComputedRef<NgxDirective[]>
  11. const directive = reactive({ directive: '', params: '' })
  12. const adding = ref(false)
  13. const mode = ref('default')
  14. const nginxDirectives = computed(() => {
  15. const res: { label: string, value: string }[] = []
  16. if (props.nginxDirectivesMap) {
  17. Object.keys(props.nginxDirectivesMap).forEach(k => {
  18. res.push({ label: k, value: k })
  19. })
  20. }
  21. return res
  22. })
  23. function add() {
  24. adding.value = true
  25. directive.directive = ''
  26. directive.params = ''
  27. }
  28. function save() {
  29. adding.value = false
  30. if (mode.value === 'multi-line')
  31. directive.directive = ''
  32. if (props.idx)
  33. ngx_directives.value.splice(props.idx + 1, 0, { directive: directive.directive, params: directive.params })
  34. else
  35. ngx_directives.value.push({ directive: directive.directive, params: directive.params })
  36. emit('save', props.idx)
  37. }
  38. function filterOption(inputValue: string, option: { label: string }) {
  39. return option.label.toLowerCase().includes(inputValue.toLowerCase())
  40. }
  41. </script>
  42. <template>
  43. <div>
  44. <div
  45. v-if="adding"
  46. class="add-directive-temp"
  47. >
  48. <AFormItem>
  49. <ASelect
  50. v-model:value="mode"
  51. default-value="default"
  52. style="width: 180px"
  53. >
  54. <ASelectOption value="default">
  55. {{ $gettext('Single Directive') }}
  56. </ASelectOption>
  57. <ASelectOption value="multi-line">
  58. {{ $gettext('Multi-line Directive') }}
  59. </ASelectOption>
  60. </ASelect>
  61. </AFormItem>
  62. <AFormItem>
  63. <div class="input-wrapper">
  64. <CodeEditor
  65. v-if="mode === 'multi-line'"
  66. v-model:content="directive.params"
  67. default-height="100px"
  68. style="width: 100%;"
  69. />
  70. <AInputGroup
  71. v-else
  72. compact
  73. >
  74. <AAutoComplete
  75. v-model:value="directive.directive"
  76. :options="nginxDirectives"
  77. style="width: 30%"
  78. :filter-option="filterOption"
  79. :placeholder="$gettext('Directive')"
  80. />
  81. <AInput
  82. v-model:value="directive.params"
  83. style="width: 70%"
  84. :placeholder="$gettext('Params')"
  85. />
  86. </AInputGroup>
  87. <AButton @click="adding = false">
  88. <template #icon>
  89. <DeleteOutlined style="font-size: 14px;" />
  90. </template>
  91. </AButton>
  92. </div>
  93. <div v-if="nginxDirectivesMap?.[directive.directive]" class="mt-2">
  94. <div>{{ $ngettext('Document', 'Documents', nginxDirectivesMap[directive.directive].links.length) }}</div>
  95. <a v-for="(link, index) in nginxDirectivesMap?.[directive.directive].links" :key="index" :href="link">
  96. {{ link }}
  97. </a>
  98. </div>
  99. </AFormItem>
  100. </div>
  101. <AButton
  102. v-if="!adding"
  103. block
  104. @click="add"
  105. >
  106. {{ $gettext('Add Directive Below') }}
  107. </AButton>
  108. <AButton
  109. v-else
  110. type="primary"
  111. block
  112. :disabled="(mode === 'default' && (!directive.directive || !directive.params))
  113. || (!directive.params && mode === 'multi-line')"
  114. @click="save"
  115. >
  116. {{ $gettext('Save Directive') }}
  117. </AButton>
  118. </div>
  119. </template>
  120. <style lang="less" scoped>
  121. .input-wrapper {
  122. display: flex;
  123. gap: 10px;
  124. align-items: center;
  125. }
  126. </style>