@etsoo/website
Version:
ETSOO CMS Based NextJs Website Framework
213 lines (195 loc) • 6.26 kB
text/typescript
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;
}
}
}