chore(template): theme logo
This commit is contained in:
@@ -88,6 +88,16 @@ Prefer action-driven updates, explicit handlers, and localized state transitions
|
|||||||
|
|
||||||
Existing `styled-components` usage is legacy tech debt — do not migrate it wholesale, but do not add new `styled-components` either. Theme tokens (`var(--ant-color-*)`) work in all three approaches.
|
Existing `styled-components` usage is legacy tech debt — do not migrate it wholesale, but do not add new `styled-components` either. Theme tokens (`var(--ant-color-*)`) work in all three approaches.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
Compose layout with Ant components, not hand-written `display: flex`.
|
||||||
|
|
||||||
|
- **1D flex** (row/column with `gap`, `align`, `justify`) → `Flex`. Do not write raw `display: flex` in new code.
|
||||||
|
- **Inline sequence** of a few elements with uniform spacing → `Space`.
|
||||||
|
- **Page/grid columns** → `Row` / `Col`.
|
||||||
|
|
||||||
|
Drive spacing with the theme scale (`Flex`/`Space` `gap`, or `var(--ant-*)` spacing tokens), not scattered `px` literals.
|
||||||
|
|
||||||
# Naming conventions
|
# Naming conventions
|
||||||
|
|
||||||
A page module lives under `src/pages/{module}` with this sub-structure: `components/`, `config/`, `forms/`, `hooks/`, `services/`, `index.tsx`. File naming:
|
A page module lives under `src/pages/{module}` with this sub-structure: `components/`, `config/`, `forms/`, `hooks/`, `services/`, `index.tsx`. File naming:
|
||||||
@@ -101,6 +111,7 @@ A page module lives under `src/pages/{module}` with this sub-structure: `compone
|
|||||||
|
|
||||||
- `config/types.ts` — TypeScript types. Form shape → `FormData`; table/list row → `ListItem`.
|
- `config/types.ts` — TypeScript types. Form shape → `FormData`; table/list row → `ListItem`.
|
||||||
- `config/index.ts` — static constants, enums, and value/label maps (e.g. `XxxStatusValueMap`, `XxxStatusLabelMap`). Keep constants out of `types.ts`.
|
- `config/index.ts` — static constants, enums, and value/label maps (e.g. `XxxStatusValueMap`, `XxxStatusLabelMap`). Keep constants out of `types.ts`.
|
||||||
|
- **`Select` options that need i18n**: set `label` to the message key and add `locale: true` on the option — the field translates it at render. Omit `locale` for options whose label is already final text. Ref `src/pages/benchmark/config/index.ts`.
|
||||||
|
|
||||||
# Common components
|
# Common components
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
@@ -1,5 +1,5 @@
|
|||||||
import { IconFont } from '@gpustack/core-ui';
|
import { IconFont } from '@gpustack/core-ui';
|
||||||
import { useIntl, useSearchParams } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Tabs, TabsProps } from 'antd';
|
import { Tabs, TabsProps } from 'antd';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Environment from './environment';
|
import Environment from './environment';
|
||||||
@@ -12,7 +12,6 @@ const Details: React.FC<{
|
|||||||
}> = ({ tabBarExtraContent }) => {
|
}> = ({ tabBarExtraContent }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [activeKey, setActiveKey] = useState('summary');
|
const [activeKey, setActiveKey] = useState('summary');
|
||||||
const [searchParams] = useSearchParams();
|
|
||||||
|
|
||||||
const items: TabsProps['items'] = [
|
const items: TabsProps['items'] = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import metaxLogo from '@/assets/logo/metax.png';
|
|||||||
import mooreLogo from '@/assets/logo/moore-logo.png';
|
import mooreLogo from '@/assets/logo/moore-logo.png';
|
||||||
import nvidiaLogo from '@/assets/logo/nvidia.png';
|
import nvidiaLogo from '@/assets/logo/nvidia.png';
|
||||||
import pytorchBlackLogo from '@/assets/logo/pytorch_black.png';
|
import pytorchBlackLogo from '@/assets/logo/pytorch_black.png';
|
||||||
|
import pytorchLightLogo from '@/assets/logo/pytorch_light.png';
|
||||||
import sgLangLogo from '@/assets/logo/sglang.png';
|
import sgLangLogo from '@/assets/logo/sglang.png';
|
||||||
import theadLogoEN from '@/assets/logo/t-head-en.png';
|
import theadLogoEN from '@/assets/logo/t-head-en.png';
|
||||||
import theadLogoZH from '@/assets/logo/t-head-zh.png';
|
import theadLogoZH from '@/assets/logo/t-head-zh.png';
|
||||||
@@ -14,6 +15,7 @@ import tensorflowkLogo from '@/assets/logo/tensorflow.svg';
|
|||||||
import ubuntuLogo from '@/assets/logo/ubuntu_logo.png';
|
import ubuntuLogo from '@/assets/logo/ubuntu_logo.png';
|
||||||
import vllmLogo from '@/assets/logo/vllm.png';
|
import vllmLogo from '@/assets/logo/vllm.png';
|
||||||
import PluginExtraFields from '@/components/plugin-extra-fields';
|
import PluginExtraFields from '@/components/plugin-extra-fields';
|
||||||
|
import useUserSettings from '@/hooks/use-user-settings';
|
||||||
import OwnerTag from '@/pages/gpu-service/components/owner-tag';
|
import OwnerTag from '@/pages/gpu-service/components/owner-tag';
|
||||||
import {
|
import {
|
||||||
GPUsConfigs,
|
GPUsConfigs,
|
||||||
@@ -33,7 +35,8 @@ import styled from 'styled-components';
|
|||||||
import { manufactureColorMap, templateActions } from '../config';
|
import { manufactureColorMap, templateActions } from '../config';
|
||||||
import { ListItem } from '../config/types';
|
import { ListItem } from '../config/types';
|
||||||
|
|
||||||
const imageLogoMap = {
|
// Light theme logos
|
||||||
|
const imageLogoLightMap = {
|
||||||
vllm: vllmLogo,
|
vllm: vllmLogo,
|
||||||
sglang: sgLangLogo,
|
sglang: sgLangLogo,
|
||||||
jupyter: jupyterLogo,
|
jupyter: jupyterLogo,
|
||||||
@@ -42,25 +45,31 @@ const imageLogoMap = {
|
|||||||
ubuntu: ubuntuLogo
|
ubuntu: ubuntuLogo
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
// Dark theme logos: inherit light, override only the ones that need a variant
|
||||||
|
const imageLogoDarkMap: typeof imageLogoLightMap = {
|
||||||
|
...imageLogoLightMap,
|
||||||
|
pytorch: pytorchLightLogo
|
||||||
|
};
|
||||||
|
|
||||||
const matchImageLogo = (
|
const matchImageLogo = (
|
||||||
image: string | undefined
|
image: string | undefined,
|
||||||
|
isDark: boolean
|
||||||
): { logo: string; type: string } | null => {
|
): { logo: string; type: string } | null => {
|
||||||
if (!image) return null;
|
if (!image) return null;
|
||||||
|
const logoMap = imageLogoLightMap;
|
||||||
const lower = image.toLowerCase();
|
const lower = image.toLowerCase();
|
||||||
let matched: keyof typeof imageLogoMap | null = null;
|
let matched: keyof typeof logoMap | null = null;
|
||||||
let earliest = Infinity;
|
let earliest = Infinity;
|
||||||
(Object.keys(imageLogoMap) as Array<keyof typeof imageLogoMap>).forEach(
|
(Object.keys(logoMap) as Array<keyof typeof logoMap>).forEach((key) => {
|
||||||
(key) => {
|
const idx = lower.indexOf(key);
|
||||||
const idx = lower.indexOf(key);
|
if (idx !== -1 && idx < earliest) {
|
||||||
if (idx !== -1 && idx < earliest) {
|
earliest = idx;
|
||||||
earliest = idx;
|
matched = key;
|
||||||
matched = key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
return matched
|
return matched
|
||||||
? {
|
? {
|
||||||
logo: imageLogoMap[matched],
|
logo: logoMap[matched],
|
||||||
type: matched
|
type: matched
|
||||||
}
|
}
|
||||||
: null;
|
: null;
|
||||||
@@ -135,6 +144,7 @@ interface TemplateCardProps {
|
|||||||
|
|
||||||
const TemplateCardItem: React.FC<TemplateCardProps> = ({ data, onSelect }) => {
|
const TemplateCardItem: React.FC<TemplateCardProps> = ({ data, onSelect }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const { isDarkTheme } = useUserSettings();
|
||||||
|
|
||||||
const manufacturerLabelMap: Record<string, string> = useMemo(() => {
|
const manufacturerLabelMap: Record<string, string> = useMemo(() => {
|
||||||
return Object.values(GPUsConfigs).reduce(
|
return Object.values(GPUsConfigs).reduce(
|
||||||
@@ -158,7 +168,7 @@ const TemplateCardItem: React.FC<TemplateCardProps> = ({ data, onSelect }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderLogo = () => {
|
const renderLogo = () => {
|
||||||
const imageLogo = matchImageLogo(data.spec?.image);
|
const imageLogo = matchImageLogo(data.spec?.image, isDarkTheme);
|
||||||
if (imageLogo?.logo) {
|
if (imageLogo?.logo) {
|
||||||
return (
|
return (
|
||||||
<LogoImg
|
<LogoImg
|
||||||
|
|||||||
Reference in New Issue
Block a user