Skip to content
Snippets Groups Projects

Add custom headers form to streaming audit events

2 files
+ 84
49
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -9,6 +9,7 @@ import {
@@ -9,6 +9,7 @@ import {
GlSprintf,
GlSprintf,
GlTableLite,
GlTableLite,
} from '@gitlab/ui';
} from '@gitlab/ui';
 
import { cloneDeep } from 'lodash';
import createFlash from '~/flash';
import createFlash from '~/flash';
import { thWidthPercent } from '~/lib/utils/table_utility';
import { thWidthPercent } from '~/lib/utils/table_utility';
import externalAuditEventDestinationCreate from '../../graphql/create_external_destination.mutation.graphql';
import externalAuditEventDestinationCreate from '../../graphql/create_external_destination.mutation.graphql';
@@ -16,7 +17,6 @@ import {
@@ -16,7 +17,6 @@ import {
ADD_STREAM_EDITOR_I18N,
ADD_STREAM_EDITOR_I18N,
AUDIT_STREAMS_NETWORK_ERRORS,
AUDIT_STREAMS_NETWORK_ERRORS,
BLANK_CUSTOM_HEADER_OBJECT,
BLANK_CUSTOM_HEADER_OBJECT,
CUSTOM_HEADER_INPUT_TYPE,
MAX_CUSTOM_HEADERS,
MAX_CUSTOM_HEADERS,
} from '../../constants';
} from '../../constants';
@@ -38,13 +38,19 @@ export default {
@@ -38,13 +38,19 @@ export default {
return {
return {
destinationUrl: '',
destinationUrl: '',
loading: false,
loading: false,
customHeaders: [{ ...BLANK_CUSTOM_HEADER_OBJECT }],
customHeaders: [cloneDeep(BLANK_CUSTOM_HEADER_OBJECT)],
};
};
},
},
computed: {
computed: {
hasMaxCustomHeaders() {
hasMaxCustomHeaders() {
return this.customHeaders.length === MAX_CUSTOM_HEADERS;
return this.customHeaders.length === MAX_CUSTOM_HEADERS;
},
},
 
isSubmitButtonDisabled() {
 
return (
 
!this.destinationUrl ||
 
this.customHeaders.filter((header) => header.validationErrors.name !== '').length > 0
 
);
 
},
},
},
methods: {
methods: {
async addDestinationUrl() {
async addDestinationUrl() {
@@ -81,27 +87,13 @@ export default {
@@ -81,27 +87,13 @@ export default {
isRowFilled(index) {
isRowFilled(index) {
return this.customHeaders[index].name !== '' && this.customHeaders[index].value !== '';
return this.customHeaders[index].name !== '' && this.customHeaders[index].value !== '';
},
},
 
headerNameExists(value) {
 
return this.customHeaders.filter((header) => header.name === value).length;
 
},
addBlankCustomHeader() {
addBlankCustomHeader() {
this.customHeaders.push({ ...BLANK_CUSTOM_HEADER_OBJECT });
this.customHeaders.push(cloneDeep(BLANK_CUSTOM_HEADER_OBJECT));
},
},
updateCustomHeader(index, type, value) {
checkIfNewRowNeeded(index) {
switch (type) {
case CUSTOM_HEADER_INPUT_TYPE.HEADER:
this.customHeaders[index].name = value;
break;
case CUSTOM_HEADER_INPUT_TYPE.VALUE:
this.customHeaders[index].value = value;
break;
case CUSTOM_HEADER_INPUT_TYPE.ACTIVE:
this.customHeaders[index].active = value;
break;
default:
break;
}
// If the maximum custom headers hasn't been reached,
// If the maximum custom headers hasn't been reached,
// the previous row is filled out
// the previous row is filled out
// and we're updating the last row in the table
// and we're updating the last row in the table
@@ -114,6 +106,25 @@ export default {
@@ -114,6 +106,25 @@ export default {
this.addBlankCustomHeader();
this.addBlankCustomHeader();
}
}
},
},
 
updateCustomHeaderName(index, value) {
 
if (value !== '' && this.headerNameExists(value)) {
 
this.customHeaders[index].validationErrors.name =
 
ADD_STREAM_EDITOR_I18N.HEADER_INPUT_DUPLICATE_ERROR;
 
} else {
 
this.customHeaders[index].validationErrors.name = '';
 
this.customHeaders[index].name = value;
 
}
 
 
this.checkIfNewRowNeeded(index);
 
},
 
updateCustomHeaderValue(index, value) {
 
this.customHeaders[index].value = value;
 
 
this.checkIfNewRowNeeded(index);
 
},
 
updateCustomHeaderActive(index, value) {
 
this.customHeaders[index].active = value;
 
},
removeCustomHeader(index) {
removeCustomHeader(index) {
this.customHeaders.splice(index, 1);
this.customHeaders.splice(index, 1);
const headersCount = this.customHeaders.length;
const headersCount = this.customHeaders.length;
@@ -125,28 +136,32 @@ export default {
@@ -125,28 +136,32 @@ export default {
},
},
},
},
i18n: { ...ADD_STREAM_EDITOR_I18N, CREATING_ERROR },
i18n: { ...ADD_STREAM_EDITOR_I18N, CREATING_ERROR },
CUSTOM_HEADER_INPUT_TYPE,
MAX_CUSTOM_HEADERS,
MAX_CUSTOM_HEADERS,
fields: [
fields: [
{
{
key: 'name',
key: 'name',
label: ADD_STREAM_EDITOR_I18N.TABLE_COLUMN_NAME_LABEL,
label: ADD_STREAM_EDITOR_I18N.TABLE_COLUMN_NAME_LABEL,
thClass: ['gl-p-3!', thWidthPercent(40)],
thClass: ['gl-border-top-0!', 'gl-p-3!', thWidthPercent(40)],
tdClass: ['gl-p-3!'],
tdClass: ['gl-p-3!'],
},
},
{
{
key: 'value',
key: 'value',
label: ADD_STREAM_EDITOR_I18N.TABLE_COLUMN_VALUE_LABEL,
label: ADD_STREAM_EDITOR_I18N.TABLE_COLUMN_VALUE_LABEL,
thClass: ['gl-p-3!', thWidthPercent(50)],
thClass: ['gl-border-top-0!', 'gl-p-3!', thWidthPercent(50)],
tdClass: ['gl-p-3!'],
tdClass: ['gl-p-3!'],
},
},
{
{
key: 'active',
key: 'active',
label: ADD_STREAM_EDITOR_I18N.TABLE_COLUMN_ACTIVE_LABEL,
label: ADD_STREAM_EDITOR_I18N.TABLE_COLUMN_ACTIVE_LABEL,
thClass: ['gl-p-3!', thWidthPercent(5)],
thClass: ['gl-border-top-0!', 'gl-p-3!', thWidthPercent(5)],
tdClass: ['gl-p-3!'],
tdClass: ['gl-p-3!'],
},
},
{ key: 'actions', label: '', thClass: ['gl-p-3!'], tdClass: ['gl-p-3! gl-text-right'] },
{
 
key: 'actions',
 
label: '',
 
thClass: ['gl-border-top-0!', 'gl-p-3!'],
 
tdClass: ['gl-p-3! gl-text-right'],
 
},
],
],
};
};
</script>
</script>
@@ -170,30 +185,48 @@ export default {
@@ -170,30 +185,48 @@ export default {
/>
/>
</gl-form-group>
</gl-form-group>
<gl-form-group v-if="showStreamsCustomHeaders" :label="$options.i18n.CUSTOM_HEADERS_LABEL">
<div v-if="showStreamsCustomHeaders" class="gl-mb-5">
<gl-table-lite :items="customHeaders" :fields="$options.fields" primary-key="name">
<strong class="gl-display-block gl-mb-3">{{ $options.i18n.CUSTOM_HEADERS_LABEL }}</strong>
<template #cell(name)="{ index, item: { disabled = false } }">
<gl-table-lite :items="customHeaders" :fields="$options.fields">
<gl-form-input
<template
value=""
#cell(name)="{
:placeholder="$options.i18n.HEADER_INPUT_PLACEHOLDER"
index,
:disabled="disabled"
item: {
@input="updateCustomHeader(index, $options.CUSTOM_HEADER_INPUT_TYPE.HEADER, $event)"
disabled = false,
/>
validationErrors: { name: feedback = '' },
 
},
 
}"
 
>
 
<gl-form-group
 
class="gl-m-0"
 
label-class="gl-m-0! gl-p-0!"
 
:invalid-feedback="feedback"
 
>
 
<gl-form-input
 
value=""
 
:placeholder="$options.i18n.HEADER_INPUT_PLACEHOLDER"
 
:disabled="disabled"
 
:state="feedback === ''"
 
@input="updateCustomHeaderName(index, $event)"
 
/>
 
</gl-form-group>
</template>
</template>
<template #cell(value)="{ index, item: { disabled = false } }">
<template #cell(value)="{ index, item: { disabled = false } }">
<gl-form-input
<gl-form-group class="gl-m-0" label-class="gl-m-0! gl-p-0!">
value=""
<gl-form-input
:placeholder="$options.i18n.VALUE_INPUT_PLACEHOLDER"
value=""
:disabled="disabled"
:placeholder="$options.i18n.VALUE_INPUT_PLACEHOLDER"
@input="updateCustomHeader(index, $options.CUSTOM_HEADER_INPUT_TYPE.VALUE, $event)"
:disabled="disabled"
/>
@input="updateCustomHeaderValue(index, $event)"
 
/>
 
</gl-form-group>
</template>
</template>
<template #cell(active)="{ index }">
<template #cell(active)="{ index }">
<gl-form-checkbox
<gl-form-checkbox
class="gl-mt-3"
class="gl-mt-3"
:checked="false"
:checked="false"
:disabled="true"
:disabled="true"
@input="updateCustomHeader(index, $options.CUSTOM_HEADER_INPUT_TYPE.ACTIVE, $event)"
@input="updateCustomHeaderActive(index, $event)"
/>
/>
</template>
</template>
<template #cell(actions)="{ index }">
<template #cell(actions)="{ index }">
@@ -207,11 +240,11 @@ export default {
@@ -207,11 +240,11 @@ export default {
</template>
</template>
</gl-sprintf>
</gl-sprintf>
</p>
</p>
</gl-form-group>
</div>
<div class="gl-display-flex">
<div class="gl-display-flex">
<gl-button
<gl-button
:disabled="!destinationUrl"
:disabled="isSubmitButtonDisabled"
:loading="loading"
:loading="loading"
:name="$options.i18n.ADD_BUTTON_NAME"
:name="$options.i18n.ADD_BUTTON_NAME"
class="gl-mr-3"
class="gl-mr-3"
Loading