puyoskey/packages/frontend/src/pages/admin/custom-emojis-manager2.stories.impl.ts
おさむのひと f9ad127aaf
feat: 新カスタム絵文字管理画面(β)の追加 (#13473)
* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* fix

* fix

* fix

* fix size

* fix register logs

* fix img autosize

* fix row selection

* support delete

* fix border rendering

* fix display:none

* tweak comments

* support choose pc file and drive file

* support directory drag-drop

* fix

* fix comment

* support context menu on data area

* fix autogen

* wip イベント整理

* イベントの整理

* refactor grid

* fix cell re-render bugs

* fix row remove

* fix comment

* fix validation

* fix utils

* list maximum

* add mimetype check

* fix

* fix number cell focus

* fix over 100 file drop

* remove log

* fix patchData

* fix performance

* fix

* support update and delete

* support remote import

* fix layout

* heightやめる

* fix performance

* add list v2 endpoint

* support pagination

* fix api call

* fix no clickable input text

* fix limit

* fix paging

* fix

* fix

* support search

* tweak logs

* tweak cell selection

* fix range select

* block delete

* add comment

* fix

* support import log

* fix dialog

* refactor

* add confirm dialog

* fix name

* fix autogen

* wip

* support image change and highlight row

* add columns

* wip

* support sort

* add role name

* add index to emoji

* refine context menu setting

* support role select

* remove unused buttons

* fix url

* fix MkRoleSelectDialog.vue

* add route

* refine remote page

* enter key search

* fix paste bugs

* fix copy/paste

* fix keyEvent

* fix copy/paste and delete

* fix comment

* fix MkRoleSelectDialog.vue and storybook scenario

* fix MkRoleSelectDialog.vue and storybook scenario

* add MkGrid.stories.impl.ts

* fix

* [wip] add custom-emojis-manager2.stories.impl.ts

* [wip] add custom-emojis-manager2.stories.impl.ts

* wip

* 課題はまだ残っているが、ひとまず完了

* fix validation and register roles

* fix upload

* optimize import

* patch from dev

* i18n

* revert excess fixes

* separate sort order component

* add SPDX

* revert excess fixes

* fix pre test

* fix bugs

* add type column

* fix types

* fix CHANGELOG.md

* fix lit

* lint

* tweak style

* refactor

* fix ci

* autogen

* Update types.ts

* CSS Module化

* fix log

* 縦スクロールを無効化

* MkStickyContainer化

* regenerate locales index.d.ts

* fix

* fix

* テスト

* ランダム値によるUI変更の抑制

* テスト

* tableタグやめる

* fix last-child css

* fix overflow css

* fix endpoint.ts

* tweak css

* 最新への追従とレイアウト微調整

* ソートキーの指定方法を他と合わせた

* fix focus

* fix layout

* v2エンドポイントのルールに対応

* 表示条件などを微調整

* fix MkDataCell.vue

* fix error code

* fix error

* add comment to MkModal.vue

* Update index.d.ts

* fix CHANGELOG.md

* fix color theme

* fix CHANGELOG.md

* fix CHANGELOG.md

* fix center

* fix: テーブルにフォーカスがあり、通常状態であるときはキーイベントの伝搬を止める

* fix: ロール選択用のダイアログにてコンディショナルロールを×ボタンで除外できなかったのを修正

* fix remote list folder

* sticky footers

* chore: fix ci error(just single line-break diff)

* fix loading

* fix like

* comma to space

* fix ci

* fix ci

* removed align-center

---------

Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
2025-01-20 11:35:37 +00:00

160 lines
4.5 KiB
TypeScript

/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { delay, http, HttpResponse } from 'msw';
import { StoryObj } from '@storybook/vue3';
import { entities } from 'misskey-js';
import { commonHandlers } from '../../../.storybook/mocks.js';
import { emoji } from '../../../.storybook/fakes.js';
import { fakeId } from '../../../.storybook/fake-utils.js';
import custom_emojis_manager2 from './custom-emojis-manager2.vue';
function createRender(params: {
emojis: entities.EmojiDetailedAdmin[];
}) {
const storedEmojis: entities.EmojiDetailedAdmin[] = [...params.emojis];
const storedDriveFiles: entities.DriveFile[] = [];
return {
render(args) {
return {
components: {
custom_emojis_manager2,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<custom_emojis_manager2 v-bind="props" />',
};
},
args: {
},
parameters: {
layout: 'fullscreen',
msw: {
handlers: [
...commonHandlers,
http.post('/api/v2/admin/emoji/list', async ({ request }) => {
await delay(100);
const bodyStream = request.body as ReadableStream;
const body = await new Response(bodyStream).json() as entities.V2AdminEmojiListRequest;
const emojis = storedEmojis;
const limit = body.limit ?? 10;
const page = body.page ?? 1;
const result = emojis.slice((page - 1) * limit, page * limit);
return HttpResponse.json({
emojis: result,
count: Math.min(emojis.length, limit),
allCount: emojis.length,
allPages: Math.ceil(emojis.length / limit),
});
}),
http.post('/api/drive/folders', () => {
return HttpResponse.json([]);
}),
http.post('/api/drive/files', () => {
return HttpResponse.json(storedDriveFiles);
}),
http.post('/api/drive/files/create', async ({ request }) => {
const data = await request.formData();
const file = data.get('file');
if (!file || !(file instanceof File)) {
return HttpResponse.json({ error: 'file is required' }, {
status: 400,
});
}
// FIXME: ファイルのバイナリに0xEF 0xBF 0xBDが混入してしまい、うまく画像ファイルとして表示できない問題がある
const base64 = await new Promise<string>((resolve) => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result as string);
};
reader.readAsDataURL(new Blob([file], { type: 'image/webp' }));
});
const driveFile: entities.DriveFile = {
id: fakeId(file.name),
createdAt: new Date().toISOString(),
name: file.name,
type: file.type,
md5: '',
size: file.size,
isSensitive: false,
blurhash: null,
properties: {},
url: base64,
thumbnailUrl: null,
comment: null,
folderId: null,
folder: null,
userId: null,
user: null,
};
storedDriveFiles.push(driveFile);
return HttpResponse.json(driveFile);
}),
http.post('api/admin/emoji/add', async ({ request }) => {
await delay(100);
const bodyStream = request.body as ReadableStream;
const body = await new Response(bodyStream).json() as entities.AdminEmojiAddRequest;
const fileId = body.fileId;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const file = storedDriveFiles.find(f => f.id === fileId)!;
const em = emoji({
id: fakeId(file.name),
name: body.name,
publicUrl: file.url,
originalUrl: file.url,
type: file.type,
aliases: body.aliases,
category: body.category ?? undefined,
license: body.license ?? undefined,
localOnly: body.localOnly,
isSensitive: body.isSensitive,
});
storedEmojis.push(em);
return HttpResponse.json(null);
}),
],
},
},
} satisfies StoryObj<typeof custom_emojis_manager2>;
}
export const Default = createRender({
emojis: [],
});
export const List10 = createRender({
emojis: Array.from({ length: 10 }, (_, i) => emoji({ name: `emoji_${i}` }, i.toString())),
});
export const List100 = createRender({
emojis: Array.from({ length: 100 }, (_, i) => emoji({ name: `emoji_${i}` }, i.toString())),
});
export const List1000 = createRender({
emojis: Array.from({ length: 1000 }, (_, i) => emoji({ name: `emoji_${i}` }, i.toString())),
});