feat(common): mock server ui improvements (#5532)
- Update active state styles for better visibility in the mock server. - BE updates catered to improving content type handling in the mock server. - Introduced a `disableMockServerInPersonalWorkspace` platform-level feature flag. - Remove inactive keyboard shorthand nudges from the Mock server dashboard context menu. --- Co-authored-by: mirarifhasan <arif.ishan05@gmail.com> Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
parent
c73e71827a
commit
e607f9db24
9 changed files with 92 additions and 35 deletions
|
|
@ -87,6 +87,7 @@ export class MockServerController {
|
|||
try {
|
||||
const headers = JSON.parse(mockResponse.headers);
|
||||
Object.keys(headers).forEach((key) => {
|
||||
console.log('Setting header:', key, headers[key]);
|
||||
res.setHeader(key, headers[key]);
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
@ -101,17 +102,31 @@ export class MockServerController {
|
|||
);
|
||||
}
|
||||
|
||||
// Send response
|
||||
const defaultContentType =
|
||||
typeof mockResponse.body === 'object'
|
||||
? 'application/json'
|
||||
: 'text/plain';
|
||||
const contentType =
|
||||
mockResponse.headers?.['content-type'] || defaultContentType;
|
||||
// Only set Content-Type if not already set
|
||||
if (!res.getHeader('Content-Type')) {
|
||||
let defaultContentType = 'text/plain';
|
||||
|
||||
res.setHeader('Content-Type', contentType);
|
||||
// Check if body is a string and try to parse it to determine content type
|
||||
if (typeof mockResponse.body === 'string') {
|
||||
try {
|
||||
JSON.parse(mockResponse.body);
|
||||
// If parsing succeeds, it's JSON
|
||||
defaultContentType = 'application/json';
|
||||
} catch {
|
||||
// If parsing fails, it's plain text
|
||||
defaultContentType = 'text/plain';
|
||||
}
|
||||
} else if (typeof mockResponse.body === 'object') {
|
||||
// If it's already an object, it's JSON
|
||||
defaultContentType = 'application/json';
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', defaultContentType);
|
||||
}
|
||||
// Security headers
|
||||
res.setHeader('X-Content-Type-Options', 'nosniff');
|
||||
|
||||
// Send response
|
||||
return res.status(mockResponse.statusCode).send(mockResponse.body);
|
||||
} catch (error) {
|
||||
console.error('Error handling mock request:', error);
|
||||
|
|
|
|||
|
|
@ -136,8 +136,7 @@
|
|||
@keyup.t="runCollectionAction?.$el.click()"
|
||||
@keyup.s="sortAction?.$el.click()"
|
||||
@keyup.m="
|
||||
ENABLE_EXPERIMENTAL_MOCK_SERVERS &&
|
||||
mockServerAction?.$el.click()
|
||||
isMockServerVisible && mockServerAction?.$el.click()
|
||||
"
|
||||
@keyup.escape="hide()"
|
||||
>
|
||||
|
|
@ -183,7 +182,7 @@
|
|||
v-if="
|
||||
!hasNoTeamAccess &&
|
||||
isRootCollection &&
|
||||
ENABLE_EXPERIMENTAL_MOCK_SERVERS
|
||||
isMockServerVisible
|
||||
"
|
||||
ref="mockServerAction"
|
||||
:icon="IconServer"
|
||||
|
|
@ -328,7 +327,7 @@ import IconArrowUpDown from "~icons/lucide/arrow-up-down"
|
|||
import { CurrentSortValuesService } from "~/services/current-sort.service"
|
||||
import { useService } from "dioc/vue"
|
||||
import { useMockServerStatus } from "~/composables/mockServer"
|
||||
import { useSetting } from "@composables/settings"
|
||||
import { useMockServerVisibility } from "~/composables/mockServerVisibility"
|
||||
import { platform } from "~/platform"
|
||||
import { invokeAction } from "~/helpers/actions"
|
||||
|
||||
|
|
@ -464,13 +463,11 @@ const isCollectionLoading = computed(() => {
|
|||
})
|
||||
|
||||
// Mock Server Status
|
||||
const ENABLE_EXPERIMENTAL_MOCK_SERVERS = useSetting(
|
||||
"ENABLE_EXPERIMENTAL_MOCK_SERVERS"
|
||||
)
|
||||
const { isMockServerVisible } = useMockServerVisibility()
|
||||
const { getMockServerStatus } = useMockServerStatus()
|
||||
|
||||
const mockServerStatus = computed(() => {
|
||||
if (!ENABLE_EXPERIMENTAL_MOCK_SERVERS.value) {
|
||||
if (!isMockServerVisible.value) {
|
||||
return { exists: false, isActive: false }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
/>
|
||||
</HoppSmartTab>
|
||||
<HoppSmartTab
|
||||
v-if="ENABLE_EXPERIMENTAL_MOCK_SERVERS"
|
||||
v-if="isMockServerVisible"
|
||||
:id="'mock-servers'"
|
||||
:icon="IconServer"
|
||||
:label="`${t('tab.mock_servers')}`"
|
||||
|
|
@ -76,15 +76,13 @@ import IconCode from "~icons/lucide/code"
|
|||
import IconServer from "~icons/lucide/server"
|
||||
import { ref } from "vue"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useSetting } from "@composables/settings"
|
||||
import MockServerDashboard from "~/components/mockServer/MockServerDashboard.vue"
|
||||
import { useMockServerWorkspaceSync } from "~/composables/mockServerWorkspace"
|
||||
import { useMockServerVisibility } from "~/composables/mockServerVisibility"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const ENABLE_EXPERIMENTAL_MOCK_SERVERS = useSetting(
|
||||
"ENABLE_EXPERIMENTAL_MOCK_SERVERS"
|
||||
)
|
||||
const { isMockServerVisible } = useMockServerVisibility()
|
||||
|
||||
type RequestOptionTabs =
|
||||
| "history"
|
||||
|
|
|
|||
|
|
@ -134,8 +134,8 @@
|
|||
class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium"
|
||||
:class="
|
||||
existingMockServer?.isActive
|
||||
? 'bg-green-600/20 text-green-200 border border-green-900/50'
|
||||
: 'bg-gray-600/20 text-gray-200 border border-gray-900/50'
|
||||
? 'bg-green-600/20 text-green-500 border border-green-600/30'
|
||||
: 'text-secondary border border-secondaryLight'
|
||||
"
|
||||
>
|
||||
<span
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
:class="
|
||||
existingMockServer?.isActive
|
||||
? 'bg-green-400'
|
||||
: 'bg-gray-400'
|
||||
: 'bg-secondaryLight'
|
||||
"
|
||||
></span>
|
||||
{{
|
||||
|
|
|
|||
|
|
@ -68,13 +68,13 @@
|
|||
class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium"
|
||||
:class="
|
||||
isActive
|
||||
? 'bg-green-600/20 text-green-200 border border-green-900/50'
|
||||
: 'bg-gray-600/20 text-gray-200 border border-gray-900/50'
|
||||
? 'bg-green-600/20 text-green-500 border border-green-600/30'
|
||||
: 'text-secondary border border-secondaryLight'
|
||||
"
|
||||
>
|
||||
<span
|
||||
class="w-2 h-2 rounded-full mr-2"
|
||||
:class="isActive ? 'bg-green-400' : 'bg-gray-400'"
|
||||
:class="isActive ? 'bg-green-400' : 'bg-secondaryLight'"
|
||||
></span>
|
||||
{{
|
||||
isActive
|
||||
|
|
|
|||
|
|
@ -150,7 +150,6 @@
|
|||
? t('mock_server.stop_server')
|
||||
: t('mock_server.start_server')
|
||||
"
|
||||
:shortcut="['S']"
|
||||
@click="
|
||||
() => {
|
||||
toggleMockServer(mockServer)
|
||||
|
|
@ -162,7 +161,6 @@
|
|||
ref="deleteAction"
|
||||
:icon="IconTrash2"
|
||||
:label="t('action.delete')"
|
||||
:shortcut="['⌫']"
|
||||
@click="
|
||||
() => {
|
||||
deleteMockServer(mockServer)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import { computed } from "vue"
|
||||
import { useSetting } from "~/composables/settings"
|
||||
import { platform } from "~/platform"
|
||||
import { useService } from "dioc/vue"
|
||||
import { WorkspaceService } from "~/services/workspace.service"
|
||||
|
||||
/**
|
||||
* Composable to determine mock server visibility based on experimental flags and platform configuration
|
||||
*/
|
||||
export function useMockServerVisibility() {
|
||||
const ENABLE_EXPERIMENTAL_MOCK_SERVERS = useSetting(
|
||||
"ENABLE_EXPERIMENTAL_MOCK_SERVERS"
|
||||
)
|
||||
|
||||
const workspaceService = useService(WorkspaceService)
|
||||
|
||||
/**
|
||||
* Check if mock servers should be visible based on experimental flag and platform configuration
|
||||
*/
|
||||
const isMockServerVisible = computed(() => {
|
||||
// First check if experimental mock servers are enabled
|
||||
if (!ENABLE_EXPERIMENTAL_MOCK_SERVERS.value) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if platform disables mock servers in personal workspaces
|
||||
const disableInPersonalWorkspace =
|
||||
platform.platformFeatureFlags.disableMockServerInPersonalWorkspace ??
|
||||
false
|
||||
|
||||
// If platform disables mock servers in personal workspaces and current workspace is personal, hide mock servers
|
||||
if (
|
||||
disableInPersonalWorkspace &&
|
||||
workspaceService.currentWorkspace.value.type === "personal"
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return {
|
||||
isMockServerVisible,
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import { useService } from "dioc/vue"
|
|||
import { WorkspaceService } from "~/services/workspace.service"
|
||||
import { setMockServers, loadMockServers } from "~/newstore/mockServers"
|
||||
import { platform } from "~/platform"
|
||||
import { useSetting } from "./settings"
|
||||
import { useMockServerVisibility } from "./mockServerVisibility"
|
||||
|
||||
/**
|
||||
* Composable to handle mock server state when workspace changes
|
||||
|
|
@ -12,14 +12,12 @@ import { useSetting } from "./settings"
|
|||
*/
|
||||
export function useMockServerWorkspaceSync() {
|
||||
const workspaceService = useService(WorkspaceService)
|
||||
const ENABLE_EXPERIMENTAL_MOCK_SERVERS = useSetting(
|
||||
"ENABLE_EXPERIMENTAL_MOCK_SERVERS"
|
||||
)
|
||||
const { isMockServerVisible } = useMockServerVisibility()
|
||||
const isAuthenticated = !!platform.auth.getCurrentUser()
|
||||
|
||||
// Initial load of mock servers for the current workspace
|
||||
onMounted(() => {
|
||||
if (!isAuthenticated || !ENABLE_EXPERIMENTAL_MOCK_SERVERS.value) return
|
||||
if (!isAuthenticated || !isMockServerVisible.value) return
|
||||
loadMockServers().catch(() => setMockServers([]))
|
||||
})
|
||||
|
||||
|
|
@ -27,7 +25,7 @@ export function useMockServerWorkspaceSync() {
|
|||
watch(
|
||||
() => workspaceService.currentWorkspace.value,
|
||||
(newWorkspace, oldWorkspace) => {
|
||||
if (!isAuthenticated || !ENABLE_EXPERIMENTAL_MOCK_SERVERS.value) return
|
||||
if (!isAuthenticated || !isMockServerVisible.value) return
|
||||
|
||||
// Clear mock servers when workspace changes to prevent stale data
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -66,6 +66,12 @@ export type PlatformDef = {
|
|||
* Whether to show the A/B testing workspace switcher click login flow or not
|
||||
*/
|
||||
workspaceSwitcherLogin?: Ref<boolean>
|
||||
|
||||
/**
|
||||
* Whether to disable mock servers in personal workspaces
|
||||
* If a value is not given, then the value is assumed to be false
|
||||
*/
|
||||
disableMockServerInPersonalWorkspace?: boolean
|
||||
}
|
||||
limits?: LimitsPlatformDef
|
||||
infra?: InfraPlatformDef
|
||||
|
|
|
|||
Loading…
Reference in a new issue