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:
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user