StreamEditor.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <script lang="ts" setup>
  2. import { HistoryOutlined, LoadingOutlined } from '@ant-design/icons-vue'
  3. import CodeEditor from '@/components/CodeEditor'
  4. import ConfigHistory from '@/components/ConfigHistory'
  5. import FooterToolBar from '@/components/FooterToolbar'
  6. import NgxConfigEditor from '@/components/NgxConfigEditor'
  7. import UpstreamCards from '@/components/UpstreamCards/UpstreamCards.vue'
  8. import { ConfigStatus } from '@/constants'
  9. import { useStreamEditorStore } from '../store'
  10. const router = useRouter()
  11. const { message } = App.useApp()
  12. const store = useStreamEditorStore()
  13. const { name, status, configText, filepath, saving, parseErrorStatus, parseErrorMessage, advanceMode, loading, data } = storeToRefs(store)
  14. const showHistory = ref(false)
  15. // Get upstream targets from backend API data
  16. const upstreamTargets = computed(() => {
  17. return data.value.proxy_targets || []
  18. })
  19. async function save() {
  20. try {
  21. await store.save()
  22. message.success($gettext('Saved successfully'))
  23. }
  24. catch {
  25. // do nothing
  26. }
  27. }
  28. </script>
  29. <template>
  30. <ASpin :spinning="loading" :indicator="LoadingOutlined">
  31. <ACard class="mb-4" :bordered="false">
  32. <template #title>
  33. <span style="margin-right: 10px">{{ $gettext('Edit %{n}', { n: name }) }}</span>
  34. <ATag
  35. v-if="status === ConfigStatus.Enabled"
  36. color="blue"
  37. >
  38. {{ $gettext('Enabled') }}
  39. </ATag>
  40. <ATag
  41. v-else
  42. color="orange"
  43. >
  44. {{ $gettext('Disabled') }}
  45. </ATag>
  46. </template>
  47. <template #extra>
  48. <ASpace>
  49. <AButton
  50. v-if="filepath"
  51. type="link"
  52. @click="showHistory = true"
  53. >
  54. <template #icon>
  55. <HistoryOutlined />
  56. </template>
  57. {{ $gettext('History') }}
  58. </AButton>
  59. <div class="mode-switch">
  60. <div class="switch">
  61. <ASwitch
  62. size="small"
  63. :disabled="parseErrorStatus"
  64. :checked="advanceMode"
  65. @change="store.handleModeChange"
  66. />
  67. </div>
  68. <template v-if="advanceMode">
  69. <div>{{ $gettext('Advance Mode') }}</div>
  70. </template>
  71. <template v-else>
  72. <div>{{ $gettext('Basic Mode') }}</div>
  73. </template>
  74. </div>
  75. </ASpace>
  76. </template>
  77. <div class="card-body">
  78. <Transition name="slide-fade">
  79. <div
  80. v-if="advanceMode"
  81. key="advance"
  82. >
  83. <div v-if="parseErrorStatus">
  84. <AAlert
  85. banner
  86. :message="$gettext('Nginx Configuration Parse Error')"
  87. :description="parseErrorMessage"
  88. type="error"
  89. show-icon
  90. />
  91. </div>
  92. <div>
  93. <CodeEditor
  94. v-model:content="configText"
  95. no-border-radius
  96. />
  97. </div>
  98. </div>
  99. <div
  100. v-else
  101. key="basic"
  102. class="domain-edit-container"
  103. >
  104. <!-- Upstream Cards Display -->
  105. <UpstreamCards
  106. :targets="upstreamTargets"
  107. :namespace-id="data.namespace_id"
  108. />
  109. <NgxConfigEditor
  110. :enabled="status === ConfigStatus.Enabled"
  111. context="stream"
  112. />
  113. </div>
  114. </Transition>
  115. </div>
  116. <ConfigHistory
  117. v-model:visible="showHistory"
  118. v-model:current-content="configText"
  119. :filepath="filepath"
  120. />
  121. <FooterToolBar>
  122. <ASpace>
  123. <AButton @click="router.push('/streams')">
  124. {{ $gettext('Back') }}
  125. </AButton>
  126. <AButton
  127. type="primary"
  128. :loading="saving"
  129. @click="save"
  130. >
  131. {{ $gettext('Save') }}
  132. </AButton>
  133. </ASpace>
  134. </FooterToolBar>
  135. </ACard>
  136. </ASpin>
  137. </template>
  138. <style scoped lang="less">
  139. .mode-switch {
  140. display: flex;
  141. .switch {
  142. display: flex;
  143. align-items: center;
  144. margin-right: 5px;
  145. }
  146. }
  147. .domain-edit-container {
  148. max-width: 800px;
  149. margin: 0 auto;
  150. }
  151. :deep(.tab-content) {
  152. padding-bottom: 24px;
  153. }
  154. </style>