Skip to content

Commit

Permalink
feat: adds summary tray to service list view (#1611)
Browse files Browse the repository at this point in the history
feat(services): adds summary tray

Adds a summary tray to the service list view.

Signed-off-by: Philipp Rudloff <[email protected]>
  • Loading branch information
Philipp Rudloff authored Oct 25, 2023
1 parent b9e5a23 commit e1a94d6
Show file tree
Hide file tree
Showing 11 changed files with 349 additions and 151 deletions.
13 changes: 10 additions & 3 deletions features/mesh/services/Index.feature
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Feature: mesh / services / index
Then the "$item:nth-child(1)" element contains
| Value |
| service-1 |
Scenario: Clicking the link goes to the detail page and back again

Scenario: Clicking View details goes to the detail page and back again
Given the URL "/meshes/default/service-insights/service-1" responds with
"""
body:
Expand All @@ -48,7 +49,10 @@ Feature: mesh / services / index
serviceType: internal
"""
Then the "$item:nth-child(1) td:nth-child(1)" element contains "service-1"
When I click the "$item:nth-child(1) td:first-of-type a" element

When I click the "$item:nth-child(1) [data-testid='k-dropdown-trigger'] button" element
And I click the "$item:nth-child(1) [data-testid='dropdown-view-details-item'] a" element

Then the URL contains "services/service-1/overview"
Then the "#service-detail-view-tab a" element exists
# Service Insights with serviceType "external" shouldn't have a Data Plane Proxy table
Expand All @@ -57,7 +61,10 @@ Feature: mesh / services / index
When I click the "$breadcrumbs > .k-breadcrumbs-item:nth-child(3) > a" element
Then the "$item" element exists 2 times
Then the "$item:nth-child(2) td:nth-child(1)" element contains "service-2"
When I click the "$item:nth-child(2) td:first-of-type a" element

When I click the "$item:nth-child(2) [data-testid='k-dropdown-trigger'] button" element
And I click the "$item:nth-child(2) [data-testid='dropdown-view-details-item'] a" element

Then the URL contains "services/service-2/overview"
Then the "[data-testid='service-detail-tabs-view']" element contains "service-2"
Then the "#service-detail-view-tab a" element exists
Expand Down
43 changes: 43 additions & 0 deletions features/mesh/services/ServiceTray.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Feature: Service tray
Background:
Given the CSS selectors
| Alias | Selector |
| item | [data-testid='service-collection'] tbody tr |
| tray | [data-testid='tray'] |
| close-tray-button | $tray [data-testid^='close-button-'] |
And the URL "/meshes/default/service-insights" responds with
"""
body:
items:
- name: service-1
"""

Scenario: Clicking a row opens the summary tray
Given the environment
"""
KUMA_SERVICEINSIGHT_COUNT: 1
"""

When I visit the "/meshes/default/services" URL
And I click the "$item:nth-child(1) td:nth-child(2)" element
Then the "$tray" element exists
And the "$tray" element contains "service-1"

When I click the "$close-tray-button" element
Then the "$tray" element doesn't exist

When I navigate "back"
Then the "$tray" element exists
And the "$tray" element contains "service-1"

When I navigate "forward"
Then the "$tray" element doesn't exist

Scenario: Summary tray URL goes to page with open service tray
Given the environment
"""
KUMA_SERVICEINSIGHT_COUNT: 51
"""

When I visit the "/meshes/default/services/service-1?page=2&size=50" URL
Then the "$tray" element exists
49 changes: 49 additions & 0 deletions src/app/services/components/ExternalServiceConfig.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<div>
<DataSource
v-slot="{ data: externalService, error: externalServiceError }: ExternalServiceSource"
:src="`/meshes/${props.mesh}/external-services/for/${props.service}`"
>
<ErrorBlock
v-if="externalServiceError"
:error="externalServiceError"
/>

<LoadingBlock v-else-if="externalService === undefined" />

<EmptyBlock
v-else-if="externalService === null"
data-testid="no-matching-external-service"
>
<template #title>
<p>{{ t('services.detail.no_matching_external_service', { name: props.service }) }}</p>
</template>
</EmptyBlock>

<ResourceCodeBlock
v-else
id="code-block-service"
:resource="externalService"
:resource-fetcher="(params) => kumaApi.getExternalService({ mesh: externalService.mesh, name: externalService.name }, params)"
is-searchable
/>
</DataSource>
</div>
</template>

<script lang="ts" setup>
import type { ExternalServiceSource } from '../sources'
import EmptyBlock from '@/app/common/EmptyBlock.vue'
import ErrorBlock from '@/app/common/ErrorBlock.vue'
import LoadingBlock from '@/app/common/LoadingBlock.vue'
import ResourceCodeBlock from '@/app/common/ResourceCodeBlock.vue'
import { useI18n, useKumaApi } from '@/utilities'
const { t } = useI18n()
const kumaApi = useKumaApi()
const props = defineProps<{
mesh: string
service: string
}>()
</script>
83 changes: 53 additions & 30 deletions src/app/services/components/ExternalServiceDetails.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,67 @@
<template>
<div class="stack">
<KCard>
<template #body>
<div class="columns">
<DefinitionCard>
<template #title>
{{ t('http.api.property.address') }}
</template>

<template #body>
{{ props.externalService.networking.address }}
</template>
</DefinitionCard>

<DefinitionCard v-if="props.externalService.tags !== null">
<template #title>
{{ t('http.api.property.tags') }}
</template>

<template #body>
<TagList :tags="props.externalService.tags" />
</template>
</DefinitionCard>
</div>
</template>
</KCard>
<div>
<DataSource
v-slot="{ data: externalService, error }: ExternalServiceSource"
:src="`/meshes/${props.mesh}/external-services/for/${props.service}`"
>
<ErrorBlock
v-if="error"
:error="error"
/>

<LoadingBlock v-else-if="externalService === undefined" />

<EmptyBlock
v-else-if="externalService === null"
data-testid="no-matching-external-service"
>
<template #title>
<p>{{ t('services.detail.no_matching_external_service', { name: props.service }) }}</p>
</template>
</EmptyBlock>

<div
v-else
class="columns"
>
<DefinitionCard>
<template #title>
{{ t('http.api.property.address') }}
</template>

<template #body>
<TextWithCopyButton :text="externalService.networking.address" />
</template>
</DefinitionCard>

<DefinitionCard v-if="externalService.tags !== null">
<template #title>
{{ t('http.api.property.tags') }}
</template>

<template #body>
<TagList :tags="externalService.tags" />
</template>
</DefinitionCard>
</div>
</DataSource>
</div>
</template>

<script lang="ts" setup>
import { KCard } from '@kong/kongponents'
import type { ExternalServiceSource } from '../sources'
import DefinitionCard from '@/app/common/DefinitionCard.vue'
import EmptyBlock from '@/app/common/EmptyBlock.vue'
import ErrorBlock from '@/app/common/ErrorBlock.vue'
import LoadingBlock from '@/app/common/LoadingBlock.vue'
import TagList from '@/app/common/TagList.vue'
import { ExternalService } from '@/types/index.d'
import TextWithCopyButton from '@/app/common/TextWithCopyButton.vue'
import { useI18n } from '@/utilities'
const { t } = useI18n()
const props = defineProps<{
externalService: ExternalService
mesh: string
service: string
}>()
</script>
76 changes: 34 additions & 42 deletions src/app/services/components/ServiceInsightDetails.vue
Original file line number Diff line number Diff line change
@@ -1,52 +1,44 @@
<template>
<div class="stack">
<KCard>
<div class="columns">
<DefinitionCard>
<template #title>
{{ t('http.api.property.status') }}
</template>

<template #body>
<div class="columns">
<DefinitionCard>
<template #title>
{{ t('http.api.property.status') }}
</template>

<template #body>
<StatusBadge :status="props.serviceInsight.status ?? 'not_available'" />
</template>
</DefinitionCard>

<DefinitionCard>
<template #title>
{{ t('http.api.property.address') }}
</template>

<template #body>
<TextWithCopyButton
v-if="props.serviceInsight.addressPort"
:text="props.serviceInsight.addressPort"
/>

<template v-else>
{{ t('common.detail.none') }}
</template>
</template>
</DefinitionCard>

<ResourceStatus
:online="props.serviceInsight.dataplanes?.online ?? 0"
:total="props.serviceInsight.dataplanes?.total ?? 0"
>
<template #title>
{{ t('http.api.property.dataPlaneProxies') }}
</template>
</ResourceStatus>
</div>
<StatusBadge :status="props.serviceInsight.status ?? 'not_available'" />
</template>
</KCard>
</DefinitionCard>

<DefinitionCard>
<template #title>
{{ t('http.api.property.address') }}
</template>

<template #body>
<TextWithCopyButton
v-if="props.serviceInsight.addressPort"
:text="props.serviceInsight.addressPort"
/>

<template v-else>
{{ t('common.detail.none') }}
</template>
</template>
</DefinitionCard>

<ResourceStatus
:online="props.serviceInsight.dataplanes?.online ?? 0"
:total="props.serviceInsight.dataplanes?.total ?? 0"
>
<template #title>
{{ t('http.api.property.dataPlaneProxies') }}
</template>
</ResourceStatus>
</div>
</template>

<script lang="ts" setup>
import { KCard } from '@kong/kongponents'
import DefinitionCard from '@/app/common/DefinitionCard.vue'
import ResourceStatus from '@/app/common/ResourceStatus.vue'
import StatusBadge from '@/app/common/StatusBadge.vue'
Expand Down
2 changes: 2 additions & 0 deletions src/app/services/locales/en-us/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ services:
service-detail-view: 'Overview'
service-data-plane-proxies-view: 'Data Plane Proxies'
service-config-view: 'YAML'
overview: 'Overview'
config: 'YAML'
items:
title: Services
detail:
Expand Down
7 changes: 7 additions & 0 deletions src/app/services/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ export const routes = () => {
module: 'services',
},
component: () => import('@/app/services/views/ServiceListView.vue'),
children: [
{
path: ':service',
name: 'service-tray-view',
component: () => import('@/app/services/views/ServiceTrayView.vue'),
},
],
},
]
},
Expand Down
43 changes: 6 additions & 37 deletions src/app/services/views/ServiceConfigView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
name="service-config-view"
:params="{
mesh: '',
service: ''
service: '',
}"
>
<AppView>
Expand All @@ -19,47 +19,16 @@

<KCard>
<template #body>
<DataSource
v-slot="{ data: externalService, error: externalServiceError }: ExternalServiceSource"
:src="`/meshes/${route.params.mesh}/external-services/for/${route.params.service}`"
>
<ErrorBlock
v-if="externalServiceError"
:error="externalServiceError"
/>

<LoadingBlock v-else-if="externalService === undefined" />

<EmptyBlock
v-else-if="externalService === null"
data-testid="no-matching-external-service"
>
<template #title>
<p>{{ t('services.detail.no_matching_external_service', { name: route.params.service }) }}</p>
</template>
</EmptyBlock>

<ResourceCodeBlock
v-else
id="code-block-service"
:resource="externalService"
:resource-fetcher="(params) => kumaApi.getExternalService({ mesh: externalService.mesh, name: externalService.name }, params)"
is-searchable
/>
</DataSource>
<ExternalServiceConfig
:mesh="route.params.mesh"
:service="route.params.service"
/>
</template>
</KCard>
</AppView>
</RouteView>
</template>

<script lang="ts" setup>
import type { ExternalServiceSource } from '../sources'
import EmptyBlock from '@/app/common/EmptyBlock.vue'
import ErrorBlock from '@/app/common/ErrorBlock.vue'
import LoadingBlock from '@/app/common/LoadingBlock.vue'
import ResourceCodeBlock from '@/app/common/ResourceCodeBlock.vue'
import { useKumaApi } from '@/utilities'
const kumaApi = useKumaApi()
import ExternalServiceConfig from '../components/ExternalServiceConfig.vue'
</script>
Loading

0 comments on commit e1a94d6

Please sign in to comment.