Files
nimbus/resources/js/components/domain/Client/Request/RequestHeader/RequestHeaders.vue
Mazen Touati 8780a79557 feat: persist UI state (#32)
* feat: persist UI state

* test: fix var declaration

* test: increate e2e timeout

sometimes there might be a network latency to load CDN assets like the fonts. Let's give the tests a maximum of 1 minute to fully run.
2026-01-11 01:32:57 +01:00

129 lines
3.8 KiB
Vue

<script setup lang="ts">
import KeyValueParametersBuilder from '@/components/common/KeyValueParameters/KeyValueParameters.vue';
import PanelSubHeader from '@/components/layout/PanelSubHeader/PanelSubHeader.vue';
import {
GeneratorType,
PendingRequest,
RequestHeader,
SourceGlobalHeaders,
} from '@/interfaces/http';
import { ParametersExternalContract } from '@/interfaces/ui';
import { useConfigStore, useRequestStore, useValueGeneratorStore } from '@/stores';
import { computed, onBeforeMount, ref, watch } from 'vue';
const requestStore = useRequestStore();
const configStore = useConfigStore();
const valueGeneratorStore = useValueGeneratorStore();
const headers = ref<RequestHeader[]>([]);
const pendingRequestData = computed(() => requestStore.pendingRequestData);
let globalHeaders: RequestHeader[] = [];
/**
* Converts RequestHeader[] to ParameterContractShape[] for the KeyValueParameters component.
*/
const headersAsParameters = computed({
get: (): ParametersExternalContract[] => {
return headers.value.map((header: RequestHeader) => ({
type: 'text',
key: header.key,
value: String(header.value),
}));
},
set: (parameters: ParametersExternalContract[]) => {
headers.value = parameters.map(
(parameter: ParametersExternalContract): RequestHeader => ({
key: parameter.key,
value: parameter.value as string | number | boolean | null,
}),
);
},
});
const generateValue = (value: GeneratorType): string => {
switch (value) {
case GeneratorType.Uuid:
return valueGeneratorStore.generateValue('uuid') as string;
case GeneratorType.Email:
return valueGeneratorStore.generateValue('email') as string;
case GeneratorType.String:
return valueGeneratorStore.generateValue('word') as string;
default:
return valueGeneratorStore.generateValue('word') as string;
}
};
const syncHeadersWithPendingRequest = () => {
if (pendingRequestData.value === null) {
return;
}
requestStore.updateRequestHeaders(
headers.value.filter((header: RequestHeader) => header.value !== null),
);
};
const enrichWithGlobalHeaders = (pendingRequest: PendingRequest | null) => {
const currentHeaders = pendingRequest?.headers ?? [];
const currentHeaderKeys = currentHeaders.map((header: RequestHeader) => header.key);
const missingGlobalHeaders = globalHeaders.filter(
(header: RequestHeader) => !currentHeaderKeys.includes(header.key),
);
headers.value = [...missingGlobalHeaders, ...currentHeaders];
};
/*
* Watchers.
*/
watch(headers, () => syncHeadersWithPendingRequest(), { deep: true });
watch(
pendingRequestData,
(newValue, oldValue) => {
// Only reinitialize if endpoint actually changed
if (
newValue?.endpoint === oldValue?.endpoint &&
newValue?.method === oldValue?.method
) {
return;
}
enrichWithGlobalHeaders(oldValue);
},
{ deep: true },
);
/*
* Lifecycle.
*/
onBeforeMount(() => {
globalHeaders = configStore.headers.map(
(globalHeader: SourceGlobalHeaders): RequestHeader => ({
key: globalHeader.header,
value:
globalHeader.type === 'generator'
? generateValue(globalHeader.value as GeneratorType)
: globalHeader.value,
}),
);
enrichWithGlobalHeaders(pendingRequestData.value);
});
</script>
<template>
<PanelSubHeader class="border-b">Request Headers</PanelSubHeader>
<KeyValueParametersBuilder
ref="parametersBuilder"
v-model="headersAsParameters"
persistence-key="pending-request-headers"
/>
</template>