Create.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <base-dialog :width="700" @cancel="cancelDialog">
  3. <div slot="header">{{ $t('common.create') }} - {{ $t('aice.container_secret') }}</div>
  4. <div slot="body">
  5. <a-form :form="form.fc" hideRequiredMark v-bind="formItemLayout">
  6. <a-form-item :label="$t('common.name')">
  7. <a-input
  8. v-decorator="decorators.name"
  9. :placeholder="$t('common.tips.input', [$t('common.name')])" />
  10. </a-form-item>
  11. <a-form-item :label="$t('aice.container_secret')" :extra="$t('aice.container_secret.env_hint') + ' ' + $t('aice.container_secret.add_pair')">
  12. <div v-for="(item, index) in items" :key="item.id" class="d-flex align-items-start mb-2">
  13. <a-input
  14. v-model="item.key"
  15. :placeholder="$t('aice.container_secret.key')"
  16. class="mr-2"
  17. style="flex: 1; min-width: 0" />
  18. <span class="mr-2 mt-2">=</span>
  19. <a-input
  20. v-model="item.value"
  21. :placeholder="$t('aice.container_secret.value')"
  22. class="mr-2"
  23. style="flex: 1; min-width: 0" />
  24. <a-button
  25. type="danger"
  26. shape="circle"
  27. icon="delete"
  28. size="small"
  29. class="mt-1"
  30. :disabled="items.length <= 1"
  31. @click="removeRow(index)" />
  32. </div>
  33. <a-button type="dashed" block icon="plus" @click="addRow">
  34. {{ $t('aice.container_secret.add_pair') }}
  35. </a-button>
  36. <div v-if="blobError" class="text-danger mt-1">{{ blobError }}</div>
  37. </a-form-item>
  38. </a-form>
  39. </div>
  40. <div slot="footer">
  41. <a-button type="primary" :loading="loading" @click="handleConfirm">{{ $t('dialog.ok') }}</a-button>
  42. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  43. </div>
  44. </base-dialog>
  45. </template>
  46. <script>
  47. import { uuid } from '@/utils/utils'
  48. import DialogMixin from '@/mixins/dialog'
  49. import WindowsMixin from '@/mixins/windows'
  50. export default {
  51. name: 'ContainerSecretCreateDialog',
  52. mixins: [DialogMixin, WindowsMixin],
  53. data () {
  54. return {
  55. loading: false,
  56. blobError: '',
  57. items: [
  58. { id: uuid(), key: '', value: '' },
  59. ],
  60. form: {
  61. fc: this.$form.createForm(this, {
  62. onValuesChange: (props, values) => {
  63. Object.keys(values).forEach((key) => {
  64. this.$set(this.form.fd, key, values[key])
  65. })
  66. },
  67. }),
  68. fd: {},
  69. },
  70. decorators: {
  71. name: [
  72. 'name',
  73. {
  74. rules: [
  75. { required: true, message: this.$t('common.tips.input', [this.$t('common.name')]) },
  76. ],
  77. },
  78. ],
  79. },
  80. formItemLayout: {
  81. wrapperCol: { span: 20 },
  82. labelCol: { span: 4 },
  83. },
  84. }
  85. },
  86. methods: {
  87. addRow () {
  88. this.items.push({ id: uuid(), key: '', value: '' })
  89. this.blobError = ''
  90. },
  91. removeRow (index) {
  92. if (this.items.length <= 1) return
  93. this.items.splice(index, 1)
  94. this.blobError = ''
  95. },
  96. buildBlob () {
  97. const blob = {}
  98. for (const item of this.items) {
  99. const k = (item.key || '').trim()
  100. const v = (item.value || '').trim()
  101. if (k) blob[k] = v
  102. }
  103. return blob
  104. },
  105. async handleConfirm () {
  106. this.blobError = ''
  107. const values = await this.form.fc.validateFields().catch(() => null)
  108. if (!values) return
  109. const blob = this.buildBlob()
  110. if (Object.keys(blob).length === 0) {
  111. this.blobError = this.$t('common.tips.input', [this.$t('aice.container_secret')])
  112. return
  113. }
  114. this.loading = true
  115. try {
  116. const manager = new this.$Manager('credentials', 'v1')
  117. const createData = {
  118. type: 'container_secret',
  119. name: values.name || '',
  120. blob,
  121. }
  122. if (this.$store.getters.scope === 'project') {
  123. const uid = this.$store.getters.userInfo?.id
  124. if (uid) createData.user_id = uid
  125. }
  126. await manager.create({ data: createData })
  127. this.$message.success(this.$t('common.success'))
  128. this.params.callback && this.params.callback()
  129. this.cancelDialog()
  130. } catch (e) {
  131. throw e
  132. } finally {
  133. this.loading = false
  134. }
  135. },
  136. },
  137. }
  138. </script>
  139. <style scoped>
  140. .mr-2 {
  141. margin-right: 8px;
  142. }
  143. .mb-2 {
  144. margin-bottom: 8px;
  145. }
  146. .mt-1 {
  147. margin-top: 4px;
  148. }
  149. .mt-2 {
  150. margin-top: 8px;
  151. }
  152. </style>