refactor: remove display ID from items and ancient artifacts
Drop display_id column from items and ancient_artifacts tables Remove display ID inputs, labels, and sorting logic across the stack BREAKING CHANGE: behavior is not backward compatible.
This commit is contained in:
16
DESIGN.md
16
DESIGN.md
@@ -593,7 +593,6 @@ Pokemon 详情页展示:
|
|||||||
|
|
||||||
物品可配置:
|
物品可配置:
|
||||||
|
|
||||||
- Display ID:用于物品和 Event Items 各自列表内展示与排序;`display_id` 与 `is_event_item` 组合唯一
|
|
||||||
- 名称
|
- 名称
|
||||||
- 介绍
|
- 介绍
|
||||||
- 是否为 Event Item:`is_event_item`
|
- 是否为 Event Item:`is_event_item`
|
||||||
@@ -638,8 +637,8 @@ Items 与 Event Items 使用相同数据模型:
|
|||||||
- 按分类展示为标签页
|
- 按分类展示为标签页
|
||||||
- 按用途筛选
|
- 按用途筛选
|
||||||
- 按标签筛选
|
- 按标签筛选
|
||||||
- 按 Display ID 和自定义排序展示
|
- 按自定义排序展示
|
||||||
- 物品列表卡片使用与 Pokemon 列表一致的居中图鉴式布局,只展示物品图标、`#Display ID 名称` 和分类;不展示标签、入手方式或编辑元信息。
|
- 物品列表卡片使用与 Pokemon 列表一致的居中图鉴式布局,只展示物品图标、名称和分类;不展示标签、入手方式或编辑元信息。
|
||||||
- 有用途的物品在卡片左上角以斜 Ribbon 展示用途名称。
|
- 有用途的物品在卡片左上角以斜 Ribbon 展示用途名称。
|
||||||
- 已配置图标时,物品卡片展示图标缩略图;未配置图标时保留默认物品标记。
|
- 已配置图标时,物品卡片展示图标缩略图;未配置图标时保留默认物品标记。
|
||||||
|
|
||||||
@@ -648,7 +647,6 @@ Items 与 Event Items 使用相同数据模型:
|
|||||||
- 基本信息
|
- 基本信息
|
||||||
- 当前图标图片;未配置图标时展示默认物品标记占位符
|
- 当前图标图片;未配置图标时展示默认物品标记占位符
|
||||||
- 顶部按图标 / 占位符与核心信息概览并排展示,移动端改为单列;顶部概览卡片不显示 `Image` / `Details` 通用区块标题,也不展示图片历史缩略图
|
- 顶部按图标 / 占位符与核心信息概览并排展示,移动端改为单列;顶部概览卡片不显示 `Image` / `Details` 通用区块标题,也不展示图片历史缩略图
|
||||||
- Display ID
|
|
||||||
- 介绍
|
- 介绍
|
||||||
- 分类
|
- 分类
|
||||||
- 用途
|
- 用途
|
||||||
@@ -667,7 +665,6 @@ Items 与 Event Items 使用相同数据模型:
|
|||||||
|
|
||||||
Ancient Artifacts 是独立 Wiki 内容类型,可配置:
|
Ancient Artifacts 是独立 Wiki 内容类型,可配置:
|
||||||
|
|
||||||
- Display ID:用于展示与排序
|
|
||||||
- 名称
|
- 名称
|
||||||
- 介绍
|
- 介绍
|
||||||
- 图片:使用 Ancient Artifacts 上传目录,支持图片历史
|
- 图片:使用 Ancient Artifacts 上传目录,支持图片历史
|
||||||
@@ -684,12 +681,11 @@ Ancient Artifacts 列表功能:
|
|||||||
- 搜索
|
- 搜索
|
||||||
- 按分类展示为标签页
|
- 按分类展示为标签页
|
||||||
- 按标签筛选
|
- 按标签筛选
|
||||||
- 按 Display ID 和自定义排序展示
|
- 按自定义排序展示
|
||||||
- 列表卡片使用与 Pokemon 列表一致的居中图鉴式布局,展示图片 / 默认 Ancient Artifact 标记、`#Display ID 名称` 和分类;不展示编辑元信息。
|
- 列表卡片使用与 Pokemon 列表一致的居中图鉴式布局,展示图片 / 默认 Ancient Artifact 标记、名称和分类;不展示编辑元信息。
|
||||||
|
|
||||||
Ancient Artifacts 详情页展示:
|
Ancient Artifacts 详情页展示:
|
||||||
|
|
||||||
- Display ID
|
|
||||||
- 名称
|
- 名称
|
||||||
- 图片;未配置图片时展示默认 Ancient Artifact 标记
|
- 图片;未配置图片时展示默认 Ancient Artifact 标记
|
||||||
- 介绍
|
- 介绍
|
||||||
@@ -719,8 +715,8 @@ Ancient Artifacts 详情页展示:
|
|||||||
|
|
||||||
- 独立于物品列表展示
|
- 独立于物品列表展示
|
||||||
- 按结果物品分类展示
|
- 按结果物品分类展示
|
||||||
- 按结果物品 Display ID 和自定义排序展示
|
- 按自定义排序展示
|
||||||
- 材料单列表卡片使用与 Pokemon 列表一致的居中图鉴式布局,按结果物品展示图标、`#Display ID 名称` 和分类;不展示编辑元信息。
|
- 材料单列表卡片使用与 Pokemon 列表一致的居中图鉴式布局,按结果物品展示图标、名称和分类;不展示编辑元信息。
|
||||||
- 有用途的结果物品在卡片左上角以斜 Ribbon 展示用途名称。
|
- 有用途的结果物品在卡片左上角以斜 Ribbon 展示用途名称。
|
||||||
- Create Recipe 按钮展示在结果物品名称下方;已有材料单的卡片保留同等按钮空间但不显示按钮;标记为无材料单的物品展示禁用按钮;可创建材料单的物品展示可点击按钮并进入创建流程。
|
- Create Recipe 按钮展示在结果物品名称下方;已有材料单的卡片保留同等按钮空间但不显示按钮;标记为无材料单的物品展示禁用按钮;可创建材料单的物品展示可点击按钮并进入创建流程。
|
||||||
|
|
||||||
|
|||||||
@@ -974,7 +974,6 @@ CREATE TABLE IF NOT EXISTS acquisition_methods (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS items (
|
CREATE TABLE IF NOT EXISTS items (
|
||||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||||
display_id integer NOT NULL CHECK (display_id > 0),
|
|
||||||
name text NOT NULL UNIQUE,
|
name text NOT NULL UNIQUE,
|
||||||
details text NOT NULL DEFAULT '',
|
details text NOT NULL DEFAULT '',
|
||||||
category_key text NOT NULL DEFAULT 'other',
|
category_key text NOT NULL DEFAULT 'other',
|
||||||
@@ -1011,7 +1010,6 @@ CREATE TABLE IF NOT EXISTS items (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ancient_artifacts (
|
CREATE TABLE IF NOT EXISTS ancient_artifacts (
|
||||||
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||||
display_id integer NOT NULL UNIQUE CHECK (display_id > 0),
|
|
||||||
name text NOT NULL UNIQUE,
|
name text NOT NULL UNIQUE,
|
||||||
details text NOT NULL DEFAULT '',
|
details text NOT NULL DEFAULT '',
|
||||||
category_key text NOT NULL CHECK (category_key IN ('lost-relics-l', 'lost-relics-s', 'fossils')),
|
category_key text NOT NULL CHECK (category_key IN ('lost-relics-l', 'lost-relics-s', 'fossils')),
|
||||||
@@ -1221,7 +1219,6 @@ ALTER TABLE life_tags
|
|||||||
ADD COLUMN IF NOT EXISTS is_default boolean NOT NULL DEFAULT false;
|
ADD COLUMN IF NOT EXISTS is_default boolean NOT NULL DEFAULT false;
|
||||||
|
|
||||||
ALTER TABLE items
|
ALTER TABLE items
|
||||||
ADD COLUMN IF NOT EXISTS display_id integer,
|
|
||||||
ADD COLUMN IF NOT EXISTS details text NOT NULL DEFAULT '',
|
ADD COLUMN IF NOT EXISTS details text NOT NULL DEFAULT '',
|
||||||
ADD COLUMN IF NOT EXISTS category_key text,
|
ADD COLUMN IF NOT EXISTS category_key text,
|
||||||
ADD COLUMN IF NOT EXISTS usage_key text;
|
ADD COLUMN IF NOT EXISTS usage_key text;
|
||||||
@@ -1242,10 +1239,6 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
UPDATE items
|
|
||||||
SET display_id = id
|
|
||||||
WHERE display_id IS NULL;
|
|
||||||
|
|
||||||
UPDATE items i
|
UPDATE items i
|
||||||
SET category_key = CASE lower(trim(c.name))
|
SET category_key = CASE lower(trim(c.name))
|
||||||
WHEN 'furniture' THEN 'furniture'
|
WHEN 'furniture' THEN 'furniture'
|
||||||
@@ -1303,7 +1296,6 @@ WHERE usage_key IS NOT NULL
|
|||||||
AND usage_key NOT IN ('decoration', 'relaxation', 'toy', 'road');
|
AND usage_key NOT IN ('decoration', 'relaxation', 'toy', 'road');
|
||||||
|
|
||||||
ALTER TABLE items
|
ALTER TABLE items
|
||||||
ALTER COLUMN display_id SET NOT NULL,
|
|
||||||
ALTER COLUMN category_key SET NOT NULL,
|
ALTER COLUMN category_key SET NOT NULL,
|
||||||
ALTER COLUMN category_key SET DEFAULT 'other';
|
ALTER COLUMN category_key SET DEFAULT 'other';
|
||||||
|
|
||||||
@@ -1313,7 +1305,6 @@ ALTER TABLE items
|
|||||||
DROP CONSTRAINT IF EXISTS items_usage_key_check;
|
DROP CONSTRAINT IF EXISTS items_usage_key_check;
|
||||||
|
|
||||||
ALTER TABLE items
|
ALTER TABLE items
|
||||||
ADD CONSTRAINT items_display_id_positive CHECK (display_id > 0),
|
|
||||||
ADD CONSTRAINT items_category_key_check CHECK (category_key IN (
|
ADD CONSTRAINT items_category_key_check CHECK (category_key IN (
|
||||||
'furniture',
|
'furniture',
|
||||||
'misc',
|
'misc',
|
||||||
@@ -1330,6 +1321,20 @@ ALTER TABLE items
|
|||||||
)),
|
)),
|
||||||
ADD CONSTRAINT items_usage_key_check CHECK (usage_key IS NULL OR usage_key IN ('decoration', 'relaxation', 'toy', 'road'));
|
ADD CONSTRAINT items_usage_key_check CHECK (usage_key IS NULL OR usage_key IN ('decoration', 'relaxation', 'toy', 'road'));
|
||||||
|
|
||||||
|
DROP INDEX IF EXISTS items_display_event_item_key;
|
||||||
|
DROP INDEX IF EXISTS items_display_order_idx;
|
||||||
|
DROP INDEX IF EXISTS ancient_artifacts_display_order_idx;
|
||||||
|
|
||||||
|
ALTER TABLE ancient_artifacts
|
||||||
|
DROP CONSTRAINT IF EXISTS ancient_artifacts_display_id_key,
|
||||||
|
DROP CONSTRAINT IF EXISTS ancient_artifacts_display_id_check;
|
||||||
|
|
||||||
|
ALTER TABLE items
|
||||||
|
DROP COLUMN IF EXISTS display_id;
|
||||||
|
|
||||||
|
ALTER TABLE ancient_artifacts
|
||||||
|
DROP COLUMN IF EXISTS display_id;
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS environments_sort_order_idx ON environments(sort_order, id);
|
CREATE INDEX IF NOT EXISTS environments_sort_order_idx ON environments(sort_order, id);
|
||||||
CREATE INDEX IF NOT EXISTS skills_sort_order_idx ON skills(sort_order, id);
|
CREATE INDEX IF NOT EXISTS skills_sort_order_idx ON skills(sort_order, id);
|
||||||
CREATE INDEX IF NOT EXISTS favorite_things_sort_order_idx ON favorite_things(sort_order, id);
|
CREATE INDEX IF NOT EXISTS favorite_things_sort_order_idx ON favorite_things(sort_order, id);
|
||||||
@@ -1342,10 +1347,7 @@ CREATE INDEX IF NOT EXISTS item_categories_sort_order_idx ON item_categories(sor
|
|||||||
CREATE INDEX IF NOT EXISTS item_usages_sort_order_idx ON item_usages(sort_order, id);
|
CREATE INDEX IF NOT EXISTS item_usages_sort_order_idx ON item_usages(sort_order, id);
|
||||||
CREATE INDEX IF NOT EXISTS acquisition_methods_sort_order_idx ON acquisition_methods(sort_order, id);
|
CREATE INDEX IF NOT EXISTS acquisition_methods_sort_order_idx ON acquisition_methods(sort_order, id);
|
||||||
CREATE INDEX IF NOT EXISTS items_sort_order_idx ON items(sort_order, id);
|
CREATE INDEX IF NOT EXISTS items_sort_order_idx ON items(sort_order, id);
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS items_display_event_item_key ON items(display_id, is_event_item);
|
|
||||||
CREATE INDEX IF NOT EXISTS items_display_order_idx ON items(is_event_item, display_id, sort_order, id);
|
|
||||||
CREATE INDEX IF NOT EXISTS ancient_artifacts_sort_order_idx ON ancient_artifacts(sort_order, id);
|
CREATE INDEX IF NOT EXISTS ancient_artifacts_sort_order_idx ON ancient_artifacts(sort_order, id);
|
||||||
CREATE INDEX IF NOT EXISTS ancient_artifacts_display_order_idx ON ancient_artifacts(display_id, sort_order, id);
|
|
||||||
CREATE INDEX IF NOT EXISTS recipes_sort_order_idx ON recipes(sort_order, id);
|
CREATE INDEX IF NOT EXISTS recipes_sort_order_idx ON recipes(sort_order, id);
|
||||||
CREATE INDEX IF NOT EXISTS dish_categories_sort_order_idx ON dish_categories(sort_order, id);
|
CREATE INDEX IF NOT EXISTS dish_categories_sort_order_idx ON dish_categories(sort_order, id);
|
||||||
CREATE INDEX IF NOT EXISTS dish_flavors_sort_order_idx ON dish_flavors(sort_order, id);
|
CREATE INDEX IF NOT EXISTS dish_flavors_sort_order_idx ON dish_flavors(sort_order, id);
|
||||||
|
|||||||
@@ -201,7 +201,6 @@ type PokemonCsvData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type ItemPayload = {
|
type ItemPayload = {
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
details: string;
|
details: string;
|
||||||
translations: TranslationInput;
|
translations: TranslationInput;
|
||||||
@@ -220,7 +219,6 @@ type ItemPayload = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type AncientArtifactPayload = {
|
type AncientArtifactPayload = {
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
details: string;
|
details: string;
|
||||||
translations: TranslationInput;
|
translations: TranslationInput;
|
||||||
@@ -541,7 +539,6 @@ type PokemonChangeSource = {
|
|||||||
favorite_things: Array<{ name: string }>;
|
favorite_things: Array<{ name: string }>;
|
||||||
} & TranslationChangeSource;
|
} & TranslationChangeSource;
|
||||||
type ItemChangeSource = {
|
type ItemChangeSource = {
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
details: string;
|
details: string;
|
||||||
isEventItem: boolean;
|
isEventItem: boolean;
|
||||||
@@ -554,7 +551,6 @@ type ItemChangeSource = {
|
|||||||
tags: Array<{ name: string }>;
|
tags: Array<{ name: string }>;
|
||||||
} & TranslationChangeSource;
|
} & TranslationChangeSource;
|
||||||
type AncientArtifactChangeSource = {
|
type AncientArtifactChangeSource = {
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
details: string;
|
details: string;
|
||||||
image: EntityImageValue | null;
|
image: EntityImageValue | null;
|
||||||
@@ -2251,7 +2247,6 @@ async function itemEditChanges(
|
|||||||
const tagNames = await entityNameMap(client, 'favorite_things', after.tagIds);
|
const tagNames = await entityNameMap(client, 'favorite_things', after.tagIds);
|
||||||
|
|
||||||
pushChange(changes, 'Name', before.name, after.name);
|
pushChange(changes, 'Name', before.name, after.name);
|
||||||
pushChange(changes, 'Display ID', String(before.displayId), String(after.displayId));
|
|
||||||
pushChange(changes, 'Description', before.details, after.details);
|
pushChange(changes, 'Description', before.details, after.details);
|
||||||
pushTranslationChanges(changes, before.translations, after.translations, ['name', 'details']);
|
pushTranslationChanges(changes, before.translations, after.translations, ['name', 'details']);
|
||||||
pushChange(changes, 'Event item', boolValue(before.isEventItem), boolValue(after.isEventItem));
|
pushChange(changes, 'Event item', boolValue(before.isEventItem), boolValue(after.isEventItem));
|
||||||
@@ -2277,7 +2272,6 @@ async function ancientArtifactEditChanges(
|
|||||||
const tagNames = await entityNameMap(client, 'favorite_things', after.tagIds);
|
const tagNames = await entityNameMap(client, 'favorite_things', after.tagIds);
|
||||||
|
|
||||||
pushChange(changes, 'Name', before.name, after.name);
|
pushChange(changes, 'Name', before.name, after.name);
|
||||||
pushChange(changes, 'Display ID', String(before.displayId), String(after.displayId));
|
|
||||||
pushChange(changes, 'Description', before.details, after.details);
|
pushChange(changes, 'Description', before.details, after.details);
|
||||||
pushTranslationChanges(changes, before.translations, after.translations, ['name', 'details']);
|
pushTranslationChanges(changes, before.translations, after.translations, ['name', 'details']);
|
||||||
pushChange(changes, 'Image', imagePathLabel(before.image?.path), imagePathLabel(after.imagePath));
|
pushChange(changes, 'Image', imagePathLabel(before.image?.path), imagePathLabel(after.imagePath));
|
||||||
@@ -2574,7 +2568,7 @@ export async function globalSearch(paramsQuery: QueryParams = {}, locale = defau
|
|||||||
${uploadedImageJson('i.image_path')} AS image
|
${uploadedImageJson('i.image_path')} AS image
|
||||||
FROM items i
|
FROM items i
|
||||||
WHERE ${itemName} ILIKE $1
|
WHERE ${itemName} ILIKE $1
|
||||||
ORDER BY i.display_id, ${orderByEntity('i')}
|
ORDER BY ${orderByEntity('i')}
|
||||||
LIMIT $2
|
LIMIT $2
|
||||||
`,
|
`,
|
||||||
[pattern, limit]
|
[pattern, limit]
|
||||||
@@ -2591,7 +2585,7 @@ export async function globalSearch(paramsQuery: QueryParams = {}, locale = defau
|
|||||||
${uploadedImageJson('a.image_path')} AS image
|
${uploadedImageJson('a.image_path')} AS image
|
||||||
FROM ancient_artifacts a
|
FROM ancient_artifacts a
|
||||||
WHERE ${artifactName} ILIKE $1
|
WHERE ${artifactName} ILIKE $1
|
||||||
ORDER BY a.display_id, ${orderByEntity('a')}
|
ORDER BY ${orderByEntity('a')}
|
||||||
LIMIT $2
|
LIMIT $2
|
||||||
`,
|
`,
|
||||||
[pattern, limit]
|
[pattern, limit]
|
||||||
@@ -6223,7 +6217,6 @@ function itemProjection(locale: string): string {
|
|||||||
return `
|
return `
|
||||||
SELECT
|
SELECT
|
||||||
i.id,
|
i.id,
|
||||||
i.display_id AS "displayId",
|
|
||||||
${itemName} AS name,
|
${itemName} AS name,
|
||||||
i.name AS "baseName",
|
i.name AS "baseName",
|
||||||
${itemDetails} AS details,
|
${itemDetails} AS details,
|
||||||
@@ -6324,8 +6317,8 @@ export async function listItems(paramsQuery: QueryParams, locale = defaultLocale
|
|||||||
|
|
||||||
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
||||||
const orderClause = recipeOrder
|
const orderClause = recipeOrder
|
||||||
? `ORDER BY CASE WHEN item_recipe.id IS NULL THEN 1 ELSE 0 END, item_recipe.sort_order, item_recipe.id, i.display_id, ${orderByEntity('i')}`
|
? `ORDER BY CASE WHEN item_recipe.id IS NULL THEN 1 ELSE 0 END, item_recipe.sort_order, item_recipe.id, ${orderByEntity('i')}`
|
||||||
: `ORDER BY i.display_id, ${orderByEntity('i')}`;
|
: `ORDER BY ${orderByEntity('i')}`;
|
||||||
return query(`${itemProjection(locale)} ${whereClause} ${orderClause}`, params);
|
return query(`${itemProjection(locale)} ${whereClause} ${orderClause}`, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6382,7 +6375,6 @@ export async function getItem(id: number, locale = defaultLocale) {
|
|||||||
), '[]'::json) AS materials,
|
), '[]'::json) AS materials,
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', result_item.id,
|
'id', result_item.id,
|
||||||
'displayId', result_item.display_id,
|
|
||||||
'name', ${resultItemName},
|
'name', ${resultItemName},
|
||||||
'image', ${uploadedImageJson('result_item.image_path')},
|
'image', ${uploadedImageJson('result_item.image_path')},
|
||||||
'category', ${systemListJsonSql('result_item.category_key', itemCategoryOptions, locale)},
|
'category', ${systemListJsonSql('result_item.category_key', itemCategoryOptions, locale)},
|
||||||
@@ -6489,7 +6481,6 @@ function cleanItemPayload(payload: Record<string, unknown>): ItemPayload {
|
|||||||
const usage = usageId === null ? null : systemListOptionById(itemUsageOptions, usageId, 'server.validation.usageRequired');
|
const usage = usageId === null ? null : systemListOptionById(itemUsageOptions, usageId, 'server.validation.usageRequired');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
displayId: requirePositiveInteger(payload.displayId, 'server.validation.itemDisplayIdRequired'),
|
|
||||||
name: cleanName(payload.name, 'server.validation.itemNameRequired'),
|
name: cleanName(payload.name, 'server.validation.itemNameRequired'),
|
||||||
details: cleanOptionalText(payload.details),
|
details: cleanOptionalText(payload.details),
|
||||||
translations: cleanTranslations(payload.translations, ['name', 'details']),
|
translations: cleanTranslations(payload.translations, ['name', 'details']),
|
||||||
@@ -6546,7 +6537,6 @@ export async function createItem(payload: Record<string, unknown>, userId: numbe
|
|||||||
const result = await client.query<{ id: number }>(
|
const result = await client.query<{ id: number }>(
|
||||||
`
|
`
|
||||||
INSERT INTO items (
|
INSERT INTO items (
|
||||||
display_id,
|
|
||||||
name,
|
name,
|
||||||
details,
|
details,
|
||||||
category_key,
|
category_key,
|
||||||
@@ -6561,11 +6551,10 @@ export async function createItem(payload: Record<string, unknown>, userId: numbe
|
|||||||
created_by_user_id,
|
created_by_user_id,
|
||||||
updated_by_user_id
|
updated_by_user_id
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $13)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $12)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
cleanPayload.displayId,
|
|
||||||
cleanPayload.name,
|
cleanPayload.name,
|
||||||
cleanPayload.details,
|
cleanPayload.details,
|
||||||
cleanPayload.categoryKey,
|
cleanPayload.categoryKey,
|
||||||
@@ -6599,23 +6588,21 @@ export async function updateItem(id: number, payload: Record<string, unknown>, u
|
|||||||
const result = await client.query(
|
const result = await client.query(
|
||||||
`
|
`
|
||||||
UPDATE items
|
UPDATE items
|
||||||
SET display_id = $1,
|
SET name = $1,
|
||||||
name = $2,
|
details = $2,
|
||||||
details = $3,
|
category_key = $3,
|
||||||
category_key = $4,
|
usage_key = $4,
|
||||||
usage_key = $5,
|
dyeable = $5,
|
||||||
dyeable = $6,
|
dual_dyeable = $6,
|
||||||
dual_dyeable = $7,
|
pattern_editable = $7,
|
||||||
pattern_editable = $8,
|
no_recipe = $8,
|
||||||
no_recipe = $9,
|
is_event_item = $9,
|
||||||
is_event_item = $10,
|
image_path = $10,
|
||||||
image_path = $11,
|
updated_by_user_id = $11,
|
||||||
updated_by_user_id = $12,
|
|
||||||
updated_at = now()
|
updated_at = now()
|
||||||
WHERE id = $13
|
WHERE id = $12
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
cleanPayload.displayId,
|
|
||||||
cleanPayload.name,
|
cleanPayload.name,
|
||||||
cleanPayload.details,
|
cleanPayload.details,
|
||||||
cleanPayload.categoryKey,
|
cleanPayload.categoryKey,
|
||||||
@@ -6665,7 +6652,6 @@ function ancientArtifactProjection(locale: string): string {
|
|||||||
return `
|
return `
|
||||||
SELECT
|
SELECT
|
||||||
a.id,
|
a.id,
|
||||||
a.display_id AS "displayId",
|
|
||||||
${artifactName} AS name,
|
${artifactName} AS name,
|
||||||
a.name AS "baseName",
|
a.name AS "baseName",
|
||||||
${artifactDetails} AS details,
|
${artifactDetails} AS details,
|
||||||
@@ -6719,7 +6705,7 @@ export async function listAncientArtifacts(paramsQuery: QueryParams = {}, locale
|
|||||||
}
|
}
|
||||||
|
|
||||||
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
||||||
return query(`${ancientArtifactProjection(locale)} ${whereClause} ORDER BY a.display_id, ${orderByEntity('a')}`, params);
|
return query(`${ancientArtifactProjection(locale)} ${whereClause} ORDER BY ${orderByEntity('a')}`, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAncientArtifact(id: number, locale = defaultLocale) {
|
export async function getAncientArtifact(id: number, locale = defaultLocale) {
|
||||||
@@ -6738,7 +6724,6 @@ function cleanAncientArtifactPayload(payload: Record<string, unknown>): AncientA
|
|||||||
const category = systemListOptionById(ancientArtifactCategoryOptions, categoryId, 'server.validation.categoryRequired');
|
const category = systemListOptionById(ancientArtifactCategoryOptions, categoryId, 'server.validation.categoryRequired');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
displayId: requirePositiveInteger(payload.displayId, 'server.validation.artifactDisplayIdRequired'),
|
|
||||||
name: cleanName(payload.name, 'server.validation.artifactNameRequired'),
|
name: cleanName(payload.name, 'server.validation.artifactNameRequired'),
|
||||||
details: cleanOptionalText(payload.details),
|
details: cleanOptionalText(payload.details),
|
||||||
translations: cleanTranslations(payload.translations, ['name', 'details']),
|
translations: cleanTranslations(payload.translations, ['name', 'details']),
|
||||||
@@ -6768,7 +6753,6 @@ export async function createAncientArtifact(payload: Record<string, unknown>, us
|
|||||||
const result = await client.query<{ id: number }>(
|
const result = await client.query<{ id: number }>(
|
||||||
`
|
`
|
||||||
INSERT INTO ancient_artifacts (
|
INSERT INTO ancient_artifacts (
|
||||||
display_id,
|
|
||||||
name,
|
name,
|
||||||
details,
|
details,
|
||||||
category_key,
|
category_key,
|
||||||
@@ -6777,11 +6761,10 @@ export async function createAncientArtifact(payload: Record<string, unknown>, us
|
|||||||
created_by_user_id,
|
created_by_user_id,
|
||||||
updated_by_user_id
|
updated_by_user_id
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $7)
|
VALUES ($1, $2, $3, $4, $5, $6, $6)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
`,
|
`,
|
||||||
[
|
[
|
||||||
cleanPayload.displayId,
|
|
||||||
cleanPayload.name,
|
cleanPayload.name,
|
||||||
cleanPayload.details,
|
cleanPayload.details,
|
||||||
cleanPayload.categoryKey,
|
cleanPayload.categoryKey,
|
||||||
@@ -6809,16 +6792,15 @@ export async function updateAncientArtifact(id: number, payload: Record<string,
|
|||||||
const result = await client.query(
|
const result = await client.query(
|
||||||
`
|
`
|
||||||
UPDATE ancient_artifacts
|
UPDATE ancient_artifacts
|
||||||
SET display_id = $1,
|
SET name = $1,
|
||||||
name = $2,
|
details = $2,
|
||||||
details = $3,
|
category_key = $3,
|
||||||
category_key = $4,
|
image_path = $4,
|
||||||
image_path = $5,
|
updated_by_user_id = $5,
|
||||||
updated_by_user_id = $6,
|
|
||||||
updated_at = now()
|
updated_at = now()
|
||||||
WHERE id = $7
|
WHERE id = $6
|
||||||
`,
|
`,
|
||||||
[cleanPayload.displayId, cleanPayload.name, cleanPayload.details, cleanPayload.categoryKey, cleanPayload.imagePath, userId, id]
|
[cleanPayload.name, cleanPayload.details, cleanPayload.categoryKey, cleanPayload.imagePath, userId, id]
|
||||||
);
|
);
|
||||||
if (result.rowCount === 0) {
|
if (result.rowCount === 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -6917,7 +6899,6 @@ export async function getRecipe(id: number, locale = defaultLocale) {
|
|||||||
), '[]'::json) AS materials,
|
), '[]'::json) AS materials,
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', result_item.id,
|
'id', result_item.id,
|
||||||
'displayId', result_item.display_id,
|
|
||||||
'name', ${resultItemName},
|
'name', ${resultItemName},
|
||||||
'image', ${uploadedImageJson('result_item.image_path')},
|
'image', ${uploadedImageJson('result_item.image_path')},
|
||||||
'category', ${systemListJsonSql('result_item.category_key', itemCategoryOptions, locale)},
|
'category', ${systemListJsonSql('result_item.category_key', itemCategoryOptions, locale)},
|
||||||
@@ -7060,14 +7041,12 @@ function dishCategoryProjection(locale: string): string {
|
|||||||
${auditSelect('dc', 'category_created_user', 'category_updated_user')},
|
${auditSelect('dc', 'category_created_user', 'category_updated_user')},
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', cookware_item.id,
|
'id', cookware_item.id,
|
||||||
'displayId', cookware_item.display_id,
|
|
||||||
'name', ${cookwareName},
|
'name', ${cookwareName},
|
||||||
'image', ${uploadedImageJson('cookware_item.image_path')},
|
'image', ${uploadedImageJson('cookware_item.image_path')},
|
||||||
'category', ${systemListJsonSql('cookware_item.category_key', itemCategoryOptions, locale)}
|
'category', ${systemListJsonSql('cookware_item.category_key', itemCategoryOptions, locale)}
|
||||||
) AS cookware,
|
) AS cookware,
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', main_material_item.id,
|
'id', main_material_item.id,
|
||||||
'displayId', main_material_item.display_id,
|
|
||||||
'name', ${mainMaterialName},
|
'name', ${mainMaterialName},
|
||||||
'image', ${uploadedImageJson('main_material_item.image_path')},
|
'image', ${uploadedImageJson('main_material_item.image_path')},
|
||||||
'category', ${systemListJsonSql('main_material_item.category_key', itemCategoryOptions, locale)}
|
'category', ${systemListJsonSql('main_material_item.category_key', itemCategoryOptions, locale)}
|
||||||
@@ -7093,7 +7072,6 @@ function dishCategoryProjection(locale: string): string {
|
|||||||
'category', json_build_object('id', dc.id, 'name', ${categoryName}),
|
'category', json_build_object('id', dc.id, 'name', ${categoryName}),
|
||||||
'item', json_build_object(
|
'item', json_build_object(
|
||||||
'id', dish_item.id,
|
'id', dish_item.id,
|
||||||
'displayId', dish_item.display_id,
|
|
||||||
'name', ${dishItemName},
|
'name', ${dishItemName},
|
||||||
'image', ${uploadedImageJson('dish_item.image_path')},
|
'image', ${uploadedImageJson('dish_item.image_path')},
|
||||||
'category', ${systemListJsonSql('dish_item.category_key', itemCategoryOptions, locale)}
|
'category', ${systemListJsonSql('dish_item.category_key', itemCategoryOptions, locale)}
|
||||||
@@ -7102,7 +7080,6 @@ function dishCategoryProjection(locale: string): string {
|
|||||||
SELECT json_agg(
|
SELECT json_agg(
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', secondary_material_item.id,
|
'id', secondary_material_item.id,
|
||||||
'displayId', secondary_material_item.display_id,
|
|
||||||
'name', ${secondaryMaterialName},
|
'name', ${secondaryMaterialName},
|
||||||
'image', ${uploadedImageJson('secondary_material_item.image_path')},
|
'image', ${uploadedImageJson('secondary_material_item.image_path')},
|
||||||
'category', ${systemListJsonSql('secondary_material_item.category_key', itemCategoryOptions, locale)}
|
'category', ${systemListJsonSql('secondary_material_item.category_key', itemCategoryOptions, locale)}
|
||||||
@@ -7153,7 +7130,6 @@ function dishProjection(locale: string): string {
|
|||||||
json_build_object('id', dc.id, 'name', ${categoryName}) AS category,
|
json_build_object('id', dc.id, 'name', ${categoryName}) AS category,
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', dish_item.id,
|
'id', dish_item.id,
|
||||||
'displayId', dish_item.display_id,
|
|
||||||
'name', ${dishItemName},
|
'name', ${dishItemName},
|
||||||
'image', ${uploadedImageJson('dish_item.image_path')},
|
'image', ${uploadedImageJson('dish_item.image_path')},
|
||||||
'category', ${systemListJsonSql('dish_item.category_key', itemCategoryOptions, locale)}
|
'category', ${systemListJsonSql('dish_item.category_key', itemCategoryOptions, locale)}
|
||||||
@@ -7162,7 +7138,6 @@ function dishProjection(locale: string): string {
|
|||||||
SELECT json_agg(
|
SELECT json_agg(
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id', secondary_material_item.id,
|
'id', secondary_material_item.id,
|
||||||
'displayId', secondary_material_item.display_id,
|
|
||||||
'name', ${secondaryMaterialName},
|
'name', ${secondaryMaterialName},
|
||||||
'image', ${uploadedImageJson('secondary_material_item.image_path')},
|
'image', ${uploadedImageJson('secondary_material_item.image_path')},
|
||||||
'category', ${systemListJsonSql('secondary_material_item.category_key', itemCategoryOptions, locale)}
|
'category', ${systemListJsonSql('secondary_material_item.category_key', itemCategoryOptions, locale)}
|
||||||
@@ -7568,7 +7543,6 @@ const dataToolColumns = {
|
|||||||
habitatPokemon: ['habitat_id', 'pokemon_id', 'map_id', 'time_of_day', 'weather', 'rarity'],
|
habitatPokemon: ['habitat_id', 'pokemon_id', 'map_id', 'time_of_day', 'weather', 'rarity'],
|
||||||
items: [
|
items: [
|
||||||
'id',
|
'id',
|
||||||
'display_id',
|
|
||||||
'name',
|
'name',
|
||||||
'details',
|
'details',
|
||||||
'category_key',
|
'category_key',
|
||||||
@@ -7590,7 +7564,6 @@ const dataToolColumns = {
|
|||||||
artifactFavoriteThings: ['ancient_artifact_id', 'favorite_thing_id'],
|
artifactFavoriteThings: ['ancient_artifact_id', 'favorite_thing_id'],
|
||||||
artifacts: [
|
artifacts: [
|
||||||
'id',
|
'id',
|
||||||
'display_id',
|
|
||||||
'name',
|
'name',
|
||||||
'details',
|
'details',
|
||||||
'category_key',
|
'category_key',
|
||||||
@@ -7901,7 +7874,7 @@ async function exportScopeData(client: DbClient, scope: DataToolScope): Promise<
|
|||||||
|
|
||||||
if (scope === 'items') {
|
if (scope === 'items') {
|
||||||
return {
|
return {
|
||||||
items: await tableRows(client, 'SELECT * FROM items ORDER BY display_id, sort_order, id'),
|
items: await tableRows(client, 'SELECT * FROM items ORDER BY sort_order, id'),
|
||||||
itemAcquisitionMethods: await tableRows(client, 'SELECT * FROM item_acquisition_methods ORDER BY item_id, acquisition_method_id'),
|
itemAcquisitionMethods: await tableRows(client, 'SELECT * FROM item_acquisition_methods ORDER BY item_id, acquisition_method_id'),
|
||||||
itemFavoriteThings: await tableRows(client, 'SELECT * FROM item_favorite_things ORDER BY item_id, favorite_thing_id'),
|
itemFavoriteThings: await tableRows(client, 'SELECT * FROM item_favorite_things ORDER BY item_id, favorite_thing_id'),
|
||||||
pokemonSkillItemDrops: await tableRows(client, 'SELECT * FROM pokemon_skill_item_drops ORDER BY pokemon_id, skill_id'),
|
pokemonSkillItemDrops: await tableRows(client, 'SELECT * FROM pokemon_skill_item_drops ORDER BY pokemon_id, skill_id'),
|
||||||
@@ -7912,7 +7885,7 @@ async function exportScopeData(client: DbClient, scope: DataToolScope): Promise<
|
|||||||
|
|
||||||
if (scope === 'artifacts') {
|
if (scope === 'artifacts') {
|
||||||
return {
|
return {
|
||||||
artifacts: await tableRows(client, 'SELECT * FROM ancient_artifacts ORDER BY display_id, sort_order, id'),
|
artifacts: await tableRows(client, 'SELECT * FROM ancient_artifacts ORDER BY sort_order, id'),
|
||||||
artifactFavoriteThings: await tableRows(
|
artifactFavoriteThings: await tableRows(
|
||||||
client,
|
client,
|
||||||
'SELECT * FROM ancient_artifact_favorite_things ORDER BY ancient_artifact_id, favorite_thing_id'
|
'SELECT * FROM ancient_artifact_favorite_things ORDER BY ancient_artifact_id, favorite_thing_id'
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ const changeLabelKeys: Record<string, string> = {
|
|||||||
标题: 'pages.checklist.task',
|
标题: 'pages.checklist.task',
|
||||||
'Pokemon ID': 'pages.pokemon.id',
|
'Pokemon ID': 'pages.pokemon.id',
|
||||||
'Pokopia ID': 'pages.pokemon.id',
|
'Pokopia ID': 'pages.pokemon.id',
|
||||||
'Display ID': 'pages.items.displayId',
|
|
||||||
'Event item': 'common.eventItem',
|
'Event item': 'common.eventItem',
|
||||||
'Event Pokemon': 'pages.pokemon.eventItem',
|
'Event Pokemon': 'pages.pokemon.eventItem',
|
||||||
'Event Habitat': 'pages.habitats.eventItem',
|
'Event Habitat': 'pages.habitats.eventItem',
|
||||||
@@ -118,12 +117,17 @@ function changeValue(value: string): string {
|
|||||||
return values[value] ?? value;
|
return values[value] ?? value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function visibleChanges(entry: EditHistoryEntry) {
|
||||||
|
return entry.changes.filter((change) => change.label !== 'Display ID');
|
||||||
|
}
|
||||||
|
|
||||||
function historySummary(entry: EditHistoryEntry): string {
|
function historySummary(entry: EditHistoryEntry): string {
|
||||||
if (!entry.changes.length) {
|
const changes = visibleChanges(entry);
|
||||||
|
if (!changes.length) {
|
||||||
return actionLabel(entry.action);
|
return actionLabel(entry.action);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry.changes.map((change) => changeLabel(change.label)).join(locale.value === 'zh-CN' ? '、' : ', ');
|
return changes.map((change) => changeLabel(change.label)).join(locale.value === 'zh-CN' ? '、' : ', ');
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDateTime(value: string): string {
|
function formatDateTime(value: string): string {
|
||||||
@@ -175,8 +179,8 @@ function formatDateTime(value: string): string {
|
|||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
<div class="edit-history-entry__content">
|
<div class="edit-history-entry__content">
|
||||||
<dl v-if="entry.changes.length" class="edit-change-list">
|
<dl v-if="visibleChanges(entry).length" class="edit-change-list">
|
||||||
<div v-for="change in entry.changes" :key="`${change.label}-${change.before}-${change.after}`">
|
<div v-for="change in visibleChanges(entry)" :key="`${change.label}-${change.before}-${change.after}`">
|
||||||
<dt>{{ changeLabel(change.label) }}</dt>
|
<dt>{{ changeLabel(change.label) }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<span class="edit-change-list__label">{{ t('history.before') }}</span>
|
<span class="edit-change-list__label">{{ t('history.before') }}</span>
|
||||||
|
|||||||
@@ -246,7 +246,6 @@ export interface HabitatUsage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RecipeResultItem extends NamedEntity {
|
export interface RecipeResultItem extends NamedEntity {
|
||||||
displayId: number;
|
|
||||||
image?: EntityImage | null;
|
image?: EntityImage | null;
|
||||||
category?: NamedEntity;
|
category?: NamedEntity;
|
||||||
usage?: NamedEntity | null;
|
usage?: NamedEntity | null;
|
||||||
@@ -254,7 +253,6 @@ export interface RecipeResultItem extends NamedEntity {
|
|||||||
|
|
||||||
export interface Item extends EditInfo {
|
export interface Item extends EditInfo {
|
||||||
id: number;
|
id: number;
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
baseName?: string;
|
baseName?: string;
|
||||||
details: string;
|
details: string;
|
||||||
@@ -276,7 +274,6 @@ export interface Item extends EditInfo {
|
|||||||
|
|
||||||
export interface AncientArtifact extends EditInfo {
|
export interface AncientArtifact extends EditInfo {
|
||||||
id: number;
|
id: number;
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
baseName?: string;
|
baseName?: string;
|
||||||
details: string;
|
details: string;
|
||||||
@@ -312,7 +309,6 @@ export interface Recipe extends EditInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemLink extends NamedEntity {
|
export interface ItemLink extends NamedEntity {
|
||||||
displayId: number;
|
|
||||||
image?: EntityImage | null;
|
image?: EntityImage | null;
|
||||||
category?: NamedEntity;
|
category?: NamedEntity;
|
||||||
}
|
}
|
||||||
@@ -791,7 +787,6 @@ export interface PokemonImageOptionsResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemPayload {
|
export interface ItemPayload {
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
details: string;
|
details: string;
|
||||||
translations?: TranslationMap;
|
translations?: TranslationMap;
|
||||||
@@ -808,7 +803,6 @@ export interface ItemPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AncientArtifactPayload {
|
export interface AncientArtifactPayload {
|
||||||
displayId: number;
|
|
||||||
name: string;
|
name: string;
|
||||||
details: string;
|
details: string;
|
||||||
translations?: TranslationMap;
|
translations?: TranslationMap;
|
||||||
|
|||||||
@@ -448,15 +448,15 @@ const configLabel = (item: EditableConfig) => item.name;
|
|||||||
const pokemonKey = (item: Pokemon) => item.id;
|
const pokemonKey = (item: Pokemon) => item.id;
|
||||||
const pokemonLabel = (item: Pokemon) => `#${item.displayId} ${item.name}`;
|
const pokemonLabel = (item: Pokemon) => `#${item.displayId} ${item.name}`;
|
||||||
const itemKey = (item: Item) => item.id;
|
const itemKey = (item: Item) => item.id;
|
||||||
const itemLabel = (item: Item) => `#${item.displayId} ${item.name}`;
|
const itemLabel = (item: Item) => item.name;
|
||||||
const ancientArtifactKey = (item: AncientArtifact) => item.id;
|
const ancientArtifactKey = (item: AncientArtifact) => item.id;
|
||||||
const ancientArtifactLabel = (item: AncientArtifact) => `#${item.displayId} ${item.name}`;
|
const ancientArtifactLabel = (item: AncientArtifact) => item.name;
|
||||||
const recipeKey = (item: Recipe) => item.id;
|
const recipeKey = (item: Recipe) => item.id;
|
||||||
const recipeLabel = (item: Recipe) => item.name;
|
const recipeLabel = (item: Recipe) => item.name;
|
||||||
const dishCategoryKey = (item: DishCategory) => item.id;
|
const dishCategoryKey = (item: DishCategory) => item.id;
|
||||||
const dishCategoryLabel = (item: DishCategory) => item.name;
|
const dishCategoryLabel = (item: DishCategory) => item.name;
|
||||||
const dishKey = (item: Dish) => item.id;
|
const dishKey = (item: Dish) => item.id;
|
||||||
const dishLabel = (item: Dish) => `#${item.item.displayId} ${item.item.name}`;
|
const dishLabel = (item: Dish) => item.item.name;
|
||||||
const habitatKey = (item: Habitat) => item.id;
|
const habitatKey = (item: Habitat) => item.id;
|
||||||
const habitatLabel = (item: Habitat) => item.name;
|
const habitatLabel = (item: Habitat) => item.name;
|
||||||
|
|
||||||
@@ -2260,7 +2260,7 @@ onMounted(() => {
|
|||||||
@reorder="persistItemOrder"
|
@reorder="persistItemOrder"
|
||||||
>
|
>
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<RouterLink :to="`/items/${item.id}`">#{{ item.displayId }} {{ item.name }}</RouterLink>
|
<RouterLink :to="`/items/${item.id}`">{{ item.name }}</RouterLink>
|
||||||
<span class="row-actions">
|
<span class="row-actions">
|
||||||
<button v-if="can('items.delete')" type="button" :disabled="busy" @click="removeItem(item.id)">
|
<button v-if="can('items.delete')" type="button" :disabled="busy" @click="removeItem(item.id)">
|
||||||
<Icon :icon="iconDelete" class="ui-icon" aria-hidden="true" />
|
<Icon :icon="iconDelete" class="ui-icon" aria-hidden="true" />
|
||||||
@@ -2288,7 +2288,7 @@ onMounted(() => {
|
|||||||
@reorder="persistAncientArtifactOrder"
|
@reorder="persistAncientArtifactOrder"
|
||||||
>
|
>
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<RouterLink :to="`/ancient-artifacts/${item.id}`">#{{ item.displayId }} {{ item.name }}</RouterLink>
|
<RouterLink :to="`/ancient-artifacts/${item.id}`">{{ item.name }}</RouterLink>
|
||||||
<span class="row-actions">
|
<span class="row-actions">
|
||||||
<button v-if="can('ancient-artifacts.delete')" type="button" :disabled="busy" @click="removeAncientArtifact(item.id)">
|
<button v-if="can('ancient-artifacts.delete')" type="button" :disabled="busy" @click="removeAncientArtifact(item.id)">
|
||||||
<Icon :icon="iconDelete" class="ui-icon" aria-hidden="true" />
|
<Icon :icon="iconDelete" class="ui-icon" aria-hidden="true" />
|
||||||
@@ -2389,7 +2389,7 @@ onMounted(() => {
|
|||||||
@reorder="persistDishOrder"
|
@reorder="persistDishOrder"
|
||||||
>
|
>
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<RouterLink :to="`/items/${item.item.id}`">#{{ item.item.displayId }} {{ item.item.name }}</RouterLink>
|
<RouterLink :to="`/items/${item.item.id}`">{{ item.item.name }}</RouterLink>
|
||||||
<span class="meta-line">{{ item.category.name }} / {{ item.flavor.name }}</span>
|
<span class="meta-line">{{ item.category.name }} / {{ item.flavor.name }}</span>
|
||||||
<span class="row-actions">
|
<span class="row-actions">
|
||||||
<button v-if="can('dish.update')" type="button" :disabled="busy" @click="editDish(item)">
|
<button v-if="can('dish.update')" type="button" :disabled="busy" @click="editDish(item)">
|
||||||
@@ -2658,7 +2658,7 @@ onMounted(() => {
|
|||||||
<label for="dish-category-cookware">{{ t('pages.dish.cookware') }}</label>
|
<label for="dish-category-cookware">{{ t('pages.dish.cookware') }}</label>
|
||||||
<select id="dish-category-cookware" v-model="dishCategoryForm.cookwareItemId" required>
|
<select id="dish-category-cookware" v-model="dishCategoryForm.cookwareItemId" required>
|
||||||
<option value="">{{ t('common.none') }}</option>
|
<option value="">{{ t('common.none') }}</option>
|
||||||
<option v-for="item in dishItemRows" :key="`cookware-${item.id}`" :value="String(item.id)">#{{ item.displayId }} {{ item.name }}</option>
|
<option v-for="item in dishItemRows" :key="`cookware-${item.id}`" :value="String(item.id)">{{ item.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
@@ -2669,7 +2669,7 @@ onMounted(() => {
|
|||||||
<label for="dish-category-main-material">{{ t('pages.dish.mainMaterial') }}</label>
|
<label for="dish-category-main-material">{{ t('pages.dish.mainMaterial') }}</label>
|
||||||
<select id="dish-category-main-material" v-model="dishCategoryForm.mainMaterialItemId" required>
|
<select id="dish-category-main-material" v-model="dishCategoryForm.mainMaterialItemId" required>
|
||||||
<option value="">{{ t('common.none') }}</option>
|
<option value="">{{ t('common.none') }}</option>
|
||||||
<option v-for="item in dishItemRows" :key="`category-main-material-${item.id}`" :value="String(item.id)">#{{ item.displayId }} {{ item.name }}</option>
|
<option v-for="item in dishItemRows" :key="`category-main-material-${item.id}`" :value="String(item.id)">{{ item.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -2710,7 +2710,7 @@ onMounted(() => {
|
|||||||
<label for="dish-item">{{ t('pages.dish.dishItem') }}</label>
|
<label for="dish-item">{{ t('pages.dish.dishItem') }}</label>
|
||||||
<select id="dish-item" v-model="dishForm.itemId" required>
|
<select id="dish-item" v-model="dishForm.itemId" required>
|
||||||
<option value="">{{ t('common.none') }}</option>
|
<option value="">{{ t('common.none') }}</option>
|
||||||
<option v-for="item in dishItemRows" :key="`dish-item-${item.id}`" :value="String(item.id)">#{{ item.displayId }} {{ item.name }}</option>
|
<option v-for="item in dishItemRows" :key="`dish-item-${item.id}`" :value="String(item.id)">{{ item.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
@@ -2726,14 +2726,14 @@ onMounted(() => {
|
|||||||
<label for="dish-secondary-material-1">{{ t('pages.dish.secondaryMaterial') }}</label>
|
<label for="dish-secondary-material-1">{{ t('pages.dish.secondaryMaterial') }}</label>
|
||||||
<select id="dish-secondary-material-1" v-model="dishForm.secondaryMaterialItemIds[0]">
|
<select id="dish-secondary-material-1" v-model="dishForm.secondaryMaterialItemIds[0]">
|
||||||
<option value="">{{ t('common.none') }}</option>
|
<option value="">{{ t('common.none') }}</option>
|
||||||
<option v-for="item in dishItemRows" :key="`dish-secondary-material-1-${item.id}`" :value="String(item.id)">#{{ item.displayId }} {{ item.name }}</option>
|
<option v-for="item in dishItemRows" :key="`dish-secondary-material-1-${item.id}`" :value="String(item.id)">{{ item.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="dishAllowsSecondSecondaryMaterial" class="field">
|
<div v-if="dishAllowsSecondSecondaryMaterial" class="field">
|
||||||
<label for="dish-secondary-material-2">{{ t('pages.dish.secondSecondaryMaterial') }}</label>
|
<label for="dish-secondary-material-2">{{ t('pages.dish.secondSecondaryMaterial') }}</label>
|
||||||
<select id="dish-secondary-material-2" v-model="dishForm.secondaryMaterialItemIds[1]">
|
<select id="dish-secondary-material-2" v-model="dishForm.secondaryMaterialItemIds[1]">
|
||||||
<option value="">{{ t('common.none') }}</option>
|
<option value="">{{ t('common.none') }}</option>
|
||||||
<option v-for="item in dishItemRows" :key="`dish-secondary-material-2-${item.id}`" :value="String(item.id)">#{{ item.displayId }} {{ item.name }}</option>
|
<option v-for="item in dishItemRows" :key="`dish-secondary-material-2-${item.id}`" :value="String(item.id)">{{ item.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ watch(
|
|||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
<section v-else class="page-stack">
|
<section v-else class="page-stack">
|
||||||
<PageHeader :title="`#${artifact.displayId} ${artifact.name}`" :subtitle="artifact.category.name">
|
<PageHeader :title="artifact.name" :subtitle="artifact.category.name">
|
||||||
<template #kicker>{{ t('pages.ancientArtifacts.detailKicker') }}</template>
|
<template #kicker>{{ t('pages.ancientArtifacts.detailKicker') }}</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<RouterLink v-if="canUpdateArtifact" class="ui-button ui-button--primary ui-button--small" :to="`/ancient-artifacts/${artifact.id}/edit`">
|
<RouterLink v-if="canUpdateArtifact" class="ui-button ui-button--primary ui-button--small" :to="`/ancient-artifacts/${artifact.id}/edit`">
|
||||||
@@ -116,10 +116,6 @@ watch(
|
|||||||
<div v-if="detailTab === 'details'" class="detail-grid">
|
<div v-if="detailTab === 'details'" class="detail-grid">
|
||||||
<DetailSection :title="t('common.details')">
|
<DetailSection :title="t('common.details')">
|
||||||
<dl class="entity-profile-facts">
|
<dl class="entity-profile-facts">
|
||||||
<div>
|
|
||||||
<dt>{{ t('pages.ancientArtifacts.displayId') }}</dt>
|
|
||||||
<dd>#{{ artifact.displayId }}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<dt>{{ t('pages.ancientArtifacts.category') }}</dt>
|
<dt>{{ t('pages.ancientArtifacts.category') }}</dt>
|
||||||
<dd>{{ artifact.category.name }}</dd>
|
<dd>{{ artifact.category.name }}</dd>
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ const busy = ref(false);
|
|||||||
const message = ref('');
|
const message = ref('');
|
||||||
const creatingSelect = ref('');
|
const creatingSelect = ref('');
|
||||||
const artifactForm = ref({
|
const artifactForm = ref({
|
||||||
displayId: 1,
|
|
||||||
name: '',
|
name: '',
|
||||||
details: '',
|
details: '',
|
||||||
translations: {} as TranslationMap,
|
translations: {} as TranslationMap,
|
||||||
@@ -98,7 +97,6 @@ async function loadEditor() {
|
|||||||
if (isEditing.value) {
|
if (isEditing.value) {
|
||||||
const artifact = await api.ancientArtifactDetail(routeId.value);
|
const artifact = await api.ancientArtifactDetail(routeId.value);
|
||||||
artifactForm.value = {
|
artifactForm.value = {
|
||||||
displayId: artifact.displayId,
|
|
||||||
name: artifact.baseName ?? artifact.name,
|
name: artifact.baseName ?? artifact.name,
|
||||||
details: artifact.baseDetails ?? artifact.details,
|
details: artifact.baseDetails ?? artifact.details,
|
||||||
translations: artifact.translations ?? {},
|
translations: artifact.translations ?? {},
|
||||||
@@ -142,7 +140,6 @@ async function saveArtifact() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const payload: AncientArtifactPayload = {
|
const payload: AncientArtifactPayload = {
|
||||||
displayId: artifactForm.value.displayId,
|
|
||||||
name: artifactNameForSave(),
|
name: artifactNameForSave(),
|
||||||
details: artifactForm.value.details,
|
details: artifactForm.value.details,
|
||||||
translations: artifactForm.value.translations,
|
translations: artifactForm.value.translations,
|
||||||
@@ -190,11 +187,6 @@ onMounted(() => {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<label for="artifact-display-id">{{ t('pages.ancientArtifacts.displayId') }}</label>
|
|
||||||
<input id="artifact-display-id" v-model.number="artifactForm.displayId" type="number" min="1" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<TranslationFields
|
<TranslationFields
|
||||||
id-prefix="artifact-details"
|
id-prefix="artifact-details"
|
||||||
v-model:base-value="artifactForm.details"
|
v-model:base-value="artifactForm.details"
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ watch(artifactQuery, loadArtifacts);
|
|||||||
<EntityCard
|
<EntityCard
|
||||||
v-for="artifact in artifacts"
|
v-for="artifact in artifacts"
|
||||||
:key="artifact.id"
|
:key="artifact.id"
|
||||||
:title="`#${artifact.displayId} ${artifact.name}`"
|
:title="artifact.name"
|
||||||
:subtitle="artifact.category.name"
|
:subtitle="artifact.category.name"
|
||||||
:to="`/ancient-artifacts/${artifact.id}`"
|
:to="`/ancient-artifacts/${artifact.id}`"
|
||||||
:icon="iconArtifact"
|
:icon="iconArtifact"
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const dishCategoryModalTitle = computed(() =>
|
|||||||
);
|
);
|
||||||
const dishModalTitle = computed(() => (dishForm.value.id ? t('pages.dish.editDish') : t('pages.dish.newDish')));
|
const dishModalTitle = computed(() => (dishForm.value.id ? t('pages.dish.editDish') : t('pages.dish.newDish')));
|
||||||
const itemSelectOptions = computed<TagsSelectOption[]>(() =>
|
const itemSelectOptions = computed<TagsSelectOption[]>(() =>
|
||||||
items.value.map((item) => ({ id: item.id, name: item.name, label: `#${item.displayId} ${item.name}` }))
|
items.value.map((item) => ({ id: item.id, name: item.name }))
|
||||||
);
|
);
|
||||||
const optionalItemSelectOptions = computed<TagsSelectOption[]>(() => [{ id: '', name: t('common.none') }, ...itemSelectOptions.value]);
|
const optionalItemSelectOptions = computed<TagsSelectOption[]>(() => [{ id: '', name: t('common.none') }, ...itemSelectOptions.value]);
|
||||||
const categorySelectOptions = computed<TagsSelectOption[]>(() => categories.value.map((category) => ({ id: category.id, name: category.name })));
|
const categorySelectOptions = computed<TagsSelectOption[]>(() => categories.value.map((category) => ({ id: category.id, name: category.name })));
|
||||||
@@ -373,7 +373,7 @@ onMounted(loadPage);
|
|||||||
<div>
|
<div>
|
||||||
<dt>{{ t('pages.dish.cookware') }}</dt>
|
<dt>{{ t('pages.dish.cookware') }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<RouterLink :to="`/items/${activeCategory.cookware.id}`">#{{ activeCategory.cookware.displayId }} {{ activeCategory.cookware.name }}</RouterLink>
|
<RouterLink :to="`/items/${activeCategory.cookware.id}`">{{ activeCategory.cookware.name }}</RouterLink>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -383,7 +383,7 @@ onMounted(loadPage);
|
|||||||
<div>
|
<div>
|
||||||
<dt>{{ t('pages.dish.mainMaterial') }}</dt>
|
<dt>{{ t('pages.dish.mainMaterial') }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<RouterLink :to="`/items/${activeCategory.mainMaterial.id}`">#{{ activeCategory.mainMaterial.displayId }} {{ activeCategory.mainMaterial.name }}</RouterLink>
|
<RouterLink :to="`/items/${activeCategory.mainMaterial.id}`">{{ activeCategory.mainMaterial.name }}</RouterLink>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
@@ -411,7 +411,7 @@ onMounted(loadPage);
|
|||||||
<Icon v-else :icon="iconItem" class="entity-card__icon" aria-hidden="true" />
|
<Icon v-else :icon="iconItem" class="entity-card__icon" aria-hidden="true" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<div class="dish-card__content">
|
<div class="dish-card__content">
|
||||||
<RouterLink class="dish-card__title" :to="`/items/${dish.item.id}`">#{{ dish.item.displayId }} {{ dish.item.name }}</RouterLink>
|
<RouterLink class="dish-card__title" :to="`/items/${dish.item.id}`">{{ dish.item.name }}</RouterLink>
|
||||||
<div class="dish-card__meta">
|
<div class="dish-card__meta">
|
||||||
<span>{{ dish.flavor.name }}</span>
|
<span>{{ dish.flavor.name }}</span>
|
||||||
<span v-if="dish.pokemonSkill">{{ dish.pokemonSkill.name }}</span>
|
<span v-if="dish.pokemonSkill">{{ dish.pokemonSkill.name }}</span>
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ watch(
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section v-else class="page-stack">
|
<section v-else class="page-stack">
|
||||||
<PageHeader :title="`#${item.displayId} ${item.name}`" :subtitle="itemSubtitle">
|
<PageHeader :title="item.name" :subtitle="itemSubtitle">
|
||||||
<template #kicker>{{ detailKicker }}</template>
|
<template #kicker>{{ detailKicker }}</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<RouterLink v-if="canUpdateItem" class="ui-button ui-button--primary ui-button--small" :to="`/items/${item.id}/edit`">
|
<RouterLink v-if="canUpdateItem" class="ui-button ui-button--primary ui-button--small" :to="`/items/${item.id}/edit`">
|
||||||
@@ -182,10 +182,6 @@ watch(
|
|||||||
<div class="entity-profile-main">
|
<div class="entity-profile-main">
|
||||||
<section class="detail-section entity-profile-overview" :aria-label="t('common.details')">
|
<section class="detail-section entity-profile-overview" :aria-label="t('common.details')">
|
||||||
<dl class="entity-profile-facts">
|
<dl class="entity-profile-facts">
|
||||||
<div>
|
|
||||||
<dt>{{ t('pages.items.displayId') }}</dt>
|
|
||||||
<dd>#{{ item.displayId }}</dd>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<dt>{{ t('pages.items.category') }}</dt>
|
<dt>{{ t('pages.items.category') }}</dt>
|
||||||
<dd>{{ item.category.name }}</dd>
|
<dd>{{ item.category.name }}</dd>
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ const busy = ref(false);
|
|||||||
const message = ref('');
|
const message = ref('');
|
||||||
const creatingSelect = ref('');
|
const creatingSelect = ref('');
|
||||||
const itemForm = ref({
|
const itemForm = ref({
|
||||||
displayId: 1,
|
|
||||||
name: '',
|
name: '',
|
||||||
details: '',
|
details: '',
|
||||||
translations: {} as TranslationMap,
|
translations: {} as TranslationMap,
|
||||||
@@ -117,7 +116,6 @@ async function loadEditor() {
|
|||||||
if (isEditing.value) {
|
if (isEditing.value) {
|
||||||
const item = await api.itemDetail(routeId.value);
|
const item = await api.itemDetail(routeId.value);
|
||||||
itemForm.value = {
|
itemForm.value = {
|
||||||
displayId: item.displayId,
|
|
||||||
name: item.baseName ?? item.name,
|
name: item.baseName ?? item.name,
|
||||||
details: item.baseDetails ?? item.details,
|
details: item.baseDetails ?? item.details,
|
||||||
translations: item.translations ?? {},
|
translations: item.translations ?? {},
|
||||||
@@ -173,7 +171,6 @@ async function saveItem() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const payload: ItemPayload = {
|
const payload: ItemPayload = {
|
||||||
displayId: itemForm.value.displayId,
|
|
||||||
name: itemNameForSave(),
|
name: itemNameForSave(),
|
||||||
details: itemForm.value.details,
|
details: itemForm.value.details,
|
||||||
translations: itemForm.value.translations,
|
translations: itemForm.value.translations,
|
||||||
@@ -226,11 +223,6 @@ onMounted(() => {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<label for="item-display-id">{{ t('pages.items.displayId') }}</label>
|
|
||||||
<input id="item-display-id" v-model.number="itemForm.displayId" type="number" min="1" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<TranslationFields
|
<TranslationFields
|
||||||
id-prefix="item-details"
|
id-prefix="item-details"
|
||||||
v-model:base-value="itemForm.details"
|
v-model:base-value="itemForm.details"
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ watch(itemQuery, loadItems);
|
|||||||
<EntityCard
|
<EntityCard
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:title="`#${item.displayId} ${item.name}`"
|
:title="item.name"
|
||||||
:subtitle="item.category.name"
|
:subtitle="item.category.name"
|
||||||
:to="`/items/${item.id}`"
|
:to="`/items/${item.id}`"
|
||||||
:icon="iconItem"
|
:icon="iconItem"
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ watch(
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section v-else class="page-stack">
|
<section v-else class="page-stack">
|
||||||
<PageHeader :title="`#${recipe.item.displayId} ${recipe.name}`" :subtitle="recipeSubtitle">
|
<PageHeader :title="recipe.name" :subtitle="recipeSubtitle">
|
||||||
<template #kicker>{{ t('pages.recipes.detailKicker') }}</template>
|
<template #kicker>{{ t('pages.recipes.detailKicker') }}</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<RouterLink v-if="canUpdateRecipe" class="ui-button ui-button--primary ui-button--small" :to="`/recipes/${recipe.id}/edit`">
|
<RouterLink v-if="canUpdateRecipe" class="ui-button ui-button--primary ui-button--small" :to="`/recipes/${recipe.id}/edit`">
|
||||||
@@ -145,7 +145,7 @@ watch(
|
|||||||
<Icon :icon="iconRecipe" class="entity-card__icon" aria-hidden="true" />
|
<Icon :icon="iconRecipe" class="entity-card__icon" aria-hidden="true" />
|
||||||
</span>
|
</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink class="entity-profile-title-link" :to="`/items/${recipe.item.id}`">#{{ recipe.item.displayId }} {{ recipe.item.name }}</RouterLink>
|
<RouterLink class="entity-profile-title-link" :to="`/items/${recipe.item.id}`">{{ recipe.item.name }}</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ watch(itemQuery, loadItems);
|
|||||||
<EntityCard
|
<EntityCard
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:title="`#${item.displayId} ${item.name}`"
|
:title="item.name"
|
||||||
:subtitle="item.category.name"
|
:subtitle="item.category.name"
|
||||||
:to="recipeTarget(item)"
|
:to="recipeTarget(item)"
|
||||||
:icon="itemIcon(item)"
|
:icon="itemIcon(item)"
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ export const systemWordingMessages = {
|
|||||||
},
|
},
|
||||||
eventItems: {
|
eventItems: {
|
||||||
title: 'Event Items',
|
title: 'Event Items',
|
||||||
description: 'Browse limited event items with their own Display IDs and shared item categories.'
|
description: 'Browse limited event items with shared item categories and custom ordering.'
|
||||||
},
|
},
|
||||||
ancientArtifacts: {
|
ancientArtifacts: {
|
||||||
title: 'Ancient Artifacts',
|
title: 'Ancient Artifacts',
|
||||||
@@ -687,7 +687,6 @@ export const systemWordingMessages = {
|
|||||||
loadingList: 'Loading item list',
|
loadingList: 'Loading item list',
|
||||||
loadingDetail: 'Loading item detail',
|
loadingDetail: 'Loading item detail',
|
||||||
loadingEdit: 'Loading item editor',
|
loadingEdit: 'Loading item editor',
|
||||||
displayId: 'Display ID',
|
|
||||||
description: 'Description',
|
description: 'Description',
|
||||||
category: 'Category',
|
category: 'Category',
|
||||||
usage: 'Usage',
|
usage: 'Usage',
|
||||||
@@ -724,14 +723,13 @@ export const systemWordingMessages = {
|
|||||||
detailKicker: 'Ancient Artifact Detail',
|
detailKicker: 'Ancient Artifact Detail',
|
||||||
detailSubtitle: 'Ancient Artifact detail',
|
detailSubtitle: 'Ancient Artifact detail',
|
||||||
editKicker: 'Ancient Artifact Edit',
|
editKicker: 'Ancient Artifact Edit',
|
||||||
editSubtitle: 'Maintain Ancient Artifact Display ID, image, description, category, tags, and translations.',
|
editSubtitle: 'Maintain Ancient Artifact image, description, category, tags, and translations.',
|
||||||
newTitle: 'New Ancient Artifact',
|
newTitle: 'New Ancient Artifact',
|
||||||
editTitle: 'Edit {name}',
|
editTitle: 'Edit {name}',
|
||||||
fallbackName: 'Ancient Artifact',
|
fallbackName: 'Ancient Artifact',
|
||||||
loadingList: 'Loading Ancient Artifact list',
|
loadingList: 'Loading Ancient Artifact list',
|
||||||
loadingDetail: 'Loading Ancient Artifact detail',
|
loadingDetail: 'Loading Ancient Artifact detail',
|
||||||
loadingEdit: 'Loading Ancient Artifact editor',
|
loadingEdit: 'Loading Ancient Artifact editor',
|
||||||
displayId: 'Display ID',
|
|
||||||
description: 'Description',
|
description: 'Description',
|
||||||
category: 'Category',
|
category: 'Category',
|
||||||
tags: 'Tags',
|
tags: 'Tags',
|
||||||
@@ -1311,11 +1309,9 @@ export const systemWordingMessages = {
|
|||||||
environmentRequired: 'Ideal Habitat is required',
|
environmentRequired: 'Ideal Habitat is required',
|
||||||
skillNoDrop: 'This speciality cannot have a drop item',
|
skillNoDrop: 'This speciality cannot have a drop item',
|
||||||
habitatNameRequired: 'Habitat name is required',
|
habitatNameRequired: 'Habitat name is required',
|
||||||
itemDisplayIdRequired: 'Item Display ID is required',
|
|
||||||
usageRequired: 'Usage is required',
|
usageRequired: 'Usage is required',
|
||||||
itemNameRequired: 'Item name is required',
|
itemNameRequired: 'Item name is required',
|
||||||
categoryRequired: 'Category is required',
|
categoryRequired: 'Category is required',
|
||||||
artifactDisplayIdRequired: 'Ancient Artifact Display ID is required',
|
|
||||||
artifactNameRequired: 'Ancient Artifact name is required',
|
artifactNameRequired: 'Ancient Artifact name is required',
|
||||||
recipeFreeWithRecipe: 'An item with a recipe cannot be marked as recipe-free',
|
recipeFreeWithRecipe: 'An item with a recipe cannot be marked as recipe-free',
|
||||||
itemRequired: 'Item is required',
|
itemRequired: 'Item is required',
|
||||||
@@ -1600,7 +1596,7 @@ export const systemWordingMessages = {
|
|||||||
},
|
},
|
||||||
eventItems: {
|
eventItems: {
|
||||||
title: 'Event Items',
|
title: 'Event Items',
|
||||||
description: '浏览限时活动物品,并维护独立的 Display ID 与共享分类。'
|
description: '浏览限时活动物品、共享分类与自定义排序。'
|
||||||
},
|
},
|
||||||
ancientArtifacts: {
|
ancientArtifacts: {
|
||||||
title: 'Ancient Artifacts',
|
title: 'Ancient Artifacts',
|
||||||
@@ -2022,7 +2018,6 @@ export const systemWordingMessages = {
|
|||||||
loadingList: '正在加载列表',
|
loadingList: '正在加载列表',
|
||||||
loadingDetail: '正在加载物品详情',
|
loadingDetail: '正在加载物品详情',
|
||||||
loadingEdit: '正在加载物品编辑内容',
|
loadingEdit: '正在加载物品编辑内容',
|
||||||
displayId: 'Display ID',
|
|
||||||
description: '介绍',
|
description: '介绍',
|
||||||
category: '分类',
|
category: '分类',
|
||||||
usage: '用途',
|
usage: '用途',
|
||||||
@@ -2059,14 +2054,13 @@ export const systemWordingMessages = {
|
|||||||
detailKicker: 'Ancient Artifact Detail',
|
detailKicker: 'Ancient Artifact Detail',
|
||||||
detailSubtitle: 'Ancient Artifact 详情',
|
detailSubtitle: 'Ancient Artifact 详情',
|
||||||
editKicker: 'Ancient Artifact Edit',
|
editKicker: 'Ancient Artifact Edit',
|
||||||
editSubtitle: '维护 Ancient Artifact Display ID、图片、介绍、分类、标签和翻译。',
|
editSubtitle: '维护 Ancient Artifact 图片、介绍、分类、标签和翻译。',
|
||||||
newTitle: '新增 Ancient Artifact',
|
newTitle: '新增 Ancient Artifact',
|
||||||
editTitle: '编辑 {name}',
|
editTitle: '编辑 {name}',
|
||||||
fallbackName: 'Ancient Artifact',
|
fallbackName: 'Ancient Artifact',
|
||||||
loadingList: '正在加载 Ancient Artifact 列表',
|
loadingList: '正在加载 Ancient Artifact 列表',
|
||||||
loadingDetail: '正在加载 Ancient Artifact 详情',
|
loadingDetail: '正在加载 Ancient Artifact 详情',
|
||||||
loadingEdit: '正在加载 Ancient Artifact 编辑内容',
|
loadingEdit: '正在加载 Ancient Artifact 编辑内容',
|
||||||
displayId: 'Display ID',
|
|
||||||
description: '介绍',
|
description: '介绍',
|
||||||
category: '分类',
|
category: '分类',
|
||||||
tags: '标签',
|
tags: '标签',
|
||||||
@@ -2644,14 +2638,12 @@ export const systemWordingMessages = {
|
|||||||
heightNonNegative: '身高必须是不小于 0 的数字',
|
heightNonNegative: '身高必须是不小于 0 的数字',
|
||||||
weightNonNegative: '体重必须是不小于 0 的数字',
|
weightNonNegative: '体重必须是不小于 0 的数字',
|
||||||
environmentRequired: '请选择喜欢的环境',
|
environmentRequired: '请选择喜欢的环境',
|
||||||
skillNoDrop: '这个特长不能设置掉落物',
|
skillNoDrop: '这个特长不能设置掉落物',
|
||||||
habitatNameRequired: '请输入栖息地名称',
|
habitatNameRequired: '请输入栖息地名称',
|
||||||
itemDisplayIdRequired: '请输入物品 Display ID',
|
usageRequired: '请选择用途',
|
||||||
usageRequired: '请选择用途',
|
itemNameRequired: '请输入物品名称',
|
||||||
itemNameRequired: '请输入物品名称',
|
categoryRequired: '请选择分类',
|
||||||
categoryRequired: '请选择分类',
|
artifactNameRequired: '请输入 Ancient Artifact 名称',
|
||||||
artifactDisplayIdRequired: '请输入 Ancient Artifact Display ID',
|
|
||||||
artifactNameRequired: '请输入 Ancient Artifact 名称',
|
|
||||||
recipeFreeWithRecipe: '已有材料单的物品不能标记为无材料单',
|
recipeFreeWithRecipe: '已有材料单的物品不能标记为无材料单',
|
||||||
itemRequired: '请选择物品',
|
itemRequired: '请选择物品',
|
||||||
recipeFreeItem: '这个物品已标记为无材料单',
|
recipeFreeItem: '这个物品已标记为无材料单',
|
||||||
|
|||||||
Reference in New Issue
Block a user