Skip to content

Commit

Permalink
refactor: show granted scopes at app level (#428)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidma415 authored Feb 27, 2024
1 parent f72d273 commit 3675fc1
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 88 deletions.
70 changes: 21 additions & 49 deletions cypress/e2e/specs/application_registration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,23 +597,15 @@ describe('Application Registration', () => {
cy.mockApplications(apps, 1)
cy.visit('/my-apps')

mockApplicationWithCredAndReg(apps[0], [], [
{
id: 'regId',
product_id: 'id',
product_name: 'mockbin',
product_version_id: 'pvid',
product_version_name: 'version_name',
application_id: apps[0].id,
status: 'approved',
created_at: '2023-11-24T17:35:52.765Z',
updated_at: '2023-11-24T17:49:32.719Z',
granted_scopes: [
'scope1',
'scope2'
]
}
])
const app = {
...apps[0],
scopes: [
'scope1',
'scope2'
]
}

mockApplicationWithCredAndReg(app, [])
cy.get('[data-testid="applications-table"] tbody tr')
.contains(apps[0].name)
.click()
Expand All @@ -627,25 +619,17 @@ describe('Application Registration', () => {
cy.mockApplications(apps, 1)
cy.visit('/my-apps')

mockApplicationWithCredAndReg(apps[0], [], [
{
id: 'regId',
product_id: 'id',
product_name: 'mockbin',
product_version_id: 'pvid',
product_version_name: 'version_name',
application_id: apps[0].id,
status: 'approved',
created_at: '2023-11-24T17:35:52.765Z',
updated_at: '2023-11-24T17:49:32.719Z',
granted_scopes: [
'scope1',
'scope2',
'scope3',
'scope4'
]
}
])
const app = {
...apps[0],
scopes: [
'scope1',
'scope2',
'scope3',
'scope4'
]
}

mockApplicationWithCredAndReg(app, [], [])
cy.get('[data-testid="applications-table"] tbody tr')
.contains(apps[0].name)
.click()
Expand All @@ -661,19 +645,7 @@ describe('Application Registration', () => {
cy.mockApplications(apps, 1)
cy.visit('/my-apps')

mockApplicationWithCredAndReg(apps[0], [], [
{
id: 'regId',
product_id: 'id',
product_name: 'mockbin',
product_version_id: 'pvid',
product_version_name: 'version_name',
application_id: apps[0].id,
status: 'approved',
created_at: '2023-11-24T17:35:52.765Z',
updated_at: '2023-11-24T17:49:32.719Z'
}
])
mockApplicationWithCredAndReg(apps[0], [], [])
cy.get('[data-testid="applications-table"] tbody tr')
.contains(apps[0].name)
.click()
Expand Down
9 changes: 8 additions & 1 deletion src/components/ScopeBadges.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
:key="(scope as string)"
:data-testid="`granted-${scope}`"
class="scope-badge"
shape="rectangular"
>
{{ scope }}
</KBadge>
<KBadge
v-if="!showRest && hiddenItems.length"
data-testid="show-more-scopes"
shape="rectangular"
@click.stop="handleShowMore"
>
<span>
Expand Down Expand Up @@ -62,11 +64,16 @@ export default defineComponent({
.badge-container {
display: flex;
flex-wrap: wrap;
max-width: 250px;
row-gap: 6px;
:not(:last-child) {
margin-right: 4px;
}
:deep(.k-badge) {
background: var(--button_colors-primary-fill, var(--blue-500, #1155cb));
border: 1px solid transparent;
color: var(--button_colors-primary-text, #fff);
}
}
</style>
2 changes: 1 addition & 1 deletion src/locales/ca_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export const ca_ES: I18nType = {
applicationName: "Nom de l'aplicació ",
authStrategy: translationNeeded(en.application.authStrategy),
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
grantedScopes: translationNeeded(en.application.grantedScopes),
clientID: 'ID de client: ',
clientSecret: 'Clau secreta de client: ',
reqField: ' indica un camp obligatori',
Expand Down Expand Up @@ -181,7 +182,6 @@ export const ca_ES: I18nType = {
nameProduct: 'Producte',
version: 'Versió',
status: 'Estat',
scopes: translationNeeded(en.productList.labels.scopes),
actions: 'Accions'
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export const de: I18nType = {
applicationName: 'Name der Applikation',
authStrategy: translationNeeded(en.application.authStrategy),
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
grantedScopes: translationNeeded(en.application.grantedScopes),
clientID: translationNeeded(en.application.clientID),
clientSecret: translationNeeded(en.application.clientSecret),
reqField: ' Pflichtfeld',
Expand Down Expand Up @@ -181,7 +182,6 @@ export const de: I18nType = {
nameProduct: 'Produkt',
version: 'Version',
status: 'Status',
scopes: translationNeeded(en.productList.labels.scopes),
actions: 'Aktionen'
}
},
Expand Down
4 changes: 2 additions & 2 deletions src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export const en = {
applicationName: 'Application Name ',
authStrategy: 'Auth Strategy',
authStrategyWarning: 'You cannot create an application as this developer portal has no available application auth strategies. Please contact a developer portal admin.',
grantedScopes: 'Granted Scopes:',
clientID: 'Client ID: ',
clientSecret: 'Client Secret: ',
reqField: ' indicates required field',
Expand Down Expand Up @@ -177,7 +178,6 @@ export const en = {
nameProduct: 'Product',
version: 'Version',
status: 'Status',
scopes: 'Scopes',
actions: 'Actions'
}
},
Expand All @@ -202,7 +202,7 @@ export const en = {
createApplication: 'Create an Application',
searchPlaceholder: 'Search applications',
cancelButton: 'Cancel',
filterScopes: 'filter...',
filterScopes: 'Filter...',
availableScopesLabel: 'Select scopes',
fetchingScopesLabel: 'Fetching scopes...',
registeredApplicationsProduct: 'The following applications are already registered to this product:',
Expand Down
2 changes: 1 addition & 1 deletion src/locales/es_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export const es_ES: I18nType = {
applicationName: 'Nombre de la aplicación ',
authStrategy: translationNeeded(en.application.authStrategy),
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
grantedScopes: translationNeeded(en.application.grantedScopes),
clientID: 'ID de cliente: ',
clientSecret: 'Clave secreta de cliente: ',
reqField: ' indica campo obligatorio',
Expand Down Expand Up @@ -181,7 +182,6 @@ export const es_ES: I18nType = {
nameProduct: 'Producto',
version: 'Versión',
status: 'Estado',
scopes: translationNeeded(en.productList.labels.scopes),
actions: 'Acciones'
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export const fr: I18nType = {
applicationName: 'Nom de l\'application ',
authStrategy: translationNeeded(en.application.authStrategy),
authStrategyWarning: translationNeeded(en.application.authStrategyWarning),
grantedScopes: translationNeeded(en.application.grantedScopes),
clientID: 'Client ID : ',
clientSecret: 'Client Secret : ',
reqField: ' indique un champ obligatoire',
Expand Down Expand Up @@ -181,7 +182,6 @@ export const fr: I18nType = {
nameProduct: 'Produit',
version: 'Version',
status: 'Statut',
scopes: translationNeeded(en.productList.labels.scopes),
actions: 'Actions'
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/locales/i18n-type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export interface I18nType {
clientID: string;
clientSecret: string;
reqField: string;
grantedScopes: string;
redirectUriLabel: string;
applicationCredentials: string;
applicationSecret: string;
Expand Down Expand Up @@ -178,7 +179,6 @@ export interface I18nType {
version: string;
status: string;
actions: string;
scopes: string;
};
};
dcrAuthentication: {
Expand Down
20 changes: 19 additions & 1 deletion src/views/Applications/ApplicationDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@
>
{{ helpText.application.referenceId(application.reference_id) }}
</div>
<div
v-if="application.scopes?.length"
class="granted-scopes color-text_colors-secondary"
data-testid="granted-scopes-container"
>
<span class="label">{{ helpText.application.grantedScopes }}</span>
<ScopeBadges :scopes="application.scopes" />
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -178,6 +186,7 @@ import CredentialsList from './CredentialsList.vue'
import ProductList from './ProductList.vue'
import DcrAuthenticationTable from './DcrAuthenticationTable.vue'
import AnalyticsMetricsCard from '@/components/vitals/AnalyticsMetricsCard.vue'
import ScopeBadges from '@/components/ScopeBadges.vue'
import { useI18nStore, useAppStore } from '@/stores'
import { PortalTimeframeKeys } from '@/types/vitals'
Expand All @@ -192,7 +201,7 @@ import { CredentialType } from '@kong/sdk-portal-js'
export default defineComponent({
name: 'ApplicationDetail',
components: { AnalyticsMetricsCard, PageTitle, CredentialsList, ProductList, DcrAuthenticationTable },
components: { AnalyticsMetricsCard, PageTitle, CredentialsList, ProductList, DcrAuthenticationTable, ScopeBadges },
setup () {
const errorMessage = ref('')
Expand Down Expand Up @@ -328,4 +337,13 @@ export default defineComponent({
color: var(--button_colors-primary-text, #fff);
}
}
.granted-scopes {
display: flex;
justify-content: flex-end;
.label {
margin-right: 4px;
}
}
</style>
31 changes: 1 addition & 30 deletions src/views/Applications/ProductList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
<KCard>
<template #body>
<KTable
:key="headerCacheKey"
data-testid="products-list"
:fetcher-cache-key="fetcherCacheKey"
:fetcher="fetcher"
Expand All @@ -27,9 +26,6 @@
<template #status="{ row }">
<StatusBadge :status="row.status" />
</template>
<template #scopes="{ row }">
<ScopeBadges :scopes="row.scopes" />
</template>
<template #actions="{ row }">
<ActionsDropdown>
<template #content>
Expand Down Expand Up @@ -75,12 +71,11 @@ import usePortalApi from '@/hooks/usePortalApi'
import PageTitle from '@/components/PageTitle.vue'
import StatusBadge from '@/components/StatusBadge.vue'
import ScopeBadges from '@/components/ScopeBadges.vue'
import ActionsDropdown from '@/components/ActionsDropdown.vue'
export default defineComponent({
name: 'ProductList',
components: { PageTitle, ScopeBadges, StatusBadge, ActionsDropdown },
components: { PageTitle, StatusBadge, ActionsDropdown },
props: {
id: {
type: String,
Expand All @@ -96,20 +91,7 @@ export default defineComponent({
const viewCatalog2 = helpText.emptyState.viewCatalog2Product
const { notify } = useToaster()
const hasGrantedScopes = ref(false)
const tableHeaders = computed(() => {
if (hasGrantedScopes.value) {
revalidateHeaders()
return [
{ label: nameLabel, key: 'name' },
{ label: helpText.labels.version, key: 'version' },
{ label: helpText.labels.status, key: 'status' },
{ label: helpText.labels.scopes, key: 'scopes' },
{ label: helpText.labels.actions, key: 'actions', hideLabel: true }
]
}
return [
{ label: nameLabel, key: 'name' },
{ label: helpText.labels.version, key: 'version' },
Expand All @@ -134,9 +116,7 @@ export default defineComponent({
)
const key = ref(0)
const headerKey = ref(0)
const fetcherCacheKey = computed(() => key.value.toString())
const headerCacheKey = computed(() => headerKey.value.toString())
const paginationConfig = ref({
paginationPageSizes: [25, 50, 100],
Expand All @@ -147,10 +127,6 @@ export default defineComponent({
key.value += 1
}
const revalidateHeaders = () => {
headerKey.value += 1
}
const fetcher = async (payload: { pageSize: number; page: number }) => {
const { pageSize, page: pageNumber } = payload
const reqPayload = { applicationId: props.id, pageNumber, pageSize }
Expand All @@ -166,15 +142,12 @@ export default defineComponent({
name: registration.product_name,
version: registration.product_version_name,
id: registration.product_version_id,
...(registration.granted_scopes) && { scopes: registration.granted_scopes },
specLink: `/spec/${registration.product_id}/${registration.product_version_id}`,
status: registration.status,
registrationId: registration.id
}
})
hasGrantedScopes.value = items.some((item) => { return item.scopes })
return {
data: items,
total: data.meta.page.total
Expand Down Expand Up @@ -212,11 +185,9 @@ export default defineComponent({
return {
helpText,
tableHeaders,
hasGrantedScopes,
currentState,
handleDeleteRegistration,
fetcher,
headerCacheKey,
fetcherCacheKey,
paginationConfig,
emptyStateTitle,
Expand Down

0 comments on commit 3675fc1

Please sign in to comment.