UNPKG

@etsoo/website

Version:

ETSOO CMS Based NextJs Website Framework

213 lines (195 loc) 6.26 kB
import { DataTypes } from '@etsoo/shared'; import enResources from '../i18n/en.json'; import zhHansResources from '../i18n/zh-Hans.json'; import zhHantResources from '../i18n/zh-Hant.json'; import { SiteTab } from '../dto/site/SiteTab'; import { ArticleLink } from '../dto/site/ArticleLink'; import { SitePageProps, SiteTabPageProps } from '../props/SitePageProps'; import { StaticTabPageProps } from '../props/StaticTabPageProps'; /** * Site utilities * 网站工具 */ export namespace SiteUtils { /** * Check the content should be considered as no content * @param content Check content * @returns Result */ export function checkNoContent(content?: string) { if ( content == null || content === '' || content === 'n/a' || content === '<p>n/a</p>' ) return true; else return false; } /** * Format article URL * 格式化文章链接 * @param item Article link item * @returns Result */ export function formatLink(item: ArticleLink) { const { url, tabLayout, tabUrl } = item; if (tabLayout === 0) return tabUrl; if (tabLayout === 1) return '#'; return `${tabUrl}/${url}`; } /** * Format tab URL * 格式化栏目地址 * @param tab Tab * @returns Result */ export function formatUrl(tab: SiteTab) { return tab.layout === 1 ? '#' : tab.url; } /** * Get JSON data * @param jsonData JSON data * @returns Result */ export function getJsonData<T>(jsonData: unknown) { if (jsonData == null) return undefined; if (typeof jsonData === 'string') { try { return JSON.parse(jsonData) as T; } catch { return undefined; } } else if (typeof jsonData === 'object') { return jsonData as T; } } /** * Get placement * @param p Placement * @returns Style classes */ export function getPlacement(p: DataTypes.PlacementEnum) { switch (p) { case DataTypes.PlacementEnum.TopLeft: return 'top-0 start-0'; case DataTypes.PlacementEnum.TopCenter: return 'top-0 start-50 translate-middle-x'; case DataTypes.PlacementEnum.TopRight: return 'top-0 end-0'; case DataTypes.PlacementEnum.MiddleLeft: return 'top-50 start-0 translate-middle-y'; case DataTypes.PlacementEnum.Center: return 'top-50 start-50 translate-middle'; case DataTypes.PlacementEnum.MiddleRight: return 'top-50 end-0 translate-middle-y'; case DataTypes.PlacementEnum.BottomLeft: return 'bottom-0 start-0'; case DataTypes.PlacementEnum.BottomCenter: return 'bottom-0 start-50 translate-middle-x'; default: return 'bottom-0 end-0'; } } const resources: DataTypes.StringRecord = {}; /** * Get culture resource * @param key key * @returns Resource */ export function get<T = string>(key: string): T | undefined { const value = resources[key]; if (value == null) return undefined; // No strict type convertion here // Make sure the type is strictly match // Otherwise even request number, may still return the source string type return value as T; } /** * Get string resource * @param key key * @param defaultLabel Default label * @returns Resource */ export function getLabel(key: string, defaultLabel?: string): string { return get<string>(key) ?? defaultLabel ?? key; } /** * Get multiple tring resources * @param keys Keys */ export function getLabels<T extends string>( ...keys: T[] ): { [K in T]: string } { const init: any = {}; return keys.reduce((a, v) => ({ ...a, [v]: getLabel(v) }), init); } /** * Is site tab page props * 是否为网站栏目页面属性 * @param props Page props * @returns Result */ export function isSiteTabPageProps( props: SitePageProps ): props is SiteTabPageProps { return 'tab' in props && props['tab'] != null; } /** * Is static tab page props * 是否为静态栏目页面属性 * @param props Page props * @returns Result */ export function isStaticTabPageProps( props: SiteTabPageProps ): props is StaticTabPageProps { return 'articles' in props && Array.isArray(props['articles']); } /** * Setup * @param culture Culture, like zh-Hans * @param customResources Custom resurces */ export function setup( culture: string, customResources: DataTypes.StringRecord ) { if ( culture === 'zh-CN' || culture === 'zh-SG' || culture === 'zh-Hans' || culture.startsWith('zh-Hans-') ) { Object.assign(resources, zhHansResources); } else if (culture.startsWith('zh-')) { Object.assign(resources, zhHantResources); } else if (culture === 'en' || culture.startsWith('en-')) { Object.assign(resources, enResources); } Object.assign(resources, customResources); } /** * Toggle button spinner show / hide * @param button Button * @param startSide In start side or not, default false */ export function toggleButtonSpinner( button: HTMLButtonElement, startSide: boolean = false ) { let span = button.querySelector('.spinner-border'); if (span == null) { span = document.createElement('span'); span.className = `spinner-border spinner-border-sm ${ startSide ? 'me-2' : 'ms-2' }`; span.role = 'status'; startSide ? button.prepend(span) : button.append(span); button.disabled = true; } else { span.remove(); button.disabled = false; } } }