Compare commits

..
Author SHA1 Message Date
jialin 5f405e4823 feat: cluster topology entry 2026-05-14 10:43:29 +08:00
623 changed files with 10064 additions and 31027 deletions
-143
View File
@@ -1,143 +0,0 @@
---
name: create-crud-page
description: Scaffold a CRUD list/table page module in the gpustack-ui monorepo. Use when creating a new page module, building a list/table page, adding a create/edit drawer, or setting up the components/config/forms/hooks/services structure for a feature.
---
# Create a CRUD Table Page
## Inputs (do this first)
- The argument passed to this skill is the **module name** (e.g. `/create-crud-page api-keys` → module `api-keys`). If no name was given, ask for it.
- **Always ask the user for the API documentation before generating any code**, even if a module name was provided:
> Where is the API documentation for this module? (OpenAPI/Swagger URL, schema file path, or an interface description)
- Wait for the answer, then read/fetch it. Derive `config/types.ts` (`FormData`, `ListItem`), the `services` request hooks, and form fields from that schema. Do not guess field names or endpoints — if the doc is missing details, ask.
- **Also ask which form layout to scaffold:**
> Should the form use tabs? (1) a plain form without tabs, or (2) a tabbed form
Choose the form structure in section 3 accordingly. Default to **no tabs** unless the user picks tabs or the schema clearly has many grouped sections.
---
Before anything: **reuse common `components`, `hooks`, and `utils` from `@gpustack/core-ui` whenever possible.**
Reference implementation for sections below: `src/pages/model-routes`.
## Module structure
Create the module under `src/pages/{module}`:
```text
{module}
├── components
├── config
├── forms
├── hooks
├── index.tsx
└── services
```
## 1. components
Module-specific components.
- The create/edit form component is named `add-xxx-modal.tsx` (repo convention — keep the `-modal` suffix even though it is built with `FormDrawer`).
- Use `FormDrawer` from `@gpustack/core-ui`.
- If a table cell's render logic/structure is complex, extract it into `xxx-cell.tsx`.
## 2. config
```text
config
├── index.ts # static configs & constants
└── types.ts # TypeScript types
```
Naming: form types → `FormData`; table list item types → `ListItem`.
## 3. forms
Main form component goes in `forms/index.tsx`.
- **Complex interactions** (Form.Item split across components): create a dedicated Form Context and wrap with `FormContext.Provider`.
- **Tab-based forms**: use `ScrollSpyTabs` from `@gpustack/core-ui`, wrapping the `Form` or `FormContext.Provider`. Do not use tabs unless necessary.
- **Required-field validation**: use `getRuleMessage` for standard `input`/`select`.
- For cascading selectors and async race protection, follow the **form-patterns** skill.
## 4. hooks
- Table columns → `use-xxx-columns.tsx`.
- Open/close hooks for `add-xxx-modal.tsx``use-create-xxx.ts`.
## 5. index.tsx (list page entry)
- **Data fetching**: `useTableFetch` from `@gpustack/core-ui`.
- **Data display**:
- Standard table → Ant Design `Table`. Ref: `src/pages/users/index.tsx`.
- Expandable/collapsible rows → `Table` from `@gpustack/core-ui`. Ref: `src/pages/model-routes/index.tsx`.
- Card-style lists → use `InfiniteScrollerProvider`. Ref: `src/pages/backends/index.tsx`.
## 6. services
`request` is injected via a provider — do **not** create a centralized `apis` directory like in `gpustack-ui`. Define request hooks directly in `services`.
- Use `useRequest` from `@gpustack/core-ui`, or `useQueryData` (same underlying method).
- Ref: `src/pages/gpu-service/storage-types/services/use-create-storage-type.ts`.
## 7. Empty data
- Page table lists → `NoResult`.
- Simple (non-page) tables → `Empty` with `image={Empty.PRESENTED_IMAGE_SIMPLE}`.
## Common UI conventions
- **Drawer/Modal open/close**: use `useBodyScroll` from `@gpustack/core-ui`. Ref: `src/pages/model-routes/hooks/use-create-route.ts`.
- **Status display** (success/failed/processing/warning): use `StatusTag`, never `Tag` from `antd` directly. See **Status display** below. Ref: `src/pages/llmodels/components/table-list.tsx`.
- **Permission-gated visibility**: use `Access` / `useAccess`. Ref: `src/pages/access/index.tsx`.
- **Styles**: avoid `styled-components` for complex/large styling. Prefer `createStyles` for component-scoped dynamic styles, CSS Modules (`xxx.module.less`) for static structured styles.
## Status display
Use `StatusTag` from `@gpustack/core-ui` for status display. Do not use `Tag` from `antd` directly.
1. Define the mapping from business status values to UI status values in the module's `config/index.ts`:
```ts
import { StatusMaps } from '@/config';
import { StatusType } from '@/config/types';
export const XxxStatusValueMap = {
Running: 'running',
Pending: 'pending',
Failed: 'failed'
};
export const XxxStatusLabelMap: Record<string, string> = {
[XxxStatusValueMap.Running]: 'Running',
[XxxStatusValueMap.Pending]: 'Pending',
[XxxStatusValueMap.Failed]: 'Failed'
};
export const status: Record<string, StatusType> = {
[XxxStatusValueMap.Running]: StatusMaps.success,
[XxxStatusValueMap.Pending]: StatusMaps.transitioning,
[XxxStatusValueMap.Failed]: StatusMaps.error
};
```
2. In table columns, pass only the UI status value and display text required by `StatusTag`:
```tsx
<StatusTag
statusValue={{
status: status[value],
text: XxxStatusLabelMap[value] || value,
message: record.state_message
}}
/>
```
`statusValue.status` must be a value mapped from `StatusMaps` (`success`, `transitioning`, `warning`, `error`, `inactive`). Do not pass business status values such as `running` or `pending` directly.
-103
View File
@@ -1,103 +0,0 @@
---
name: form-patterns
description: Patterns for forms with cascading/dependent selections in the gpustack-ui monorepo. Use when building a form where picking one field derives another (pick A → auto-pick B → write form), handling async option loading on modal open, or protecting against stale async results.
---
# Form Patterns
Theme: keep cascading selections (pick A → derive B → write form) on a single, predictable path.
## Accessing the form: `form` vs `form.current`
This is **not** absolute — it depends on the call site:
- **Inside the form component** (`forms/index.tsx`), or anywhere holding a `Form.useForm()` instance → call it directly: `form.setFieldsValue(...)`.
- **In the outer Drawer/Modal wrapper** that opens the form and holds it via `ref={form}` (`const form = useRef(null)`), driven by an `open` prop → go through the ref: `form.current?.setFieldsValue(...)`.
The reference template below is written for the **Drawer-wrapper scenario** (it reacts to `open` and owns the shared `selection` state), so it uses `form.current?` throughout. If you lift this logic into the form body with a `useForm()` instance, drop the `.current`.
## 1. No fallback for derived selection
When "pick A then auto-pick B", match by rule and return `undefined` if no match — let the form field stay empty. Do **not** silently fall back to `list[0]`; a fallback hides data issues and fakes a valid selection.
```ts
const findB = (key, list) =>
key ? list.find((x) => x.key === key) : undefined;
```
For form fields, clear with `undefined`, not `''`. In Ant Design `undefined` restores the placeholder; `''` is treated as a real value.
## 2. Async race protection
For fetches triggered by a lifecycle entry (e.g. modal open), tag each invocation with a session ref. Discard stale results if the session rotated (modal closed and re-opened) before the response arrives.
```ts
const sessionRef = useRef(0);
useEffect(() => {
if (!open) {
sessionRef.current += 1;
return;
}
const session = ++sessionRef.current;
Promise.all([fetchA(), fetchB()]).then(([as, bs]) => {
if (sessionRef.current !== session) return;
applySelection(as.items[0], findB(as.items[0].key, bs.items));
});
}, [open]);
```
## 3. Reference template
Two cascading selectors backed by a single shared state, with a single atomic write (state + form together):
```ts
type Selection = { a?: string; b?: number };
const [selection, setSelection] = useState<Selection>({});
const sessionRef = useRef(0);
const form = useRef<any>(null); // wrapper holds the form via <Form ref={form} /> — see "Accessing the form" above
const findB = (key, list) =>
key ? list.find((x) => x.key === key) : undefined;
// Single atomic write: state + form together.
const applySelection = (a, b) => {
setSelection({ a: a.name, b: b?.id });
form.current?.setFieldsValue({
field: b?.field,
spec: { ...currentSpec, ...b?.spec }
});
};
// Trigger 1: modal opened
useEffect(() => {
if (!open) {
sessionRef.current++;
setSelection({});
return;
}
const session = ++sessionRef.current;
Promise.all([fetchA(), fetchB()]).then(([as, bs]) => {
if (sessionRef.current !== session) return;
const first = as.items[0];
applySelection(first, findB(first.key, bs.items));
});
}, [open]);
// Trigger 2: user picks A
const handleAChange = (a) => {
applySelection(a, findB(a.key, listB));
};
// Trigger 3: user picks B
const handleBChange = (b) => {
setSelection((prev) => ({ ...prev, b: b.id }));
form.current?.setFieldsValue({ ...b.fields });
};
```
## Related
- Module/file structure for forms lives in the **create-crud-page** skill (section 3).
- Required-field validation: use `getRuleMessage`.
-18
View File
@@ -1,7 +1,6 @@
name: CI
on:
workflow_dispatch: {}
push:
branches:
- 'main'
@@ -118,20 +117,3 @@ jobs:
remote_path: releases/${{ steps.version.outputs.version }}.tar.gz
accelerate: true
clean: false
trigger-backend:
needs: build-publish
if: (github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')) || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-22.04
steps:
- name: Dispatch backend build
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.DISPATCH_PAT }}
repository: gpustack/gpustack
event-type: ui-built
client-payload: |
{
"ref": "${{ github.ref }}",
"sha": "${{ github.sha }}"
}
+1 -2
View File
@@ -13,6 +13,5 @@
.swc
.DS_Store
.idea
.claude/settings.local.json
.claude
/dist.zip
.cache
+2 -1
View File
@@ -3,6 +3,7 @@ node_modules
.umi-production
public/static/*.js
public/static/*.css
src/components/iconfont/
src/components/icon-font/iconfont/iconfont.js
src/components/icon-font/iconfont/*.css
+1 -1
View File
@@ -3,5 +3,5 @@ module.exports = {
rules: {
'selector-class-pattern': null
},
ignoreFiles: ['public/static/*.css', 'src/components/iconfont/iconfont.css']
ignoreFiles: ['public/static/*.css']
};
-57
View File
@@ -1,57 +0,0 @@
# Agent Instructions
This project keeps a single source of truth for agent/contributor conventions in [`CLAUDE.md`](./CLAUDE.md). **Read [`CLAUDE.md`](./CLAUDE.md) and follow it.**
@CLAUDE.md
## Downstream fork workflow
This repo is a **downstream fork** that customizes the product appearance on top of upstream `gpustack/gpustack-ui`. The mirror chain is:
```
upstream https://github.com/gpustack/gpustack-ui.git
| (fetch)
origin ssh://git@192.168.0.23:11022/root/gpustack-ui.git (private registry, also https://git.digiman.live)
```
### Goal
Track upstream releases. When upstream changes, we pull it in, then apply our own appearance/customization changes on a dedicated branch so we keep our look-and-feel on top of the latest upstream product.
### Branch naming
Customization work lives on `v<upstream-version>-lofyer` branches (e.g. `v2.2.0-lofyer`). Each time upstream ships a new version we want to follow, create a new `v<version>-lofyer` branch from the corresponding upstream tag/branch and re-apply (or rebase) our customizations onto it.
### Syncing from upstream
`scripts/sync-github` mirrors upstream into the private `origin` (full mirror, force push of all branches + tags). It auto-configures the `upstream` remote on first run.
```bash
# preview only, no push
DRY_RUN=1 ./scripts/sync-github
# real sync (force-pushes every upstream branch + tag to origin)
./scripts/sync-github
# also delete origin branches that no longer exist upstream (true mirror, destructive)
PRUNE_BRANCHES=1 ./scripts/sync-github
```
Env knobs: `UPSTREAM_URL`, `ORIGIN_REMOTE`, `UPSTREAM_REMOTE`, `PRUNE_BRANCHES`, `DRY_RUN`. After syncing, branch a fresh `v<version>-lofyer` off the updated upstream ref and apply the appearance changes there.
### Re-applying brand customizations
`scripts/rebrand` swaps the standalone brand word `GPUStack` for our brand (`MesaStack`) across user-facing text. It is the first appearance change to re-apply on every new `v<version>-lofyer` branch.
```bash
# preview hits, no writes
DRY_RUN=1 ./scripts/rebrand
# apply (default GPUStack -> MesaStack)
./scripts/rebrand
# custom brand words
FROM=GPUStack TO=AcmeStack ./scripts/rebrand
```
It deliberately **does not** touch functional references — lowercase `gpustack` (npm pkg / URLs / paths / k8s namespace), ALL-CAPS `GPUSTACK_*` constants, JS identifiers like `getGPUStackPlugin`, and `X-*` HTTP headers — and carries a line-level skip list for backend-contract strings matched at runtime (see `SKIP_LINE_PATTERNS` in the script). Always review `git diff` afterwards. Logo images under `src/assets/images/` are NOT changed by the script — replace those PNGs separately when new brand assets are available.
-151
View File
@@ -1,151 +0,0 @@
# Repo
This is the **open source UI** (`gpustack-ui`). Common `components`, `hooks`, and `utils` are published as `@gpustack/core-ui` and consumed throughout `src`.
**Always prioritize reusing common `components`, `hooks`, and `utils` from `@gpustack/core-ui`.**
Task-specific conventions live in skills: use **create-crud-page** when building a page module, **form-patterns** when building cascading/dependent forms.
# React State and Request Patterns
Keep data flow explicit, predictable, and performant. The triggering **action** is the source of truth for UI updates — not effect-driven synchronization.
## 1. Avoid effect-driven requests
Do not use request functions as `useEffect` dependencies. Trigger requests explicitly from user actions or lifecycle entry points.
```ts
// Avoid
useEffect(() => {
fetchData();
}, [fetchData]);
```
## 2. Form requests should be action-driven
- Fetch form data (e.g. `Select` options) when the form first opens.
- If later requests depend on interactions, trigger them inside the interaction handler.
- Do not rely on `useEffect` dependency changes.
```ts
// Recommended
const handleOnChange = (value) => {
fetchData(value);
};
```
## 3. Update related states together
When one action updates multiple related states, update them all directly in the handler. Do not sync via `useEffect` or derive indirectly via `useMemo`.
```ts
const handleOnChange = (value) => {
setState1(...);
setState2(...);
buildState(...);
};
```
## 4. Group strongly related state
If multiple states always update together, use a single state object instead of multiple `useState` calls — fewer rerenders, more predictable transitions.
```ts
const [state, setState] = useState({ state1: ..., state2: ..., state3: ... });
```
## 5. Prefer explicit state flow
Keep request execution, state updates, and derived calculations close to the triggering action. Avoid chaining business logic through multiple `useEffect` hooks.
```ts
// Prefer
const handleAction = () => {
fetchData();
setTableData(...);
setSelectedRow(...);
};
```
## 6. Avoid premature memoization
Do not use `useMemo` / `useCallback` unless there is a confirmed bottleneck. Overuse adds complexity, obscures state flow, and risks stale dependencies. Optimize only when necessary.
## 7. Keep request logic predictable
A user interaction should clearly show: what request fires, which states update, how the UI changes. Avoid indirect update chains from dependency-driven effects.
## 8. Prefer action-driven architecture
Prefer action-driven updates, explicit handlers, and localized state transitions over effect-driven synchronization, cross-hook implicit updates, and reactive chains between states.
# Styles
**Future direction (apply to all new code):** avoid `styled-components`. Prefer:
1. `createStyles` for component-scoped dynamic styles
2. CSS Modules (`xxx.module.less`) for structured static styles
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
A page module lives under `src/pages/{module}` with this sub-structure: `components/`, `config/`, `forms/`, `hooks/`, `services/`, `index.tsx`. File naming:
- **Create/edit modal**: `add-{feature}-modal.tsx` (keep the `-modal` suffix even when built with `FormDrawer`).
- **Table columns hook**: `use-{feature}-columns.tsx`.
- **Open/close & request hooks**: `use-{verb}-{noun}.ts` (e.g. `use-create-user.ts`, `use-query-user-list.ts`).
- **Complex table cell**: extract into `{feature}-cell.tsx`.
# Config & types
- `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`.
- **`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
Always check `@gpustack/core-ui` first. Frequently reused:
- **Drawer/Modal open/close**: `useBodyScroll`.
- **Form drawer / footer**: `FormDrawer`, `ModalFooter`.
- **Delete confirmation**: `DeleteModal`.
- **Search + bulk actions bar**: `FilterBar`.
- **Form fields**: `BaseSelect`, `Input` (labeled).
- **Text overflow**: `AutoTooltip`.
- **Icons**: `IconFont`.
- **Tags & status** (4 variants): see the section below.
- **Permission-gated visibility**: `Access` / `useAccess`.
- **Request hooks**: `useRequest` / `useQueryData` / `useQueryDataList`.
- **Table data fetching**: `useTableFetch`.
- **Submit guard** (prevent double-submit): `useSubmitLock`.
- **Tabbed forms**: `ScrollSpyTabs`.
# Tags & status indicators
Four core-ui components cover tag/status display in tables and lists. Pick by **what the value means**, not by how it looks — don't reach for a generic antd `Tag`:
- **`StatusTag`** — semantic status with a **dynamic message/detail** (tooltip, download, extra content). Use when a row's status carries variable text, e.g. a failed job with an error message. Colors come from `StatusColorMap` (error/warning/transitioning/success/inactive).
- **`StatusDot`** — colored dot + short label, **no message**. Use for a plain status/type cell where the value is a fixed enum (e.g. an event-type or log column). Same `StatusColorMap` palette; `inactive` dot is quaternary. If the status needs dynamic text, use `StatusTag` instead.
- **`ThemeTag`** — a **standalone category label** (independent content, e.g. a permission scope or a model name). Default neutral; wraps antd `Tag`.
- **`TextAttribute`** — a small neutral pill that is a **subordinate annotation following a primary text** (e.g. `key-name [custom]`), not a standalone tag. Manages its own leading margin. Two variants: `filled` (default) and `outlined`. Ref the name column in `src/pages/api-keys/hooks/use-keys-columns.tsx`.
Rule of thumb: semantic + dynamic text → `StatusTag`; semantic + fixed enum → `StatusDot`; independent category → `ThemeTag`; annotation of nearby text → `TextAttribute`.
# Dynamic add-item form fields
When building a form, select the add-item component from the **shape of the field's data** (its schema). Match the schema, don't hand-roll a list UI:
- **Plain object** (key→value map) → `LabelSelector`.
- **String array** → `ListInput`. Ref `src/pages/llmodels/forms/backend-parameters-list.tsx`.
- **Object array** → `MetadataList` with a custom item renderer per entry. Ref `src/pages/llmodels/forms/model-lora-list.tsx`.
+46
View File
@@ -0,0 +1,46 @@
## Create form table list
## Create a form
## StatusTag
Use `StatusTag` from `@gpustack/core-ui` for status display. Do not use `Tag` from `antd` directly.
1. Define the mapping from business status values to UI status values in the module's `config/index.ts`:
```ts
import { StatusMaps } from '@/config';
import { StatusType } from '@/config/types';
export const XxxStatusValueMap = {
Running: 'running',
Pending: 'pending',
Failed: 'failed'
};
export const XxxStatusLabelMap: Record<string, string> = {
[XxxStatusValueMap.Running]: 'Running',
[XxxStatusValueMap.Pending]: 'Pending',
[XxxStatusValueMap.Failed]: 'Failed'
};
export const status: Record<string, StatusType> = {
[XxxStatusValueMap.Running]: StatusMaps.success,
[XxxStatusValueMap.Pending]: StatusMaps.transitioning,
[XxxStatusValueMap.Failed]: StatusMaps.error
};
```
2. In table columns, pass only the UI status value and display text required by `StatusTag`:
```tsx
<StatusTag
statusValue={{
status: status[value],
text: XxxStatusLabelMap[value] || value,
message: record.state_message
}}
/>
```
`statusValue.status` must be a value mapped from `StatusMaps`, such as `success`, `transitioning`, `warning`, `error`, or `inactive`. Do not pass business status values such as `running` or `pending` directly.
+2 -2
View File
@@ -1,6 +1,6 @@
# MesaStack UI
# GPUStack UI
UI for [MesaStack](https://github.com/gpustack/gpustack).
UI for [GPUStack](https://github.com/gpustack/gpustack).
## Installation
+1 -1
View File
@@ -77,7 +77,7 @@ export default defineConfig({
antd: {
style: 'less'
},
title: 'ZStack AIOS',
title: 'GPUStack',
hash: true,
access: {},
model: {},
-1
View File
@@ -31,6 +31,5 @@ export default function createProxyTable(target?: string) {
},
{}
);
return proxyTable;
}
+77 -113
View File
@@ -100,15 +100,6 @@ const baseRoutes = [
path: '/models',
redirect: '/models/deployments'
},
{
name: 'userModels',
path: '/models/user-models',
key: 'userModels',
icon: 'icon-models',
selectedIcon: 'icon-models-filled',
defaultIcon: 'icon-models',
component: './llmodels/user-models'
},
{
name: 'modelCatalog',
path: '/models/catalog',
@@ -119,6 +110,16 @@ const baseRoutes = [
access: 'canSeeOrgAdmin',
component: './llmodels/catalog'
},
{
name: 'userModels',
path: '/models/user-models',
key: 'userModels',
icon: 'icon-models',
selectedIcon: 'icon-models-filled',
defaultIcon: 'icon-models',
access: 'canSeeUser',
component: './llmodels/user-models'
},
{
name: 'deployment',
path: '/models/deployments',
@@ -139,6 +140,15 @@ const baseRoutes = [
access: 'canSeeOrgAdmin',
component: './model-routes/index'
},
{
name: 'usage',
path: '/models/usage',
key: 'usage',
icon: 'icon-usage-outlined',
selectedIcon: 'icon-usage-filled',
defaultIcon: 'icon-usage-outlined',
component: './usage/index'
},
{
name: 'providers',
path: '/models/providers',
@@ -169,26 +179,6 @@ const baseRoutes = [
access: 'canSeeOrgAdmin',
hideInMenu: true,
component: './benchmark/details'
},
{
name: 'backendsList',
path: '/models/backends',
key: 'backendsList',
icon: 'icon-backend',
selectedIcon: 'icon-backend-filled',
defaultIcon: 'icon-backend',
access: 'canSeeOrgAdmin',
component: './backends/index'
},
{
name: 'modelfiles',
path: '/models/modelfiles',
key: 'modelfiles',
icon: 'icon-files',
selectedIcon: 'icon-files-filled',
defaultIcon: 'icon-files',
access: 'canSeeOrgAdmin',
component: './resources/components/model-files'
}
]
},
@@ -196,7 +186,6 @@ const baseRoutes = [
name: 'gpuService',
path: '/gpu-service',
key: 'gpuService',
access: 'canSeeGpuService',
routes: [
{
path: '/gpu-service',
@@ -224,25 +213,10 @@ const baseRoutes = [
name: 'storage',
path: '/gpu-service/storage',
key: 'gpuServiceStorage',
icon: 'icon-database-outlined',
selectedIcon: 'icon-database-filled',
defaultIcon: 'icon-database-outlined',
component: './gpu-service/storage'
},
{
name: 'storageTypes',
path: '/gpu-service/storage-types',
key: 'gpuServiceStorageTypes',
icon: 'icon-storage-outlined',
// Storage types are tenant-scoped on the backend (Org owners
// can create/list their own), so the menu shouldn't be
// platform-admin-only. ``canSeeOrgAdmin`` keeps the gate at
// "admin or current-org owner" — Org members still don't see
// it, which matches the read/write model in the route.
access: 'canSeeOrgAdmin',
selectedIcon: 'icon-storage-filled',
defaultIcon: 'icon-storage-outlined',
component: './gpu-service/storage-types'
component: './gpu-service/storage'
},
{
name: 'publicKeys',
@@ -265,16 +239,6 @@ const baseRoutes = [
path: '/resources',
redirect: '/resources/workers'
},
{
name: 'clusters',
path: '/resources/clusters/list',
key: 'clusters',
icon: 'icon-cluster2-outline',
selectedIcon: 'icon-cluster2-filled',
defaultIcon: 'icon-cluster2-outline',
component: './cluster-management/clusters',
subMenu: ['/resources/clusters/create']
},
{
name: 'workers',
path: '/resources/workers',
@@ -293,9 +257,63 @@ const baseRoutes = [
defaultIcon: 'icon-gpu1',
component: './resources/components/gpus'
},
{
name: 'backendsList',
path: '/resources/backends',
key: 'backendsList',
icon: 'icon-backend',
selectedIcon: 'icon-backend-filled',
defaultIcon: 'icon-backend',
access: 'canSeeOrgAdmin',
component: './backends/index'
},
{
name: 'modelfiles',
path: '/resources/modelfiles',
key: 'modelfiles',
icon: 'icon-files',
selectedIcon: 'icon-files-filled',
defaultIcon: 'icon-files',
component: './resources/components/model-files'
}
]
},
{
name: 'clusterManagement',
path: '/cluster-management',
key: 'clusterManagement',
access: 'canSeeOrgAdmin',
routes: [
{
path: '/cluster-management',
redirect: '/cluster-management/clusters/list'
},
{
name: 'clusters',
path: '/cluster-management/clusters/list',
key: 'clusters',
icon: 'icon-cluster2-outline',
selectedIcon: 'icon-cluster2-filled',
defaultIcon: 'icon-cluster2-outline',
component: './cluster-management/clusters',
subMenu: [
'/cluster-management/clusters/detail',
'/cluster-management/clusters/create'
]
},
{
name: 'clusterDetail',
path: '/cluster-management/clusters/detail',
key: 'clusterDetail',
icon: 'icon-cluster2-outline',
selectedIcon: 'icon-cluster2-filled',
defaultIcon: 'icon-cluster2-outline',
hideInMenu: true,
component: './cluster-management/cluster-detail'
},
{
name: 'credentials',
path: '/resources/credentials',
path: '/cluster-management/credentials',
key: 'credentials',
icon: 'icon-credential-outline',
selectedIcon: 'icon-credential-filled',
@@ -304,46 +322,6 @@ const baseRoutes = [
}
]
},
{
// Cross-resource consumption (tokens + GPU/CPU instances + storage).
// A folder so it matches the other top-level groups; more usage views can
// graduate in here later.
name: 'billingAndUsage',
path: '/usage',
key: 'usageGroup',
icon: 'icon-usage-outlined',
selectedIcon: 'icon-usage-filled',
defaultIcon: 'icon-usage-outlined',
routes: [
{
path: '/usage',
redirect: '/usage/overview'
},
{
name: 'usage',
path: '/usage/overview',
key: 'usage',
icon: 'icon-usage-outlined',
selectedIcon: 'icon-usage-filled',
defaultIcon: 'icon-usage-outlined',
component: './usage/index'
},
{
name: 'billing',
path: '/usage/billing',
key: 'billing',
icon: 'icon-billing-outlined',
selectedIcon: 'icon-billing-filled',
defaultIcon: 'icon-billing-outlined',
hideInMenu: process.env.ENABLE_ENTERPRISE === 'true',
// OSS exposes the menu as a teaser for the enterprise billing
// module. The page itself just renders an upsell notice — the real
// billing UI lives in the enterprise plugin and shadows this route
// via `routes.extensions.ts`.
component: './billing'
}
]
},
{
name: 'accessControl',
path: '/access-control',
@@ -353,20 +331,6 @@ const baseRoutes = [
path: '/access-control',
redirect: '/access-control/users'
},
{
name: 'organizations',
path: '/access-control/organizations',
key: 'organizations',
icon: 'icon-org-outlined',
selectedIcon: 'icon-org-filled',
defaultIcon: 'icon-org-outlined',
// OSS exposes the menu to platform admins as a teaser for the
// enterprise multi-tenancy module. The page itself just renders
// an upsell notice — the real CRUD UI lives in the enterprise
// plugin and shadows this route via `routes.extensions.ts`.
access: 'canSeeAdmin',
component: './organizations'
},
{
name: 'users',
path: '/access-control/users',
@@ -400,8 +364,8 @@ const baseRoutes = [
},
{
name: 'profile',
path: '/preferences',
key: 'preferences',
path: '/profile',
key: 'profile',
hideInMenu: true,
component: './profile',
icon: 'User'
+10 -24
View File
@@ -1,27 +1,13 @@
import { execSync } from 'child_process';
const child_process = require('child_process');
export const getBranchInfo = () => {
// git may be absent (source archive, bare container) or this tree may
// not be a git checkout. Swallow the failure and fall back to the env
// overrides below — losing build info shouldn't fail the build.
let latestCommit = '';
let versionTag = '';
try {
latestCommit = execSync('git rev-parse HEAD').toString().trim();
versionTag = execSync(`git tag --contains ${latestCommit}`)
.toString()
.trim();
} catch {
// Not a git checkout / git unavailable; rely on env overrides.
}
// Respect explicit GPUSTACK_UI_* overrides so a wrapping build that
// checks this source tree out as a sub-package can stamp its own
// release tag and commit id onto the UI (otherwise the panel reports
// the host tree's git HEAD, which the wrapper doesn't control).
const overrideVersion = process.env.GPUSTACK_UI_VERSION?.trim();
const overrideCommitId = process.env.GPUSTACK_UI_COMMIT_ID?.trim();
return {
version: overrideVersion || versionTag || '',
commitId: overrideCommitId || latestCommit.slice(0, 7)
};
const latestCommit = child_process
.execSync('git rev-parse HEAD')
.toString()
.trim();
const versionTag = child_process
.execSync(`git tag --contains ${latestCommit}`)
.toString()
.trim();
return { version: versionTag || '', commitId: latestCommit.slice(0, 7) };
};
+1 -2
View File
@@ -14,8 +14,7 @@ export default defineConfig([
'dist',
'src/.umi/',
'src/.umi-production/',
'src/.umi-test/',
'src/components/iconfont/'
'src/.umi-test/'
]),
{
files: ['**/*.{ts,tsx,js,jsx}'],
+2 -1
View File
@@ -17,7 +17,7 @@
"@ant-design/pro-components": "3.1.0-0",
"@antv/g6": "^5.0.51",
"@braintree/sanitize-url": "^7.1.1",
"@gpustack/core-ui": "^1.0.42",
"@gpustack/core-ui": "^1.0.10",
"@huggingface/gguf": "^0.1.7",
"@huggingface/hub": "^0.15.1",
"@huggingface/tasks": "^0.11.6",
@@ -39,6 +39,7 @@
"culori": "^4.0.2",
"dayjs": "^1.11.11",
"dompurify": "^3.2.6",
"driver.js": "^1.3.1",
"echarts": "^5.5.1",
"file-saver": "^2.0.5",
"has-ansi": "^5.0.1",
-2
View File
@@ -5,8 +5,6 @@ export default (api: IApi) => {
const info = JSON.parse(process.env.VERSION || '{}');
const env = process.env.NODE_ENV;
$('html').attr('lang', 'en');
$('html').attr('data-env', env);
$('html').attr(
+143 -176
View File
@@ -24,8 +24,8 @@ importers:
specifier: ^7.1.1
version: 7.1.2
'@gpustack/core-ui':
specifier: ^1.0.42
version: 1.0.42(czdvzceysqw7iv6pct2ucnb23e)
specifier: ^1.0.10
version: 1.0.10(czdvzceysqw7iv6pct2ucnb23e)
'@huggingface/gguf':
specifier: ^0.1.7
version: 0.1.18
@@ -49,7 +49,7 @@ importers:
version: 4.17.24
'@umijs/max':
specifier: ^4.6.15
version: 4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(lightningcss@1.22.1)(prettier@3.8.3)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
version: 4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(lightningcss@1.22.1)(prettier@3.8.3)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@xterm/addon-fit':
specifier: ^0.10.0
version: 0.10.0(@xterm/xterm@5.5.0)
@@ -89,6 +89,9 @@ importers:
dompurify:
specifier: ^3.2.6
version: 3.4.2
driver.js:
specifier: ^1.3.1
version: 1.4.0
echarts:
specifier: ^5.5.1
version: 5.6.0
@@ -106,7 +109,7 @@ importers:
version: 3.3.0
jotai:
specifier: ^2.8.4
version: 2.20.0(@babel/core@7.23.6)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1)
version: 2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1)
js-yaml:
specifier: ^4.1.0
version: 4.1.1
@@ -202,7 +205,7 @@ importers:
version: 6.4.1(css-to-react-native@3.2.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
umi-presets-pro:
specifier: ^2.0.3
version: 2.0.3(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(chokidar@3.6.0)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(umi@4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))
version: 2.0.3(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(chokidar@3.6.0)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(umi@4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))
wavesurfer.js:
specifier: ^7.8.8
version: 7.12.6
@@ -230,10 +233,10 @@ importers:
version: 1.0.1
'@umijs/plugins':
specifier: ^4.4.11
version: 4.6.51(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
version: 4.6.51(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
babel-plugin-named-asset-import:
specifier: ^0.3.8
version: 0.3.8(@babel/core@7.23.6)
version: 0.3.8(@babel/core@7.29.0)
case-sensitive-paths-webpack-plugin:
specifier: ^2.4.0
version: 2.4.0
@@ -1481,24 +1484,24 @@ packages:
resolution: {integrity: sha512-KWk80UPIzPmUg+P0rKh6TqspRw0G6eux1PuJr+zz47ftMaZ9QDwbGzHZbtzWkl5hgayM/qrKRutllRC7D/vVXQ==, tarball: https://registry.npmjs.org/@formatjs/intl-utils/-/intl-utils-2.3.0.tgz}
deprecated: the package is rather renamed to @formatjs/ecma-abstract with some changes in functionality (primarily selectUnit is removed and we don't plan to make any further changes to this package
'@gpustack/core-ui@1.0.42':
resolution: {integrity: sha512-upMClTHU+xAqd8dlx0w1S9XWHlog5g1hcOCulTk2rmMXqgl66QHfqhEFhJnWIGe1xc8tEj6rW3r5Sirif+qswA==, tarball: https://registry.npmjs.org/@gpustack/core-ui/-/core-ui-1.0.42.tgz}
'@gpustack/core-ui@1.0.10':
resolution: {integrity: sha512-gw1dlkb0NzcKy23aGa+4EPe9tHI0hgxoUf/ZJZkjvjQQjAZ+zxZFtLscHGvlTVxwc7GE5FOeGjOIGlbIxW+7EA==, tarball: https://registry.npmjs.org/@gpustack/core-ui/-/core-ui-1.0.10.tgz}
peerDependencies:
'@ant-design/icons': ^6.1.0
'@ant-design/icons': '>=6.0.0'
'@ant-design/pro-components': 3.1.0-0
'@monaco-editor/react': ^4.6.0
ahooks: ^3.8.5
antd: ^6.3.3
antd-style: ^3.6.2
axios: ^1.8.2
echarts: ^5.5.1
ahooks: '>=3.0.0'
antd: '>=6.0.0'
antd-style: '>=3.0.0'
axios: '>=1.8.0'
echarts: '>=5.0.0'
file-saver: ^2.0.5
monaco-editor: ^0.30.1
monaco-yaml: ^4.0.0
overlayscrollbars-react: ^0.5.6
react: ^18.2.0
react-dom: ^18.2.0
styled-components: ^6.1.15
react: '>=18.0.0'
react-dom: '>=18.0.0'
styled-components: '>=6.0.0'
'@hono/node-server@1.19.14':
resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==, tarball: https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz}
@@ -2460,9 +2463,6 @@ packages:
'@types/node@25.6.2':
resolution: {integrity: sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw==, tarball: https://registry.npmjs.org/@types/node/-/node-25.6.2.tgz}
'@types/node@25.9.1':
resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==, tarball: https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz}
'@types/normalize-package-data@2.4.4':
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==, tarball: https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz}
@@ -2492,9 +2492,6 @@ packages:
'@types/react@18.3.28':
resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==, tarball: https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz}
'@types/react@18.3.29':
resolution: {integrity: sha512-ch0qJdr2JY0r04NXSprbK6TXOgnaJ1Tz23fm5W+z0/CBah6BSBc3n96h7K9GOtwh0HrilNWHIBzE1Ko4Dcw/Wg==, tarball: https://registry.npmjs.org/@types/react/-/react-18.3.29.tgz}
'@types/resolve@1.20.6':
resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==, tarball: https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz}
@@ -4317,6 +4314,9 @@ packages:
dot-case@3.0.4:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==, tarball: https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz}
driver.js@1.4.0:
resolution: {integrity: sha512-Gm64jm6PmcU+si21sQhBrTAM1JvUrR0QhNmjkprNLxohOBzul9+pNHXgQaT9lW84gwg9GMLB3NZGuGolsz5uew==, tarball: https://registry.npmjs.org/driver.js/-/driver.js-1.4.0.tgz}
duck@0.1.12:
resolution: {integrity: sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==, tarball: https://registry.npmjs.org/duck/-/duck-0.1.12.tgz}
@@ -4402,10 +4402,6 @@ packages:
resolution: {integrity: sha512-xe9vQb5kReirPUxgQrXA3ihgbCqssmTiM7cOZ+Gzu+VeGWgpV98lLZvp0dl4yriyAePcewxGUs9UpKD8PET9KQ==, tarball: https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.2.tgz}
engines: {node: '>=10.13.0'}
enhanced-resolve@5.22.0:
resolution: {integrity: sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==, tarball: https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.0.tgz}
engines: {node: '>=10.13.0'}
enhanced-resolve@5.9.3:
resolution: {integrity: sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==, tarball: https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz}
engines: {node: '>=10.13.0'}
@@ -8609,11 +8605,6 @@ packages:
engines: {node: '>=10'}
hasBin: true
terser@5.48.0:
resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==, tarball: https://registry.npmjs.org/terser/-/terser-5.48.0.tgz}
engines: {node: '>=10'}
hasBin: true
test-exclude@6.0.0:
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, tarball: https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz}
engines: {node: '>=8'}
@@ -8827,9 +8818,6 @@ packages:
undici-types@7.19.2:
resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==, tarball: https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz}
undici-types@7.24.6:
resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==, tarball: https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz}
unfetch@5.0.0:
resolution: {integrity: sha512-3xM2c89siXg0nHvlmYsQ2zkLASvVMBisZm5lF3gFDqfF2xonNStDJyMpvaOBe0a1Edxmqrf2E0HBdmy9QyZaeg==, tarball: https://registry.npmjs.org/unfetch/-/unfetch-5.0.0.tgz}
@@ -9062,8 +9050,8 @@ packages:
engines: {node: '>= 10.13.0'}
hasBin: true
webpack-sources@3.5.0:
resolution: {integrity: sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==, tarball: https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz}
webpack-sources@3.4.1:
resolution: {integrity: sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==, tarball: https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.4.1.tgz}
engines: {node: '>=10.13.0'}
webpack@5.106.2:
@@ -9251,14 +9239,14 @@ snapshots:
'@radix-ui/popper': 0.0.10
react: 18.3.1
'@alita/plugins@3.5.5(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@alita/plugins@3.5.5(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@alita/babel-transform-jsx-class': 0.0.2
'@alita/inspx': 0.0.2(react@18.3.1)
'@alita/request': 3.1.2
'@alita/types': 3.1.2
'@umijs/bundler-utils': 4.4.11
'@umijs/plugins': 4.4.11(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/plugins': 4.4.11(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/utils': 4.4.11
ahooks: 3.9.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
antd-mobile-alita: 2.3.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -10128,90 +10116,90 @@ snapshots:
dependencies:
'@babel/types': 7.29.0
'@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.6)':
'@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.6)':
'@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.6)':
'@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.6)':
'@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.23.6)':
'@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.6)':
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.6)':
'@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.23.6)':
'@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.6)':
'@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.6)':
'@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.6)':
'@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.6)':
'@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.6)':
'@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.6)':
'@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.6)':
'@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.6)':
'@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
'@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.6)':
'@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.23.6
'@babel/helper-module-transforms': 7.28.6(@babel/core@7.23.6)
'@babel/core': 7.29.0
'@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
'@babel/helper-plugin-utils': 7.28.6
'@babel/helper-simple-access': 7.27.1
transitivePeerDependencies:
@@ -10802,7 +10790,7 @@ snapshots:
'@formatjs/intl-utils@2.3.0': {}
'@gpustack/core-ui@1.0.42(czdvzceysqw7iv6pct2ucnb23e)':
'@gpustack/core-ui@1.0.10(czdvzceysqw7iv6pct2ucnb23e)':
dependencies:
'@ant-design/icons': 6.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@ant-design/pro-components': 3.1.0-0(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -11877,10 +11865,6 @@ snapshots:
dependencies:
undici-types: 7.19.2
'@types/node@25.9.1':
dependencies:
undici-types: 7.24.6
'@types/normalize-package-data@2.4.4': {}
'@types/parse-json@4.0.2': {}
@@ -11901,31 +11885,26 @@ snapshots:
'@types/react-router-dom@4.3.5':
dependencies:
'@types/history': 5.0.0
'@types/react': 18.3.29
'@types/react': 18.3.28
'@types/react-router': 5.1.20
'@types/react-router-redux@5.0.27':
dependencies:
'@types/history': 4.7.11
'@types/react': 18.3.29
'@types/react': 18.3.28
'@types/react-router': 5.1.20
redux: 4.2.1
'@types/react-router@5.1.20':
dependencies:
'@types/history': 4.7.11
'@types/react': 18.3.29
'@types/react': 18.3.28
'@types/react@18.3.28':
dependencies:
'@types/prop-types': 15.7.15
csstype: 3.2.3
'@types/react@18.3.29':
dependencies:
'@types/prop-types': 15.7.15
csstype: 3.2.3
'@types/resolve@1.20.6': {}
'@types/semver@7.7.1': {}
@@ -12275,11 +12254,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@umijs/bundler-utoopack@4.6.51(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))':
'@umijs/bundler-utoopack@4.6.51(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))':
dependencies:
'@umijs/bundler-utils': 4.6.51
'@umijs/bundler-webpack': 4.6.51(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@utoo/pack': 1.4.3(less-loader@11.1.0(less@4.1.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(less@4.1.3)(postcss@8.5.14)(resolve-url-loader@5.0.0)(sass-loader@13.2.0(sass@1.54.0)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))
'@utoo/pack': 1.4.3(less-loader@11.1.0(less@4.1.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(less@4.1.3)(postcss@8.5.14)(resolve-url-loader@5.0.0)(sass-loader@13.2.0(sass@1.54.0)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))
compression: 1.8.1
connect-history-api-fallback: 2.0.0
cors: 2.8.6
@@ -12308,18 +12287,18 @@ snapshots:
- webpack-hot-middleware
- webpack-plugin-serve
'@umijs/bundler-vite@4.6.51(@types/node@25.6.2)(lightningcss@1.22.1)(postcss@8.5.14)(rollup@3.30.0)(sass@1.54.0)(terser@5.48.0)':
'@umijs/bundler-vite@4.6.51(@types/node@25.6.2)(lightningcss@1.22.1)(postcss@8.5.14)(rollup@3.30.0)(sass@1.54.0)(terser@5.47.1)':
dependencies:
'@svgr/core': 6.5.1
'@umijs/bundler-utils': 4.6.51
'@umijs/utils': 4.6.51
'@vitejs/plugin-react': 4.0.0(vite@4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.48.0))
'@vitejs/plugin-react': 4.0.0(vite@4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.47.1))
core-js: 3.34.0
less: 4.1.3
postcss-preset-env: 7.5.0(postcss@8.5.14)
rollup-plugin-visualizer: 5.9.0(rollup@3.30.0)
systemjs: 6.15.1
vite: 4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.48.0)
vite: 4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.47.1)
transitivePeerDependencies:
- '@types/node'
- lightningcss
@@ -12547,14 +12526,14 @@ snapshots:
- supports-color
- typescript
'@umijs/max@4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(lightningcss@1.22.1)(prettier@3.8.3)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))':
'@umijs/max@4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(lightningcss@1.22.1)(prettier@3.8.3)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))':
dependencies:
'@umijs/lint': 4.6.51(eslint@8.35.0)(stylelint@14.8.2)(typescript@5.9.3)
'@umijs/plugins': 4.6.51(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@4.24.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/plugins': 4.6.51(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@4.24.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
antd: 4.24.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
eslint: 8.35.0
stylelint: 14.8.2
umi: 4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@8.35.0)(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
umi: 4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@8.35.0)(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
transitivePeerDependencies:
- '@babel/core'
- '@rspack/core'
@@ -12636,7 +12615,7 @@ snapshots:
dependencies:
tsx: 3.12.2
'@umijs/plugins@4.4.11(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@umijs/plugins@4.4.11(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@ahooksjs/use-request': 2.8.15(react@18.3.1)
'@ant-design/antd-theme-variable': 1.0.0
@@ -12651,7 +12630,7 @@ snapshots:
antd-dayjs-webpack-plugin: 1.0.6(dayjs@1.11.20)
axios: 0.27.2
babel-plugin-import: 1.13.8
babel-plugin-styled-components: 2.1.4(@babel/core@7.23.6)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
babel-plugin-styled-components: 2.1.4(@babel/core@7.29.0)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
dayjs: 1.11.20
dva-core: 2.0.4(redux@4.2.1)
dva-immer: 1.0.2(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
@@ -12681,7 +12660,7 @@ snapshots:
- react-native
- supports-color
'@umijs/plugins@4.6.51(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@4.24.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@umijs/plugins@4.6.51(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@4.24.16(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@ahooksjs/use-request': 2.8.15(react@18.3.1)
'@ant-design/antd-theme-variable': 1.0.0
@@ -12696,7 +12675,7 @@ snapshots:
antd-dayjs-webpack-plugin: 1.0.6(dayjs@1.11.20)
axios: 0.27.2
babel-plugin-import: 1.13.8
babel-plugin-styled-components: 2.1.4(@babel/core@7.23.6)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
babel-plugin-styled-components: 2.1.4(@babel/core@7.29.0)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
dayjs: 1.11.20
dva-core: 2.0.4(redux@4.2.1)
dva-immer: 1.0.2(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
@@ -12726,7 +12705,7 @@ snapshots:
- react-native
- supports-color
'@umijs/plugins@4.6.51(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
'@umijs/plugins@4.6.51(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@ahooksjs/use-request': 2.8.15(react@18.3.1)
'@ant-design/antd-theme-variable': 1.0.0
@@ -12741,7 +12720,7 @@ snapshots:
antd-dayjs-webpack-plugin: 1.0.6(dayjs@1.11.20)
axios: 0.27.2
babel-plugin-import: 1.13.8
babel-plugin-styled-components: 2.1.4(@babel/core@7.23.6)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
babel-plugin-styled-components: 2.1.4(@babel/core@7.29.0)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
dayjs: 1.11.20
dva-core: 2.0.4(redux@4.2.1)
dva-immer: 1.0.2(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
@@ -12771,7 +12750,7 @@ snapshots:
- react-native
- supports-color
'@umijs/preset-umi@4.6.51(@types/node@25.6.2)(@types/react@18.3.28)(lightningcss@1.22.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))':
'@umijs/preset-umi@4.6.51(@types/node@25.6.2)(@types/react@18.3.28)(lightningcss@1.22.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))':
dependencies:
'@iconify/utils': 2.1.1
'@stagewise/toolbar': 0.6.2
@@ -12781,8 +12760,8 @@ snapshots:
'@umijs/bundler-esbuild': 4.6.51
'@umijs/bundler-mako': 0.11.10(postcss@8.5.14)(sass@1.54.0)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/bundler-utils': 4.6.51
'@umijs/bundler-utoopack': 4.6.51(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/bundler-vite': 4.6.51(@types/node@25.6.2)(lightningcss@1.22.1)(postcss@8.5.14)(rollup@3.30.0)(sass@1.54.0)(terser@5.48.0)
'@umijs/bundler-utoopack': 4.6.51(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/bundler-vite': 4.6.51(@types/node@25.6.2)(lightningcss@1.22.1)(postcss@8.5.14)(rollup@3.30.0)(sass@1.54.0)(terser@5.47.1)
'@umijs/bundler-webpack': 4.6.51(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/core': 4.6.51
'@umijs/did-you-know': 1.0.4
@@ -12864,13 +12843,13 @@ snapshots:
react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react-router-dom: 6.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/request-record@1.1.4(umi@4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))':
'@umijs/request-record@1.1.4(umi@4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))':
dependencies:
chokidar: 3.6.0
express: 4.22.1
lodash: 4.18.1
prettier: 2.8.8
umi: 4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
umi: 4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
transitivePeerDependencies:
- supports-color
@@ -12886,13 +12865,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@umijs/test@4.6.51(@babel/core@7.23.6)':
'@umijs/test@4.6.51(@babel/core@7.29.0)':
dependencies:
'@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.6)
'@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.29.0)
'@jest/types': 27.5.1
'@umijs/bundler-utils': 4.6.51
'@umijs/utils': 4.6.51
babel-jest: 29.7.0(@babel/core@7.23.6)
babel-jest: 29.7.0(@babel/core@7.29.0)
esbuild: 0.21.4
identity-obj-proxy: 3.0.0
isomorphic-unfetch: 4.0.2
@@ -13012,7 +12991,7 @@ snapshots:
'@utoo/pack-win32-x64-msvc@1.4.3':
optional: true
'@utoo/pack@1.4.3(less-loader@11.1.0(less@4.1.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(less@4.1.3)(postcss@8.5.14)(resolve-url-loader@5.0.0)(sass-loader@13.2.0(sass@1.54.0)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))':
'@utoo/pack@1.4.3(less-loader@11.1.0(less@4.1.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(less@4.1.3)(postcss@8.5.14)(resolve-url-loader@5.0.0)(sass-loader@13.2.0(sass@1.54.0)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))':
dependencies:
'@babel/code-frame': 7.22.5
'@hono/node-server': 1.19.14(hono@4.12.18)
@@ -13033,7 +13012,7 @@ snapshots:
sass-loader: 13.2.0(sass@1.54.0)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
semver: 7.8.0
send: 0.17.1
styled-jsx: 5.1.7(@babel/core@7.23.6)(react@18.3.1)
styled-jsx: 5.1.7(@babel/core@7.29.0)(react@18.3.1)
ws: 8.20.0
optionalDependencies:
'@utoo/pack-darwin-arm64': 1.4.3
@@ -13048,13 +13027,13 @@ snapshots:
- supports-color
- utf-8-validate
'@vitejs/plugin-react@4.0.0(vite@4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.48.0))':
'@vitejs/plugin-react@4.0.0(vite@4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.47.1))':
dependencies:
'@babel/core': 7.29.0
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
'@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0)
react-refresh: 0.14.2
vite: 4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.48.0)
vite: 4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.47.1)
transitivePeerDependencies:
- supports-color
@@ -13549,13 +13528,13 @@ snapshots:
transitivePeerDependencies:
- debug
babel-jest@29.7.0(@babel/core@7.23.6):
babel-jest@29.7.0(@babel/core@7.29.0):
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@jest/transform': 29.7.0
'@types/babel__core': 7.20.5
babel-plugin-istanbul: 6.1.1
babel-preset-jest: 29.6.3(@babel/core@7.23.6)
babel-preset-jest: 29.6.3(@babel/core@7.29.0)
chalk: 4.1.2
graceful-fs: 4.2.11
slash: 3.0.0
@@ -13595,9 +13574,9 @@ snapshots:
cosmiconfig: 7.1.0
resolve: 1.22.12
babel-plugin-named-asset-import@0.3.8(@babel/core@7.23.6):
babel-plugin-named-asset-import@0.3.8(@babel/core@7.29.0):
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
babel-plugin-react-compiler@0.0.0-experimental-c23de8d-20240515:
dependencies:
@@ -13609,11 +13588,11 @@ snapshots:
zod: 3.25.76
zod-validation-error: 2.1.0(zod@3.25.76)
babel-plugin-styled-components@2.1.4(@babel/core@7.23.6)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
babel-plugin-styled-components@2.1.4(@babel/core@7.29.0)(styled-components@6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)):
dependencies:
'@babel/helper-annotate-as-pure': 7.27.3
'@babel/helper-module-imports': 7.28.6
'@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.23.6)
'@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0)
lodash: 4.18.1
picomatch: 2.3.2
styled-components: 6.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -13621,30 +13600,30 @@ snapshots:
- '@babel/core'
- supports-color
babel-preset-current-node-syntax@1.2.0(@babel/core@7.23.6):
babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0):
dependencies:
'@babel/core': 7.23.6
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.6)
'@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.6)
'@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.6)
'@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.6)
'@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.23.6)
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.6)
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.6)
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.6)
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.6)
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.6)
'@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.6)
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.6)
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.6)
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.6)
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.6)
'@babel/core': 7.29.0
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0)
'@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0)
'@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0)
'@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0)
'@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0)
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0)
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0)
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0)
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0)
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0)
'@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0)
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0)
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0)
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0)
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0)
babel-preset-jest@29.6.3(@babel/core@7.23.6):
babel-preset-jest@29.6.3(@babel/core@7.29.0):
dependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
babel-plugin-jest-hoist: 29.6.3
babel-preset-current-node-syntax: 1.2.0(@babel/core@7.23.6)
babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0)
babel-runtime-jsx-plus@0.1.5: {}
@@ -14548,6 +14527,8 @@ snapshots:
no-case: 3.0.4
tslib: 2.8.1
driver.js@1.4.0: {}
duck@0.1.12:
dependencies:
underscore: 1.13.8
@@ -14664,11 +14645,6 @@ snapshots:
graceful-fs: 4.2.11
tapable: 2.3.3
enhanced-resolve@5.22.0:
dependencies:
graceful-fs: 4.2.11
tapable: 2.3.3
enhanced-resolve@5.9.3:
dependencies:
graceful-fs: 4.2.11
@@ -16382,7 +16358,7 @@ snapshots:
jest-worker@27.5.1:
dependencies:
'@types/node': 25.9.1
'@types/node': 25.6.2
merge-stream: 2.0.0
supports-color: 8.1.1
@@ -16402,9 +16378,9 @@ snapshots:
jiti@2.7.0: {}
jotai@2.20.0(@babel/core@7.23.6)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1):
jotai@2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@18.3.28)(react@18.3.1):
optionalDependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
'@babel/template': 7.28.6
'@types/react': 18.3.28
react: 18.3.1
@@ -19797,12 +19773,12 @@ snapshots:
css-to-react-native: 3.2.0
react-dom: 18.3.1(react@18.3.1)
styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1):
styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1):
dependencies:
client-only: 0.0.1
react: 18.3.1
optionalDependencies:
'@babel/core': 7.23.6
'@babel/core': 7.29.0
stylelint-config-recommended@7.0.0(stylelint@14.8.2):
dependencies:
@@ -19952,7 +19928,7 @@ snapshots:
'@jridgewell/trace-mapping': 0.3.31
jest-worker: 27.5.1
schema-utils: 4.3.3
terser: 5.48.0
terser: 5.47.1
webpack: 5.106.2(lightningcss@1.22.1)(postcss@8.5.14)
optionalDependencies:
lightningcss: 1.22.1
@@ -19965,13 +19941,6 @@ snapshots:
commander: 2.20.3
source-map-support: 0.5.21
terser@5.48.0:
dependencies:
'@jridgewell/source-map': 0.3.11
acorn: 8.16.0
commander: 2.20.3
source-map-support: 0.5.21
test-exclude@6.0.0:
dependencies:
'@istanbuljs/schema': 0.1.6
@@ -20156,12 +20125,12 @@ snapshots:
ua-parser-js@0.7.41: {}
umi-presets-pro@2.0.3(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(chokidar@3.6.0)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(umi@4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))):
umi-presets-pro@2.0.3(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(chokidar@3.6.0)(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(encoding@0.1.13)(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3)(umi@4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))):
dependencies:
'@alita/plugins': 3.5.5(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@alita/plugins': 3.5.5(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/max-plugin-openapi': 2.0.3(chokidar@3.6.0)(encoding@0.1.13)(typescript@5.9.3)
'@umijs/plugins': 4.6.51(@babel/core@7.23.6)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/request-record': 1.1.4(umi@4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))
'@umijs/plugins': 4.6.51(@babel/core@7.29.0)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(antd@6.3.7(date-fns@2.30.0)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(dva@2.5.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(rc-field-form@2.7.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/request-record': 1.1.4(umi@4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)))
swagger-ui-dist: 4.19.1
transitivePeerDependencies:
- '@babel/core'
@@ -20185,17 +20154,17 @@ snapshots:
isomorphic-fetch: 2.2.1
qs: 6.15.1
umi@4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@8.35.0)(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)):
umi@4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@8.35.0)(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)):
dependencies:
'@babel/runtime': 7.23.6
'@umijs/bundler-utils': 4.6.51
'@umijs/bundler-webpack': 4.6.51(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/core': 4.6.51
'@umijs/lint': 4.6.51(eslint@8.35.0)(stylelint@14.8.2)(typescript@5.9.3)
'@umijs/preset-umi': 4.6.51(@types/node@25.6.2)(@types/react@18.3.28)(lightningcss@1.22.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/preset-umi': 4.6.51(@types/node@25.6.2)(@types/react@18.3.28)(lightningcss@1.22.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/renderer-react': 4.6.51(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/server': 4.6.51
'@umijs/test': 4.6.51(@babel/core@7.23.6)
'@umijs/test': 4.6.51(@babel/core@7.29.0)
'@umijs/utils': 4.6.51
prettier-plugin-organize-imports: 3.2.4(prettier@3.8.3)(typescript@5.9.3)
prettier-plugin-packagejson: 2.4.3(prettier@3.8.3)
@@ -20239,17 +20208,17 @@ snapshots:
- webpack-hot-middleware
- webpack-plugin-serve
umi@4.6.51(@babel/core@7.23.6)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(stylelint@14.8.2)(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)):
umi@4.6.51(@babel/core@7.29.0)(@types/node@25.6.2)(@types/react@18.3.28)(eslint@9.39.4(jiti@2.7.0))(lightningcss@1.22.1)(prettier@3.8.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(stylelint@14.8.2)(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14)):
dependencies:
'@babel/runtime': 7.23.6
'@umijs/bundler-utils': 4.6.51
'@umijs/bundler-webpack': 4.6.51(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/core': 4.6.51
'@umijs/lint': 4.6.51(eslint@9.39.4(jiti@2.7.0))(stylelint@14.8.2)(typescript@5.9.3)
'@umijs/preset-umi': 4.6.51(@types/node@25.6.2)(@types/react@18.3.28)(lightningcss@1.22.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.23.6)(react@18.3.1))(terser@5.48.0)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/preset-umi': 4.6.51(@types/node@25.6.2)(@types/react@18.3.28)(lightningcss@1.22.1)(rollup@3.30.0)(sass@1.54.0)(styled-jsx@5.1.7(@babel/core@7.29.0)(react@18.3.1))(terser@5.47.1)(type-fest@0.20.2)(typescript@5.9.3)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
'@umijs/renderer-react': 4.6.51(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@umijs/server': 4.6.51
'@umijs/test': 4.6.51(@babel/core@7.23.6)
'@umijs/test': 4.6.51(@babel/core@7.29.0)
'@umijs/utils': 4.6.51
prettier-plugin-organize-imports: 3.2.4(prettier@3.8.3)(typescript@5.9.3)
prettier-plugin-packagejson: 2.4.3(prettier@3.8.3)
@@ -20304,8 +20273,6 @@ snapshots:
undici-types@7.19.2: {}
undici-types@7.24.6: {}
unfetch@5.0.0: {}
unified@11.0.5:
@@ -20490,7 +20457,7 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.3
vite@4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.48.0):
vite@4.5.2(@types/node@25.6.2)(less@4.1.3)(lightningcss@1.22.1)(sass@1.54.0)(terser@5.47.1):
dependencies:
esbuild: 0.18.20
postcss: 8.5.14
@@ -20501,7 +20468,7 @@ snapshots:
less: 4.1.3
lightningcss: 1.22.1
sass: 1.54.0
terser: 5.48.0
terser: 5.47.1
vm-browserify@1.1.2: {}
@@ -20563,7 +20530,7 @@ snapshots:
- bufferutil
- utf-8-validate
webpack-sources@3.5.0: {}
webpack-sources@3.4.1: {}
webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14):
dependencies:
@@ -20577,7 +20544,7 @@ snapshots:
acorn-import-phases: 1.0.4(acorn@8.16.0)
browserslist: 4.28.2
chrome-trace-event: 1.0.4
enhanced-resolve: 5.22.0
enhanced-resolve: 5.21.2
es-module-lexer: 2.1.0
eslint-scope: 5.1.1
events: 3.3.0
@@ -20590,7 +20557,7 @@ snapshots:
tapable: 2.3.3
terser-webpack-plugin: 5.6.0(lightningcss@1.22.1)(postcss@8.5.14)(webpack@5.106.2(lightningcss@1.22.1)(postcss@8.5.14))
watchpack: 2.5.1
webpack-sources: 3.5.0
webpack-sources: 3.4.1
transitivePeerDependencies:
- '@minify-html/node'
- '@swc/core'
Binary file not shown.

Before

Width:  |  Height:  |  Size: 587 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 587 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 3.0 KiB

-102
View File
@@ -1,102 +0,0 @@
#!/bin/bash
#
# rebrand: 把面向用户的品牌标识从 GPUStack 批量替换为 ZStack AIOS(或自定义品牌)。
#
# 设计目标:上游每次更新后,在新的 v<version>-lofyer 分支上跑一次即可重新应用品牌定制。
#
# 只替换「独立的品牌词」FROM,并刻意跳过所有功能性引用:
# - 小写 `gpustack` —— npm 包名 (@gpustack/core-ui)、URL、路径、k8s 命名空间、author(大小写敏感,天然不匹配)
# - 全大写 `GPUSTACK` —— 常量/环境变量/全局 (GPUSTACK_API_BASE_URL, __GPUSTACK_*__, GPUSTACK_UI_*)(大小写敏感,不匹配)
# - 代码标识符 —— getGPUStackPlugin / GPUStackVersionAtom / GPUStackPluginManager / GPUStackLogo 等
# (FROM 紧邻字母时视为标识符的一部分,跳过)
# - HTTP 头 X-GPUStack-* —— 后端契约 (如 X-GPUStack-Model),跳过
#
# 匹配规则:FROM 前后都不是字母(独立单词),且不是 `X-` 前缀的头名。
#
# 环境变量:
# FROM 源品牌词(默认 GPUStack
# TO 目标品牌词(默认 ZStack AIOS
# DRY_RUN 设为 1 时只预览将改动的行,不写文件
#
set -e
FROM="${FROM:-GPUStack}"
TO="${TO:-ZStack AIOS}"
DRY_RUN="${DRY_RUN:-0}"
log() { echo -e "\033[1;34m[rebrand]\033[0m $*"; }
# 大小写敏感、单词边界、排除 X- 头前缀的 Perl 正则。
# (?<![A-Za-z]) 前面不是字母 (?<!X-) 不是 X- 头 (?![A-Za-z]) 后面不是字母
# FROM 为纯字母品牌词(无正则元字符),故直接拼接,不用 \Q\E
# —— \Q\E 在「经变量插值进正则」时不会被求值,反而会破坏匹配。
PATTERN="(?<![A-Za-z])(?<!X-)${FROM}(?![A-Za-z])"
# 行级排除:某些 FROM 出现在「与后端契约绑定的字符串」里,改了会破坏运行时逻辑,
# 即使是独立单词也必须整行跳过。命中下列任一正则的行不替换。
# 已知例外:
# - llmodels/hooks/index.ts 用 startsWith() 比对后端返回的英文兼容性消息
# "... does not exist on the GPUStack server ..."),后端仍发 GPUStack,前端不能改。
SKIP_LINE_PATTERNS=(
'does not exist on the .*server. It'"'"'s recommended'
)
skip_line() {
local line="$1" pat
for pat in "${SKIP_LINE_PATTERNS[@]}"; do
if echo "$line" | grep -qP "$pat"; then return 0; fi
done
return 1
}
# 待处理的已跟踪文本文件(排除 lockfile 与本脚本自身)。
mapfile -t files < <(
git ls-files -- \
'*.ts' '*.tsx' '*.js' '*.jsx' '*.json' '*.less' '*.html' '*.md' \
| grep -v 'pnpm-lock.yaml'
)
log "品牌替换: '${FROM}' -> '${TO}'"
log "候选文件: ${#files[@]}"
# 把行级排除合并成一个 perl 正则,供预览与替换共用(经环境变量传入,免去转义)。
SKIP_RE=""
for pat in "${SKIP_LINE_PATTERNS[@]}"; do
SKIP_RE="${SKIP_RE:+${SKIP_RE}|}(?:${pat})"
done
export REBRAND_SKIP_RE="${SKIP_RE}"
export REBRAND_PATTERN="${PATTERN}"
export REBRAND_TO="${TO}"
# 统计命中行(预览/确认用),已扣除被行级排除的行。
log "命中行预览(最多 40 行):"
grep -rnP "${PATTERN}" "${files[@]}" 2>/dev/null \
| { [[ -n "${SKIP_RE}" ]] && grep -vP "${SKIP_RE}" || cat; } \
| head -40 || true
total=$(grep -rnP "${PATTERN}" "${files[@]}" 2>/dev/null \
| { [[ -n "${SKIP_RE}" ]] && grep -vP "${SKIP_RE}" || cat; } | wc -l)
log "命中总行数: ${total}"
if [[ -n "${SKIP_RE}" ]]; then
skipped=$(grep -rnP "${PATTERN}" "${files[@]}" 2>/dev/null | grep -cP "${SKIP_RE}" || true)
log "行级排除(后端契约,保留 ${FROM}: ${skipped} 行"
fi
if [[ "${DRY_RUN}" == "1" ]]; then
log "DRY_RUN=1:未写入任何文件。"
exit 0
fi
# 实际替换(in-place)。命中行级排除的行整行跳过。
changed=0
for f in "${files[@]}"; do
if grep -qP "${PATTERN}" "$f" 2>/dev/null; then
perl -i -pe '
my $skip = $ENV{REBRAND_SKIP_RE};
next if length($skip) && /$skip/;
s/$ENV{REBRAND_PATTERN}/$ENV{REBRAND_TO}/g;
' "$f"
changed=$((changed + 1))
fi
done
log "已修改文件数: ${changed}"
log "完成。请用 'git diff' 复核改动。"
-83
View File
@@ -1,83 +0,0 @@
#!/bin/bash
#
# sync-github: 从上游 GitHub 拉取最新源码,并全量镜像同步到 192.168.0.23 私有源。
#
# 默认行为(全量镜像 / 强制):
# 1. 确保存在 upstream remote 指向 GitHub(不存在则自动添加,URL 不一致则更新)。
# 2. 从 upstream 抓取所有分支与 tag(--prune 清理已删除的远端引用)。
# 3. 将上游每个分支强制推送到私有源同名分支(force push)。
# 4. 将上游所有 tag 强制推送到私有源。
#
# 可用环境变量:
# UPSTREAM_URL 上游 GitHub 仓库地址(默认 https://github.com/gpustack/gpustack-ui.git
# ORIGIN_REMOTE 私有源 remote 名称(默认 origin
# UPSTREAM_REMOTE 上游 remote 名称(默认 upstream
# PRUNE_BRANCHES 设为 1 时,删除私有源上「上游已不存在」的分支(真·镜像,破坏性,默认关闭)
# DRY_RUN 设为 1 时,仅打印将要执行的推送动作,不实际推送
#
set -e
UPSTREAM_URL="${UPSTREAM_URL:-https://github.com/gpustack/gpustack-ui.git}"
ORIGIN_REMOTE="${ORIGIN_REMOTE:-origin}"
UPSTREAM_REMOTE="${UPSTREAM_REMOTE:-upstream}"
PRUNE_BRANCHES="${PRUNE_BRANCHES:-0}"
DRY_RUN="${DRY_RUN:-0}"
log() { echo -e "\033[1;34m[sync-github]\033[0m $*"; }
warn() { echo -e "\033[1;33m[sync-github]\033[0m $*" >&2; }
run() {
if [[ "${DRY_RUN}" == "1" ]]; then
echo " (dry-run) git $*"
else
git "$@"
fi
}
# 1. 确保 upstream remote 指向 GitHub。
if git remote get-url "${UPSTREAM_REMOTE}" >/dev/null 2>&1; then
current_url=$(git remote get-url "${UPSTREAM_REMOTE}")
if [[ "${current_url}" != "${UPSTREAM_URL}" ]]; then
log "更新 ${UPSTREAM_REMOTE} 地址: ${current_url} -> ${UPSTREAM_URL}"
git remote set-url "${UPSTREAM_REMOTE}" "${UPSTREAM_URL}"
fi
else
log "添加 upstream remote: ${UPSTREAM_REMOTE} -> ${UPSTREAM_URL}"
git remote add "${UPSTREAM_REMOTE}" "${UPSTREAM_URL}"
fi
origin_url=$(git remote get-url "${ORIGIN_REMOTE}")
log "上游 (拉取): ${UPSTREAM_URL}"
log "私有源 (推送): ${origin_url}"
# 2. 抓取上游所有分支与 tag。
log "抓取上游分支与 tag..."
git fetch --prune --tags "${UPSTREAM_REMOTE}"
# 3. 逐个分支强制推送到私有源。
log "强制同步分支到私有源..."
upstream_branches=$(git for-each-ref --format='%(refname:strip=3)' "refs/remotes/${UPSTREAM_REMOTE}/" | grep -v '^HEAD$')
for branch in ${upstream_branches}; do
log " -> ${branch}"
run push --force "${ORIGIN_REMOTE}" \
"refs/remotes/${UPSTREAM_REMOTE}/${branch}:refs/heads/${branch}"
done
# 4. 强制同步所有 tag。
log "强制同步 tag 到私有源..."
run push --force --tags "${ORIGIN_REMOTE}"
# 5. 可选:删除私有源上、上游已不存在的分支(真·镜像)。
if [[ "${PRUNE_BRANCHES}" == "1" ]]; then
warn "PRUNE_BRANCHES=1:将删除私有源上上游已不存在的分支"
origin_branches=$(git ls-remote --heads "${ORIGIN_REMOTE}" | sed 's@.*refs/heads/@@')
for branch in ${origin_branches}; do
if ! echo "${upstream_branches}" | grep -qx "${branch}"; then
warn " 删除私有源分支: ${branch}"
run push "${ORIGIN_REMOTE}" --delete "${branch}"
fi
done
fi
log "同步完成。"
+1 -22
View File
@@ -1,10 +1,6 @@
import { applyAccessExtensions } from './access.extensions';
export default (initialState: {
currentUser?: Global.UserInfo;
hasKubernetesCluster?: boolean;
hasResourceEvents?: boolean;
}) => {
export default (initialState: { currentUser?: Global.UserInfo }) => {
const isPlatformAdmin = !!(
initialState &&
initialState.currentUser &&
@@ -15,16 +11,6 @@ export default (initialState: {
initialState.currentUser &&
!initialState.currentUser.is_admin
);
// GPU Service is Kubernetes-only. We only gate visibility down when
// the probe in `getInitialState` came back with a definitive answer;
// `undefined` (probe failed / not yet ready) collapses to the
// role-based default so a transient network blip can't lock anyone
// out of the menu.
const hasKubernetesCluster = initialState?.hasKubernetesCluster;
// Having run GPU/CPU instances or storage (any resource_events) also unlocks
// GPU Service / the full Usage page — a user who used it keeps seeing it even
// without a current cluster. MaaS-only users (no cluster, no events) don't.
const hasResourceEvents = !!initialState?.hasResourceEvents;
// Predicate roles, top-down by strictness:
// * `canSeeAdmin` — strictly platform admin (`users.is_admin`).
@@ -32,11 +18,6 @@ export default (initialState: {
// * `canSeeOrgAdmin` — admin-style menus that work cross-org
// (Dashboard, Resources, Models, Cluster Management). Defaults
// to platform admin; extensions widen to include org admins.
// * `canSeeGpuService` — GPU Service menu. Anyone allowed to
// manage clusters (admins, Org owners) sees it; non-admins fall
// through to "show only if a Kubernetes cluster is actually
// reachable" so Org members without scheduling access don't see
// a dead-end menu item.
// * `canManageCurrentOrg` — pages that only make sense inside a
// specific org context (member / group management). Defaults to
// `false`; extensions widen when both an org is selected AND
@@ -46,8 +27,6 @@ export default (initialState: {
return applyAccessExtensions({
canSeeAdmin: isPlatformAdmin,
canSeeOrgAdmin: isPlatformAdmin,
canSeeGpuService:
isPlatformAdmin || hasKubernetesCluster !== false || hasResourceEvents,
canManageCurrentOrg: false,
canSeeUser,
canDelete: true,
+3 -55
View File
@@ -1,9 +1,8 @@
import { userSettingsHelperAtom } from '@/atoms/settings';
import { GPUStackVersionAtom, UpdateCheckAtom, userAtom } from '@/atoms/user';
import { GPUStackVersionAtom, UpdateCheckAtom } from '@/atoms/user';
import { setAtomStorage } from '@/atoms/utils';
import { DEFAULT_ENTER_PAGE, GPUSTACK_API_BASE_URL } from '@/config/settings';
import { COLOR_PRIMARY } from '@/config/theme/constants';
import { getGPUStackPlugin } from '@/plugins';
import { enterprisePluginReady } from '@/plugins/enterprise-ready';
import { GPUStackPluginManager } from '@/plugins/manager';
import { requestConfig } from '@/request-config';
@@ -14,11 +13,6 @@ import {
} from '@/services/profile/apis';
import { fetchSystemConfig } from '@/services/system/query-system-config';
import { isOnline } from '@/utils';
import {
markInitialStateProbed,
probeAccessFlags
} from '@/utils/access-probes';
import { installTenantFetch } from '@/utils/install-fetch';
import {
IS_FIRST_LOGIN,
readState,
@@ -28,8 +22,6 @@ import '@gpustack/core-ui/style.css';
import { RequestConfig, history, request as umiRequest } from '@umijs/max';
import { message } from 'antd';
installTenantFetch();
// only for the first login and access from http://localhost
const checkDefaultPage = async (userInfo: any) => {
@@ -47,8 +39,6 @@ export async function getInitialState(): Promise<{
fetchUserInfo: () => Promise<Global.UserInfo>;
currentUser?: Global.UserInfo;
pluginData?: Record<string, any>;
hasKubernetesCluster?: boolean;
hasResourceEvents?: boolean;
}> {
const { location } = history;
@@ -93,36 +83,6 @@ export async function getInitialState(): Promise<{
getUpdateCheck();
fetchSystemConfig();
}
// Only commit a substantive user object. A truthy-but-empty
// `data` (e.g. server responded 200 with an empty body) would
// otherwise look like "logged in" to every `currentUser`
// reader and the access seam — break out instead and let the
// caller treat the request as failed.
if (data && typeof data === 'object' && Object.keys(data).length > 0) {
// Commit the identity to atom storage (and so to localStorage)
// before returning. The access function — memoized on
// `initialState` and run once per commit — reads identity from
// localStorage; without this preemptive write the predicate
// sees the prior session's identity on its first evaluation
// after login, and stays stale until the next identity change
// (which usually doesn't come without a manual refresh).
try {
setAtomStorage(userAtom, data);
} catch (err) {
console.error('userAtom commit error:', err);
}
// Fire `onUserFetched` so plugins maintaining identity-scoped
// caches can seed them under the new identity before any
// caller commits this user to `initialState`. Errors here are
// swallowed and logged — fetchUserInfo must still return.
try {
await getGPUStackPlugin()?.login?.onUserFetched?.(data, {
request: umiRequest
});
} catch (err) {
console.error('onUserFetched plugin hook error:', err);
}
}
return data;
} catch (error: any) {
const data = error?.response?.data;
@@ -162,24 +122,12 @@ export async function getInitialState(): Promise<{
getAppVersionInfo();
if (![DEFAULT_ENTER_PAGE.login].includes(location.pathname)) {
const [userInfo, accessFlags] = await Promise.all([
fetchUserInfo(),
probeAccessFlags()
]);
// Record that the probes ran for an authenticated user this page load
// (the refresh path) so the layout doesn't re-probe. A failed
// fetch (empty user — e.g. unauthenticated deep link that bounces to
// login) is NOT marked: the user will log in via SPA afterwards and
// the layout becomes responsible for probing.
if (userInfo?.username) {
markInitialStateProbed();
}
const userInfo = await fetchUserInfo();
checkDefaultPage(userInfo);
return {
fetchUserInfo,
currentUser: userInfo,
pluginData,
...accessFlags
pluginData
};
}
return {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 286 64"><g><g><defs><path id="SVGID_1_" d="M47.5 17.6L25 4.8v52.6l9-5.2V37.4l6.8 3.9-.1-10.1-6.7-3.9v-5.9l13.5 7.9z"/></defs><clipPath id="SVGID_2_"><use xlink:href="#SVGID_1_" overflow="visible"/></clipPath><g clip-path="url(#SVGID_2_)"><linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-1.6" y1="335.05" x2="53.6" y2="335.05" gradientTransform="translate(0 -304)"><stop offset="0" stop-color="#ff6f00"/><stop offset="1" stop-color="#ffa800"/></linearGradient><path d="M-1.6 4.6h55.2v52.9H-1.6V4.6z" fill="url(#SVGID_3_)"/></g></g></g><g><g><defs><path id="SVGID_4_" d="M.5 17.6L23 4.8v52.6l-9-5.2V21.4L.5 29.3z"/></defs><clipPath id="SVGID_5_"><use xlink:href="#SVGID_4_" overflow="visible"/></clipPath><g clip-path="url(#SVGID_5_)"><linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="-1.9" y1="335.05" x2="53.3" y2="335.05" gradientTransform="translate(0 -304)"><stop offset="0" stop-color="#ff6f00"/><stop offset="1" stop-color="#ffa800"/></linearGradient><path d="M-1.9 4.6h55.2v52.9H-1.9V4.6z" fill="url(#SVGID_6_)"/></g></g></g><path style="fill:#425066" d="M88.2 21.1h-10v27.7h-5.6V21.1h-10v-4.5h25.6v4.5z"/><path style="fill:#425066" d="M94.9 49.2c-3.4 0-6.2-1.1-8.3-3.2-2.1-2.1-3.2-5-3.2-8.6v-.7c0-2.2.4-4.4 1.4-6.4.9-1.8 2.2-3.3 3.9-4.4 1.7-1.1 3.6-1.6 5.6-1.6 3.3 0 5.8 1 7.6 3.1s2.7 5 2.7 8.8v2.2H88.9c.1 1.8.8 3.4 2 4.7 1.2 1.2 2.7 1.8 4.4 1.7 2.4.1 4.6-1.1 6-3l2.9 2.8c-1 1.4-2.3 2.6-3.8 3.3-1.8 1-3.6 1.4-5.5 1.3zm-.6-20.5c-1.4-.1-2.7.5-3.6 1.5-1 1.2-1.6 2.7-1.7 4.3h10.3v-.4c-.1-1.8-.6-3.2-1.4-4.1-1-.8-2.3-1.4-3.6-1.3zm19.4-3.9l.2 2.8c1.7-2.1 4.3-3.3 7-3.2 5 0 7.5 2.9 7.6 8.6v15.8h-5.4V33.3c0-1.5-.3-2.6-1-3.4-.7-.7-1.7-1.1-3.2-1.1-2.1-.1-4 1.1-4.9 2.9v17h-5.4v-24l5.1.1zm32.2 17.5c0-.9-.4-1.7-1.2-2.2-1.2-.7-2.6-1.1-3.9-1.3-1.6-.3-3.1-.8-4.6-1.5-2.7-1.3-4-3.2-4-5.6 0-2 1-4 2.6-5.2 1.7-1.4 4-2.1 6.6-2.1 2.9 0 5.2.7 6.9 2.1 1.7 1.3 2.7 3.4 2.6 5.5h-5.4c0-1-.4-1.9-1.2-2.6-.9-.7-1.9-1.1-3.1-1-1 0-2 .2-2.9.8-.7.5-1.1 1.3-1.1 2.2 0 .8.4 1.5 1 1.9.7.5 2.1.9 4.2 1.4 1.7.3 3.4.9 5 1.7 1.1.5 2 1.3 2.7 2.3.6 1 .9 2.1.9 3.3 0 2.1-1 4-2.7 5.2-1.8 1.3-4.1 2-7 2-1.8 0-3.6-.3-5.2-1.1-1.4-.6-2.7-1.6-3.6-2.9-.8-1.2-1.3-2.6-1.3-4h5.2c0 1.1.5 2.2 1.4 2.9 1 .7 2.3 1.1 3.5 1 1.4 0 2.5-.3 3.2-.8 1-.4 1.4-1.2 1.4-2zm8.1-5.7c0-2.2.4-4.4 1.4-6.3.9-1.8 2.2-3.3 3.9-4.3 1.8-1 3.8-1.6 5.8-1.5 3.2 0 5.9 1 7.9 3.1s3.1 4.8 3.3 8.3v1.3c0 2.2-.4 4.3-1.4 6.3-.8 1.8-2.2 3.3-3.9 4.3-1.8 1-3.8 1.6-5.9 1.5-3.4 0-6.1-1.1-8.1-3.4-2-2.2-3-5.2-3.1-9l.1-.3zm5.3.5c0 2.5.5 4.4 1.5 5.8 1.8 2.3 5.1 2.8 7.5 1 .4-.3.7-.6 1-1 1-1.4 1.5-3.5 1.5-6.2 0-2.4-.5-4.3-1.6-5.8-1.7-2.3-5-2.8-7.4-1.1-.4.3-.8.7-1.1 1-.8 1.4-1.4 3.5-1.4 6.3zm33.1-7.3c-.7-.1-1.5-.2-2.2-.2-2.5 0-4.1.9-5 2.8v16.4h-5.4v-24h5.1l.1 2.7c1.3-2.1 3.1-3.1 5.4-3.1.6 0 1.3.1 1.9.3l.1 5.1zm22.5 5.3h-13v13.7h-5.6V16.6h20.5v4.5h-14.9v9.6h13v4.4zm10.7 13.7h-5.4V16.5h5.4v32.3zm3.9-12.2c0-2.2.4-4.4 1.4-6.3.9-1.8 2.2-3.3 3.9-4.3 1.8-1 3.8-1.6 5.8-1.5 3.2 0 5.9 1 7.9 3.1s3.1 4.8 3.3 8.3v1.3c0 2.2-.4 4.3-1.3 6.3-.8 1.8-2.2 3.3-3.9 4.3-1.8 1-3.8 1.6-5.9 1.5-3.4 0-6.1-1.1-8.1-3.4-2-2.2-3.1-5.2-3.1-9v-.3zm5.4.5c0 2.5.5 4.4 1.5 5.8 1 1.4 2.6 2.2 4.3 2.1 1.7.1 3.3-.7 4.2-2.1 1-1.4 1.5-3.5 1.5-6.2 0-2.4-.5-4.3-1.6-5.8-1.7-2.3-5-2.8-7.4-1.1-.4.3-.8.7-1.1 1-.9 1.4-1.4 3.5-1.4 6.3zm41.2 4.3l3.8-16.5h5.2l-6.5 24h-4.4l-5.1-16.5-5.1 16.5h-4.4l-6.6-24h5.3l3.9 16.4 4.9-16.4h4.1l4.9 16.5z"/></svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

-24
View File
@@ -1,24 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<defs>
<!-- 顶面填充(亮面,高透明度) -->
<linearGradient id="cube-top-grad" x1="12" y1="2" x2="12" y2="12" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#f759ab" stop-opacity="0.18"/>
<stop offset="100%" stop-color="#c41d7f" stop-opacity="0.1"/>
</linearGradient>
<!-- 左侧面填充(暗面,低透明度) -->
<linearGradient id="cube-left-grad" x1="2" y1="7" x2="12" y2="17" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#c41d7f" stop-opacity="0.12"/>
<stop offset="100%" stop-color="#c41d7f" stop-opacity="0.04"/>
</linearGradient>
<linearGradient id="cube-stroke-grad" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#f759ab"/>
<stop offset="100%" stop-color="#c41d7f"/>
</linearGradient>
</defs>
<!-- 顶面填充 -->
<polygon points="12,2 21.5,6.7 12,11.5 2.5,6.7" fill="url(#cube-top-grad)" />
<!-- 左侧面填充 -->
<polygon points="2.5,6.7 12,11.5 12,21.3 2.5,16.5" fill="url(#cube-left-grad)" />
<!-- 立方体全纯线外骨架(细化为圆角衔接) -->
<path d="M12 2L2.5 6.7M12 2l9.5 4.7M21.5 6.7L12 11.5M2.5 6.7L12 11.5M2.5 6.7v9.8l9.5 4.8M21.5 6.7v9.8l-9.5 4.8M12 11.5v9.8" stroke="url(#cube-stroke-grad)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

-22
View File
@@ -1,22 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<defs>
<!-- 1. 定义专属微通透渐变填充 -->
<linearGradient id="img-fill-grad" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#d46b08" stop-opacity="0.12"/>
<stop offset="100%" stop-color="#d46b08" stop-opacity="0.04"/>
</linearGradient>
<!-- 2. 定义边框高精度渐变(亮橙到深橙,拉开层次) -->
<linearGradient id="img-stroke-grad" x1="4" y1="4" x2="20" y2="20" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#fa8c16"/>
<stop offset="100%" stop-color="#d46b08"/>
</linearGradient>
</defs>
<!-- 3. 精装底色充填层 -->
<rect x="3" y="3" width="18" height="18" rx="4" fill="url(#img-fill-grad)" />
<!-- 4. 高级柔和微圆角边框层 -->
<rect x="3" y="3" width="18" height="18" rx="4" stroke="url(#img-stroke-grad)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<!-- 内部几何现代山脉线条 -->
<path d="M3 16l4-4a2 2 0 0 1 2.8 0l5.2 5.2M13 15l2.5-2.5a2 2 0 0 1 2.8 0l2.7 2.7" stroke="url(#img-stroke-grad)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<!-- 标志性通透小钻石 -->
<rect x="14" y="6" width="4" height="4" rx="1.5" transform="rotate(45 16 8)" fill="#fa8c16" fill-opacity="0.3" stroke="url(#img-stroke-grad)" stroke-width="1"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

-17
View File
@@ -1,17 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<defs>
<linearGradient id="chat-fill-grad" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#389e0d" stop-opacity="0.1"/>
<stop offset="100%" stop-color="#389e0d" stop-opacity="0.02"/>
</linearGradient>
<linearGradient id="chat-stroke-grad" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#73d13d"/>
<stop offset="100%" stop-color="#389e0d"/>
</linearGradient>
</defs>
<!-- 主现代对话框体(全部改为圆润R角,精装填充) -->
<path d="M18 4H6a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h7.5l3.5 3.5a1 1 0 0 0 1.5-.5V17a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3z" fill="url(#chat-fill-grad)" stroke="url(#chat-stroke-grad)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<!-- 内部通透对话线条(细化为圆角代码采样块感) -->
<rect x="7" y="8" width="8" height="1.5" rx="0.75" fill="#73d13d" fill-opacity="0.3"/>
<rect x="7" y="11.5" width="10" height="1.5" rx="0.75" fill="#73d13d" fill-opacity="0.2"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

-19
View File
@@ -1,19 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<defs>
<linearGradient id="rank-fill-grad" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#08979c" stop-opacity="0.1"/>
<stop offset="100%" stop-color="#08979c" stop-opacity="0.01"/>
</linearGradient>
<linearGradient id="rank-stroke-grad" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#36cfc9"/>
<stop offset="100%" stop-color="#08979c"/>
</linearGradient>
</defs>
<!-- 数据权重条(全部改为高级圆角) -->
<rect x="11" y="4" width="10" height="2.5" rx="1.25" fill="#36cfc9" fill-opacity="0.1" stroke="url(#rank-stroke-grad)" stroke-width="1.5"/>
<rect x="11" y="9" width="7.5" height="2.5" rx="1.25" fill="#36cfc9" fill-opacity="0.05" stroke="url(#rank-stroke-grad)" stroke-width="1.5"/>
<rect x="11" y="14" width="5" height="2.5" rx="1.25" stroke="url(#rank-stroke-grad)" stroke-width="1.5"/>
<!-- 基准线与立体双向指引箭头(优化为圆角) -->
<path d="M3 17l3 3 3-3M6 4v16" stroke="url(#rank-stroke-grad)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.5 5.5L6 4l1.5 1.5" stroke="url(#rank-stroke-grad)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 801 B

-18
View File
@@ -1,18 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<defs>
<linearGradient id="stt-fill-grad" x1="12" y1="3" x2="12" y2="14" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#40a9ff" stop-opacity="0.2"/>
<stop offset="100%" stop-color="#1677ff" stop-opacity="0.05"/>
</linearGradient>
<linearGradient id="stt-stroke-grad" x1="12" y1="3" x2="12" y2="21" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#40a9ff"/>
<stop offset="100%" stop-color="#1677ff"/>
</linearGradient>
</defs>
<!-- 麦克风核心体:精装通透填充 -->
<rect x="8.5" y="3" width="7" height="11" rx="3.5" fill="url(#stt-fill-grad)" stroke="url(#stt-stroke-grad)" stroke-width="1.8" />
<!-- 内部音膜立体结构线(细化为点状) -->
<line x1="10" y1="8" x2="14" y2="8" stroke="url(#stt-stroke-grad)" stroke-width="1" stroke-dasharray="1 2"/>
<!-- 悬挂外托架与底座(全部改为高级圆角) -->
<path d="M5 10a7 7 0 0 0 14 0M12 17v4M8 21h8" stroke="url(#stt-stroke-grad)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

-23
View File
@@ -1,23 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<defs>
<!-- 1. 核心高通透深蓝渐变充填 -->
<linearGradient id="tts-v2-fill" x1="12" y1="2" x2="12" y2="22" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#2f54eb" stop-opacity="0.15"/>
<stop offset="100%" stop-color="#1d39c4" stop-opacity="0.03"/>
</linearGradient>
<!-- 2. 精准调校的专属蓝色渐变边框 -->
<linearGradient id="tts-v2-stroke" x1="4" y1="4" x2="20" y2="20" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#2f54eb"/>
<stop offset="100%" stop-color="#1d39c4"/>
</linearGradient>
</defs>
<!-- 左侧:低频辅助声波(大间距,带现代圆角) -->
<rect x="4" y="8" width="2.2" height="8" rx="1.1" stroke="url(#tts-v2-stroke)" stroke-width="1.8" stroke-linecap="round"/>
<!-- 中央:核心高频声波主体(拉大宽度,注入通透水晶质感) -->
<rect x="10.4" y="2" width="3.2" height="20" rx="1.6" fill="url(#tts-v2-fill)" stroke="url(#tts-v2-stroke)" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
<!-- 右侧:高频衰减声波(保持几何对称与呼吸感) -->
<rect x="17.8" y="5" width="2.2" height="14" rx="1.1" stroke="url(#tts-v2-stroke)" stroke-width="1.8" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

@@ -1 +0,0 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>AlibabaCloud</title><path d="M14.752 4.64h5.274C22.242 4.64 24 6.475 24 8.691V15.8a3.947 3.947 0 01-3.974 3.975h-5.274l1.299-1.835 3.822-1.222c.688-.23 1.146-.918 1.146-1.605v-5.81c0-.687-.458-1.375-1.146-1.605L16.05 6.475l-1.3-1.835zM2.98 15.111c0 .688.46 1.376 1.147 1.606l3.822 1.146 1.3 1.835H3.974A3.947 3.947 0 010 15.723V8.69c0-2.216 1.758-4.05 3.975-4.05h5.273L7.95 6.474 4.127 7.697c-.688.23-1.146.918-1.146 1.606v5.808z" fill="#FF6A00"></path><path d="M16.051 11.213H8.025v1.835h8.026v-1.835z" fill="#FF6A00"></path></svg>

Before

Width:  |  Height:  |  Size: 656 B

-1
View File
@@ -1 +0,0 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>BaiLian</title><path d="M6.336 8.919v6.162l5.335-3.083L6.337 8.92z" fill="#1C54E3"></path><path d="M21.394 5.288s-.006-.006-.01-.006L17.01 2.754 6.336 8.92l5.335 3.082 9.701-5.6.016-.01a.635.635 0 00.006-1.1v-.003z" fill="#AA9AFF"></path><path d="M21.71 12.465a.62.62 0 00-.316.085s-.006 0-.009.003l-4.375 2.528 5.05 2.915h.006a2.06 2.06 0 00.28-1.04v-3.855a.637.637 0 00-.636-.636z" fill="#00EAD1"></path><path d="M22.06 17.996l-5.05-2.915L6.34 21.242l4.27 2.465s.016.006.022.012a2.102 2.102 0 002.093 0c.006-.003.016-.006.022-.012l8.538-4.93c.003 0 .006-.003.01-.006.321-.183.589-.45.775-.772h-.006l-.004-.003z" fill="#00CEC9"></path><path d="M11.672 11.998l-5.336 3.083-1.444.832-3.605 2.083H1.28c.173.303.416.555.709.738l.078.044.016.01.02.012 4.232 2.442 10.671-6.161-5.335-3.082z" fill="#00EAD1"></path><path d="M12.74.29c-.1-.06-.208-.107-.315-.148-.02-.006-.038-.016-.057-.022a2.121 2.121 0 00-.7-.12c-.233 0-.457.038-.668.11l-.031.01a2.196 2.196 0 00-.372.17L2.068 5.222s-.003 0-.006.003c-.324.183-.592.451-.781.773h.006l5.049 2.918L17.01 2.758 12.74.29z" fill="#7347FF"></path><path d="M1.287 6.001H1.28A2.06 2.06 0 001 7.041v9.915c0 .378.1.735.28 1.043h.007l5.049-2.918V8.919l-5.05-2.918z" fill="#0423DA"></path></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

-3
View File
@@ -1,3 +0,0 @@
.ant-alert-with-description .ant-alert-title {
line-height: 1;
}
-1
View File
@@ -1,5 +1,4 @@
@import './table.less';
@import './alert.less';
.m-b-20 {
margin-bottom: 20px;
-1
View File
@@ -3,7 +3,6 @@
.ant-layout-sider-children {
border-inline: none;
border-radius: 0;
padding-inline-end: 0;
padding-block-end: 8px;
}
-31
View File
@@ -9,15 +9,6 @@
}
}
@keyframes tableEmptyFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.scroll-table {
.ant-table {
.ant-table-container {
@@ -27,27 +18,5 @@
scrollbar-color: var(--color-scrollbar-thumb) transparent;
}
}
// Reserve a stable block for the empty/loading state so the first-load
// spinner and the empty result occupy the same height as eventual data —
// this removes the layout jump when entering the page. Scoped to
// `.ant-table-content` so it only targets x-scroll tables (whose empty
// row lives here) and leaves fixed-height `scroll.y` tables untouched.
// Height must match the `minHeight` passed to <NoResult> in
// use-no-resource-result.
.ant-table-content {
.ant-table-placeholder {
> .ant-table-cell {
height: calc(100vh - 300px);
}
// NoResult renders nothing while loading and mounts an <Empty> only
// once the request settles, so this fires exactly when the empty
// state appears — a seamless fade-in instead of a hard pop.
.ant-empty {
animation: tableEmptyFadeIn 0.3s ease-in-out;
}
}
}
}
}
-7
View File
@@ -63,13 +63,6 @@ export const fromClusterCreationAtom = atom(false);
export const clusterSessionAtom = atom<{
firstAddWorker: boolean;
firstAddCluster: boolean;
presetClusterType?: 'model' | 'gpu';
// Provider to preselect when the create flow opens — set by the
// empty-state CTA on feature pages that need a specific provider
// (e.g. GPU Service can only schedule on Kubernetes, so its
// "Add Cluster" button skips provider catalog and lands on the
// K8s configure step). Consumed once by ClusterCreate on mount.
providerHint?: string;
} | null>(null);
export const clusterDetailAtom = atom<ClusterListItem | null>(null);
+6
View File
@@ -0,0 +1,6 @@
import { ClusterListItem } from '@/pages/cluster-management/config/types';
import { atom } from 'jotai';
export const currentClusterAtom = atom<
(Partial<ClusterListItem> & { label?: string; value?: number }) | null
>(null);
-7
View File
@@ -55,10 +55,3 @@ export const userSettingsHelperAtom = atom(
}
);
export const hideModalTemporarilyAtom = atom<boolean>(false);
export const collapsedMenuGroupsAtom = atomWithStorage<string[]>(
'collapsedMenuGroups',
[],
undefined,
{ getOnInit: true }
);
+13 -55
View File
@@ -3,15 +3,6 @@ import { atomWithStorage } from 'jotai/utils';
export const userAtom = atomWithStorage<any>('userInfo', null);
// Backs the `currentOrganizationId` localStorage key. Stays null in
// builds with no Org context (single-tenant), and is shared with any
// extension that persists the same key so both sides stay in sync
// without one side having to import from the other.
export const currentOrganizationIdAtom = atomWithStorage<number | null>(
'currentOrganizationId',
null
);
export const GPUStackVersionAtom = atom<{
version: string;
git_commit: string;
@@ -32,15 +23,16 @@ export const UpdateCheckAtom = atom<{
latest_version: ''
});
export const initialPasswordAtom = atom<string>('');
export const initialPasswordAtom = atomWithStorage<string>(
'initialPassword',
''
);
// Namespace the server creates for an Org's resources on each Kubernetes
// cluster. The format must match the backend's ``get_namespace_name``
// helper — ``gpustack-{name}`` — because the GPU-instance / storage CRDs
// helper — ``gpustack-{slug}`` — because the GPU-instance / storage CRDs
// (worker.gpustack.ai/v1) are namespaced and the server-side admission
// keys off this exact name. The identifier column on the unified
// Principal table is now ``name`` (post identity-consolidation rename
// of the legacy ``slug``); the namespace prefix is unchanged.
// keys off this exact name.
//
// Resolution path:
// 1. The Org the caller is currently acting under — the enterprise
@@ -83,61 +75,27 @@ const getStoredCurrentOrgId = (): number | null => {
// the caller's member orgs; ``allOrganizations`` is admin-only (every
// Org on the platform) so admin sessions can resolve any owner Org id.
// Both are checked because ``currentOrganizationId`` is null in the
// admin "All" view but a member org's ``name`` might still cover the
// admin "All" view but a member org's slug might still cover the
// cluster-owner fallback.
const ORG_CACHE_KEYS = ['organizationList', 'allOrganizations'] as const;
export interface CachedOrg {
id: number;
name?: string;
// The platform Org (single global tenant). Its models are NOT
// namespaced in ``/v1/models`` — they appear under their bare name.
is_platform?: boolean;
}
// Resolve the cached Org record for an owner/principal id by scanning both
// org caches. ``organizationList`` (the caller's member orgs) is checked
// alongside the admin-only ``allOrganizations`` so member sessions resolve
// too. Id types vary between localStorage payloads (some writers stringify,
// others persist as a JSON number), so compare as strings — strict equality
// would silently miss those cases.
export const getOrgById = (
id: number | string | null | undefined
): CachedOrg | null => {
const lookupOrgNamespace = (id: number | null): string | null => {
if (id == null) return null;
// Normalise both sides to strings — the stored id type varies between
// localStorage payloads (some writers stringify, others persist as a
// JSON number); strict equality would silently miss those cases.
const target = String(id);
for (const key of ORG_CACHE_KEYS) {
try {
const raw = localStorage.getItem(key);
if (!raw) continue;
const list = JSON.parse(raw) as CachedOrg[];
const list = JSON.parse(raw) as Array<{ id: number; slug?: string }>;
if (!Array.isArray(list)) continue;
const match = list.find((item) => String(item?.id) === target);
if (match) return match;
if (match?.slug) return `gpustack-${match.slug}`;
} catch {
// ignore malformed cache; continue checking other keys
}
}
return null;
};
// Bare Org *name* (e.g. ``org1``) for an owner/principal id, or null.
export const getOrgNameById = (
id: number | string | null | undefined
): string | null => {
return getOrgById(id)?.name ?? null;
};
const lookupOrgNamespace = (id: number | null): string | null => {
const name = getOrgNameById(id);
return name ? `gpustack-${name}` : null;
};
// The Org the caller is currently acting under, or null in the admin-"All"
// context. The org-switcher reloads the page on switch, so the list pages
// always show this org's resources — which is how ``/v1/models`` namespaces
// their model ids (``{org}/{name}``). Callers reconstructing that id use this
// as the fallback owner when a row carries no explicit ``owner_principal_id``.
export const getCurrentOrg = (): CachedOrg | null => {
return getOrgById(getStoredCurrentOrgId());
};
+2 -7
View File
@@ -6,17 +6,12 @@ export const clearStorageUserSettings = () => {
const savedSettings = JSON.parse(
localStorage.getItem('userSettings') || '{}'
);
// colorPrimary is an enterprise-wide branding setting (set by admins
// and applied by `onAppInit` from /enterprise/settings), not a per-user
// preference. Preserve it across login — otherwise the next layout
// mount triggers `atomWithStorage.onMount`, re-reads localStorage,
// and falls back to the default color until a full page refresh
// re-runs `applyEnterpriseSettings`.
localStorage.setItem(
'userSettings',
JSON.stringify({
...savedSettings,
hideAddResourceModal: false
hideAddResourceModal: false,
colorPrimary: undefined
})
);
} catch (error) {
+26 -4
View File
@@ -1,8 +1,10 @@
import { GPUStackVersionAtom } from '@/atoms/user';
import { getAtomStorage } from '@/atoms/utils';
import VersionInfo, { modalConfig } from '@/components/version-info';
import externalLinks from '@/constants/external-links';
import { useIntl } from '@umijs/max';
import { Divider, Typography } from 'antd';
import { Button, Divider, Modal, Typography } from 'antd';
import { createStyles } from 'antd-style';
import { useAtomValue } from 'jotai';
import styled from 'styled-components';
const CompanyWrapper = styled.div`
@@ -31,11 +33,20 @@ const useStyles = createStyles(({ token, css }) => ({
const Footer: React.FC = () => {
const intl = useIntl();
const [modal, contextHolder] = Modal.useModal();
const { styles } = useStyles();
const version = useAtomValue(GPUStackVersionAtom);
const showVersion = () => {
modal.info({
...modalConfig,
width: 460,
content: <VersionInfo intl={intl} />
});
};
return (
<>
{contextHolder}
<div className={styles.footer}>
<div className="footer-content">
<div className="footer-content-left">
@@ -52,7 +63,18 @@ const Footer: React.FC = () => {
</Typography.Link>
</CompanyWrapper>
<Divider orientation="vertical" />
<span>{version?.version}</span>
<Button
type="link"
size="small"
href={externalLinks.documentation}
target="_blank"
>
{intl.formatMessage({ id: 'common.button.help' })}
</Button>
<Divider orientation="vertical" />
<Button type="link" size="small" onClick={showVersion}>
{getAtomStorage(GPUStackVersionAtom)?.version}
</Button>
</div>
</div>
</div>
-12
View File
@@ -1,12 +0,0 @@
// Wrapper around core-ui's FullMarkdown that co-locates the KaTeX stylesheet.
//
// core-ui deliberately does NOT bundle katex.min.css (importing it there
// base64-inlines ~1.4MB of fonts into the shared, render-blocking index.css).
// Importing it here keeps the KaTeX CSS in the route chunk that actually
// renders math, so it loads lazily and never blocks first paint.
//
// Always import FullMarkdown from this module, not from '@gpustack/core-ui/markdown'.
import { FullMarkdown } from '@gpustack/core-ui/markdown';
import 'katex/dist/katex.min.css';
export default FullMarkdown;
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More