Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Show ConsoleSamples resources in the samples catalog
- Loading branch information
Showing
42 changed files
with
1,357 additions
and
184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
...d/packages/console-app/src/components/quick-starts/utils/__tests__/useQuickStarts.data.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { QuickStart } from '@patternfly/quickstarts'; | ||
|
||
export const quickStartSample: QuickStart = { | ||
apiVersion: 'console.openshift.io/v1', | ||
kind: 'ConsoleQuickStart', | ||
metadata: { name: 'quickstart-sample' }, | ||
spec: { | ||
displayName: 'QuickStart sample', | ||
description: '', | ||
icon: '', | ||
}, | ||
}; | ||
|
||
export const anotherQuickStartSample: QuickStart = { | ||
apiVersion: 'console.openshift.io/v1', | ||
kind: 'ConsoleQuickStart', | ||
metadata: { name: 'another-quickstart-sample' }, | ||
spec: { | ||
displayName: 'QuickStart sample', | ||
description: '', | ||
icon: '', | ||
}, | ||
}; | ||
|
||
const getPseudoTranslatedQuickStart = ( | ||
quickStart: QuickStart, | ||
lang?: string, | ||
country?: string, | ||
): QuickStart => { | ||
return { | ||
...quickStart, | ||
metadata: { | ||
...quickStart.metadata, | ||
name: `${quickStart.metadata.name}${lang ? `-${lang}` : ''}${country ? `-${country}` : ''}`, | ||
labels: { | ||
...quickStart.metadata.labels, | ||
'console.openshift.io/name': quickStart.metadata.name, | ||
'console.openshift.io/lang': lang, | ||
'console.openshift.io/country': country, | ||
}, | ||
}, | ||
spec: { | ||
...quickStart.spec, | ||
displayName: `${quickStart.spec.displayName}${lang ? ` ${lang}` : ''}${ | ||
country ? `-${country}` : '' | ||
}`, | ||
}, | ||
}; | ||
}; | ||
|
||
export const translatedQuickStarts: QuickStart[] = [ | ||
getPseudoTranslatedQuickStart(quickStartSample), | ||
getPseudoTranslatedQuickStart(quickStartSample, 'en', 'US'), | ||
getPseudoTranslatedQuickStart(quickStartSample, 'EN', 'CA'), | ||
getPseudoTranslatedQuickStart(quickStartSample, 'fr', 'CA'), | ||
getPseudoTranslatedQuickStart(quickStartSample, 'fr'), | ||
getPseudoTranslatedQuickStart(quickStartSample, 'de', 'DE'), | ||
getPseudoTranslatedQuickStart(quickStartSample, 'de', 'AT'), | ||
]; |
74 changes: 74 additions & 0 deletions
74
...d/packages/console-app/src/components/quick-starts/utils/__tests__/useQuickStarts.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { getBestMatch, groupQuickStartsByName } from '../useQuickStarts'; | ||
import { | ||
quickStartSample, | ||
anotherQuickStartSample, | ||
translatedQuickStarts, | ||
} from './useQuickStarts.data'; | ||
|
||
describe('groupConsoleSamplesByName', () => { | ||
it('should create a single group for one sample without localization labels', () => { | ||
const actual = groupQuickStartsByName([quickStartSample]); | ||
expect(actual).toEqual({ | ||
'quickstart-sample': [quickStartSample], | ||
}); | ||
}); | ||
|
||
it('should create a two groups for two different samples without localization labels', () => { | ||
const actual = groupQuickStartsByName([quickStartSample, anotherQuickStartSample]); | ||
expect(actual).toEqual({ | ||
'quickstart-sample': [quickStartSample], | ||
'another-quickstart-sample': [anotherQuickStartSample], | ||
}); | ||
}); | ||
|
||
it('should group the translated samples correct', () => { | ||
const actual = groupQuickStartsByName(translatedQuickStarts); | ||
|
||
expect(actual).toEqual({ 'quickstart-sample': translatedQuickStarts }); | ||
}); | ||
}); | ||
|
||
describe('getBestMatch', () => { | ||
it('should return null for null', () => { | ||
expect(getBestMatch(null, '')).toBe(null); | ||
}); | ||
|
||
it('should return null for an empty array', () => { | ||
expect(getBestMatch([], 'en')).toBe(null); | ||
}); | ||
|
||
it('should return the sample with an equal language and country', () => { | ||
// neighter language or country is defined | ||
expect(getBestMatch(translatedQuickStarts, '')).toEqual(translatedQuickStarts[0]); | ||
// default language is preferred, no country | ||
expect(getBestMatch(translatedQuickStarts, 'en')).toEqual(translatedQuickStarts[0]); | ||
// non default language and country | ||
expect(getBestMatch(translatedQuickStarts, 'fr-CA')).toEqual(translatedQuickStarts[3]); | ||
// lowercase input | ||
expect(getBestMatch(translatedQuickStarts, 'fr-ca')).toEqual(translatedQuickStarts[3]); | ||
// uppercase input | ||
expect(getBestMatch(translatedQuickStarts, 'FR-CA')).toEqual(translatedQuickStarts[3]); | ||
// language defined, but not english, no country | ||
expect(getBestMatch(translatedQuickStarts, 'fr')).toEqual(translatedQuickStarts[4]); | ||
}); | ||
|
||
it('should return the sample with the same language, prefer no country', () => { | ||
expect(getBestMatch(translatedQuickStarts, 'fr-MC')).toEqual(translatedQuickStarts[4]); | ||
}); | ||
|
||
it('should return the sample with the same language, prefer any country', () => { | ||
expect(getBestMatch(translatedQuickStarts, 'DE-CH')).toEqual(translatedQuickStarts[5]); | ||
}); | ||
|
||
it('should return the fallback language with the same country', () => { | ||
expect(getBestMatch(translatedQuickStarts, 'NA-CA')).toEqual(translatedQuickStarts[2]); | ||
}); | ||
|
||
it('should return the fallback language with no country', () => { | ||
expect(getBestMatch(translatedQuickStarts, 'NA-NA')).toEqual(translatedQuickStarts[0]); | ||
}); | ||
|
||
it('should return the fallback language with any country', () => { | ||
expect(getBestMatch(translatedQuickStarts.slice(1), 'NA-NA')).toEqual(translatedQuickStarts[1]); | ||
}); | ||
}); |
121 changes: 121 additions & 0 deletions
121
frontend/packages/console-app/src/components/quick-starts/utils/useQuickStarts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import * as React from 'react'; | ||
import { QuickStart, getDisabledQuickStarts } from '@patternfly/quickstarts'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { | ||
WatchK8sResult, | ||
getGroupVersionKindForModel, | ||
} from '@console/dynamic-plugin-sdk/src/lib-core'; | ||
import { useK8sWatchResource } from '@console/dynamic-plugin-sdk/src/utils/k8s/hooks/useK8sWatchResource'; | ||
import { QuickStartModel } from '../../../models'; | ||
|
||
const LOCALIZATION_NAME_LABEL = 'console.openshift.io/name'; | ||
const LOCALIZATION_LANGUAGE_LABEL = 'console.openshift.io/lang'; | ||
const LOCALIZATION_COUNTRY_LABEL = 'console.openshift.io/country'; | ||
|
||
export const getQuickStartNameRef = (quickStart: QuickStart) => | ||
quickStart.metadata.labels?.[LOCALIZATION_NAME_LABEL] || | ||
quickStart.metadata.annotations?.[LOCALIZATION_NAME_LABEL] || | ||
quickStart.metadata.name; | ||
|
||
export const groupQuickStartsByName = (quickStarts: QuickStart[]) => { | ||
return quickStarts.reduce<Record<string, QuickStart[]>>((grouped, quickStart) => { | ||
const name = getQuickStartNameRef(quickStart); | ||
if (!grouped[name]) grouped[name] = []; | ||
grouped[name].push(quickStart); | ||
return grouped; | ||
}, {}); | ||
}; | ||
|
||
/** | ||
* Returns the QuickStart with the best localization match, for the given | ||
* preferred language and preferred country. It prefers a match in this order: | ||
* | ||
* 1. QuickStart language and country are equal to the preferred language and country. | ||
* /// This includes that the no quick starts language and country is defined. | ||
* | ||
* 2. QuickStart language is equal to the preferred language. | ||
* 1. And the quick starts has no country defined. (eg, select en quick starts is used for en-CA and en-GB) | ||
* 2. Any country is defined. (eg, select en-CA quick starts is used for en-GB) | ||
* | ||
* 3. Fallback to an english quick starts | ||
* (QuickStart language is en OR quick starts language is not defined): | ||
* 1. Same country (use en-CA quick starts if preference is fr-CA) | ||
* 2. No country () | ||
* 3. Any country (use en-CA quick starts if preference is en-US) | ||
*/ | ||
export const getBestMatch = (quickStarts: QuickStart[], language: string): QuickStart | null => { | ||
if (!quickStarts || !quickStarts.length) { | ||
return null; | ||
} | ||
const preferredLanguage = (language || 'en').split('-')[0].toLowerCase(); | ||
const preferredCountry = ((language || '').split('-')[1] || '').toUpperCase(); | ||
|
||
let sameLanguageWithoutCountry: QuickStart = null; | ||
let sameLanguageWithAnyCountry: QuickStart = null; | ||
let fallbackLanguageSameCountry: QuickStart = null; | ||
let fallbackLanguageNoCountry: QuickStart = null; | ||
let fallbackLanguageAnyCountry: QuickStart = null; | ||
|
||
for (const quickStart of quickStarts) { | ||
const quickStartLanguage = ( | ||
quickStart.metadata?.labels?.[LOCALIZATION_LANGUAGE_LABEL] || 'en' | ||
).toLowerCase(); | ||
const quickStartCountry = ( | ||
quickStart.metadata?.labels?.[LOCALIZATION_COUNTRY_LABEL] || '' | ||
).toUpperCase(); | ||
|
||
if (quickStartLanguage === preferredLanguage && quickStartCountry === preferredCountry) { | ||
return quickStart; | ||
} | ||
if (quickStartLanguage === preferredLanguage) { | ||
if (!quickStartCountry && !sameLanguageWithoutCountry) { | ||
sameLanguageWithoutCountry = quickStart; | ||
} else if (quickStartCountry && !sameLanguageWithAnyCountry) { | ||
sameLanguageWithAnyCountry = quickStart; | ||
} | ||
} | ||
if (quickStartLanguage === 'en') { | ||
if (quickStartCountry === preferredCountry && !fallbackLanguageSameCountry) { | ||
fallbackLanguageSameCountry = quickStart; | ||
} else if (!quickStartCountry && !fallbackLanguageNoCountry) { | ||
fallbackLanguageNoCountry = quickStart; | ||
} else if (!fallbackLanguageAnyCountry) { | ||
fallbackLanguageAnyCountry = quickStart; | ||
} | ||
} | ||
} | ||
return ( | ||
sameLanguageWithoutCountry || | ||
sameLanguageWithAnyCountry || | ||
fallbackLanguageSameCountry || | ||
fallbackLanguageNoCountry || | ||
fallbackLanguageAnyCountry | ||
); | ||
}; | ||
|
||
export const useQuickStarts = (filterDisabledQuickStarts = true): WatchK8sResult<QuickStart[]> => { | ||
const preferredLanguage = useTranslation().i18n.language; | ||
|
||
const [quickStarts, quickStartsLoaded, quickStartsError] = useK8sWatchResource<QuickStart[]>({ | ||
groupVersionKind: getGroupVersionKindForModel(QuickStartModel), | ||
isList: true, | ||
}); | ||
|
||
const bestMatchQuickStarts = React.useMemo(() => { | ||
if (!quickStartsLoaded) { | ||
return []; | ||
} | ||
const groupedQuickStarts = groupQuickStartsByName(quickStarts); | ||
|
||
if (filterDisabledQuickStarts) { | ||
const disabledQuickStarts = getDisabledQuickStarts(); | ||
disabledQuickStarts.forEach((quickStartName) => delete groupedQuickStarts[quickStartName]); | ||
} | ||
|
||
return Object.values(groupedQuickStarts).map((quickStartsByName) => | ||
getBestMatch(quickStartsByName, preferredLanguage), | ||
); | ||
}, [quickStarts, quickStartsLoaded, filterDisabledQuickStarts, preferredLanguage]); | ||
|
||
return [bestMatchQuickStarts, quickStartsLoaded, quickStartsError]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.