fix: persist headers across endpoints (#6)

* refactor: config are not reactive

* fix: persist headers across endpoints

make sure the UI and request builder are truly in sync
This commit is contained in:
Mazen Touati
2025-11-04 18:41:37 +01:00
committed by GitHub
parent da56fd3070
commit 47e94ca206
2 changed files with 48 additions and 57 deletions

View File

@@ -1,7 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import KeyValueParametersBuilder from '@/components/common/KeyValueParameters/KeyValueParameters.vue'; import KeyValueParametersBuilder from '@/components/common/KeyValueParameters/KeyValueParameters.vue';
import PanelSubHeader from '@/components/layout/PanelSubHeader/PanelSubHeader.vue'; import PanelSubHeader from '@/components/layout/PanelSubHeader/PanelSubHeader.vue';
import { GeneratorType, RequestHeader, SourceGlobalHeaders } from '@/interfaces/http'; import {
GeneratorType,
PendingRequest,
RequestHeader,
SourceGlobalHeaders,
} from '@/interfaces/http';
import { ParametersExternalContract } from '@/interfaces/ui'; import { ParametersExternalContract } from '@/interfaces/ui';
import { useConfigStore, useRequestStore, useValueGeneratorStore } from '@/stores'; import { useConfigStore, useRequestStore, useValueGeneratorStore } from '@/stores';
import { computed, onBeforeMount, ref, watch } from 'vue'; import { computed, onBeforeMount, ref, watch } from 'vue';
@@ -14,17 +19,7 @@ const headers = ref<RequestHeader[]>([]);
const pendingRequestData = computed(() => requestStore.pendingRequestData); const pendingRequestData = computed(() => requestStore.pendingRequestData);
const globalHeaders = computed(() => { let globalHeaders: RequestHeader[] = [];
return configStore.headers.map(
(globalHeader: SourceGlobalHeaders): RequestHeader => ({
key: globalHeader.header,
value:
globalHeader.type === 'generator'
? generateValue(globalHeader.value as GeneratorType)
: globalHeader.value,
}),
);
});
/** /**
* Converts RequestHeader[] to ParameterContractShape[] for the KeyValueParameters component. * Converts RequestHeader[] to ParameterContractShape[] for the KeyValueParameters component.
@@ -70,12 +65,15 @@ const syncHeadersWithPendingRequest = () => {
); );
}; };
const initializeHeaders = () => { const initializeHeaders = (previousPendingData: PendingRequest | null = null) => {
// TODO [Enhancement] De-dupe the list. const previousHeaders = previousPendingData?.headers ?? [];
headers.value = [ const previousHeaderKeys = previousHeaders.map((header: RequestHeader) => header.key);
...globalHeaders.value,
...(pendingRequestData.value?.headers ?? []), const missingGlobalHeaders = globalHeaders.filter(
]; (header: RequestHeader) => !previousHeaderKeys.includes(header.key),
);
headers.value = [...missingGlobalHeaders, ...previousHeaders];
}; };
/* /*
@@ -95,7 +93,7 @@ watch(
return; return;
} }
initializeHeaders(); initializeHeaders(oldValue);
}, },
{ deep: true }, { deep: true },
); );
@@ -105,6 +103,16 @@ watch(
*/ */
onBeforeMount(() => { onBeforeMount(() => {
globalHeaders = configStore.headers.map(
(globalHeader: SourceGlobalHeaders): RequestHeader => ({
key: globalHeader.header,
value:
globalHeader.type === 'generator'
? generateValue(globalHeader.value as GeneratorType)
: globalHeader.value,
}),
);
initializeHeaders(); initializeHeaders();
}); });
</script> </script>

View File

@@ -1,52 +1,35 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { computed, ref } from 'vue';
export interface CurrentUser { export interface CurrentUser {
id: string | number; id: string | number;
} }
export interface AppConfig { export type GlobalHeadersArray = Array<{
urlBase: string; header: string;
basePath: string; type: 'raw' | 'generator';
globalHeaders: Array<{ value: string | number;
header: string; }>;
type: 'raw' | 'generator';
value: string | number;
}>;
isVersioned: boolean;
currentUser: CurrentUser | null;
}
// TODO [Refactor] convert this to a plain module.
export const useConfigStore = defineStore('config', () => { export const useConfigStore = defineStore('config', () => {
// Default configuration const urlBase = (window.Nimbus?.apiBaseUrl as string) || 'http://localhost';
const config = ref<AppConfig>({ const isVersioned = (window.Nimbus?.isVersioned as boolean) || false;
urlBase: (window.Nimbus?.apiBaseUrl as string) || 'http://localhost', const basePath = (window.Nimbus?.basePath as string) || '';
isVersioned: (window.Nimbus?.isVersioned as boolean) || false, const globalHeaders: GlobalHeadersArray = window.Nimbus?.headers
basePath: (window.Nimbus?.basePath as string) || '', ? JSON.parse(window.Nimbus.headers as string)
globalHeaders: window.Nimbus?.headers : [];
? JSON.parse(window.Nimbus.headers as string) const currentUser = window.Nimbus?.currentUser
: [], ? JSON.parse(window.Nimbus.currentUser)
currentUser: window.Nimbus?.currentUser : null;
? JSON.parse(window.Nimbus.currentUser)
: null,
});
// Computed values // Derived values
const apiUrl = computed(() => config.value.urlBase); const isLoggedIn = currentUser !== null;
const appBasePath = computed(() => config.value.basePath); const userId = currentUser?.id ?? null;
const headers = computed(() => config.value.globalHeaders);
const isVersioned = computed(() => config.value.isVersioned);
const isLoggedIn = computed(() => config.value.currentUser !== null);
const userId = computed(() => config.value.currentUser?.id ?? null);
return { return {
// State apiUrl: urlBase,
config, appBasePath: basePath,
headers: globalHeaders,
// Getters
apiUrl,
appBasePath,
headers,
isVersioned, isVersioned,
isLoggedIn, isLoggedIn,
userId, userId,