From e39ba6286f567bca735928b84c69214d1308a2cc Mon Sep 17 00:00:00 2001 From: samunohito <46447427+samunohito@users.noreply.github.com> Date: Tue, 23 Jan 2024 15:34:52 +0900 Subject: [PATCH] wip --- packages/frontend/package.json | 2 +- .../frontend/src/components/MkMediaList.vue | 2 +- .../components/MkTutorialDialog.PostNote.vue | 2 +- .../components/MkTutorialDialog.Sensitive.vue | 2 +- .../components/MkTutorialDialog.Timeline.vue | 3 +- .../frontend/src/components/grid/MkCell.vue | 26 -- .../src/components/grid/MkDataCell.vue | 304 +++++++++++++++ .../src/components/grid/MkDataRow.vue | 48 +++ .../frontend/src/components/grid/MkGrid.vue | 346 +++++++++++++++--- .../src/components/grid/MkHeaderCell.vue | 195 ++++++++++ .../src/components/grid/MkHeaderRow.vue | 45 +++ .../src/components/grid/MkNumberCell.vue | 46 +++ .../frontend/src/components/grid/MkRow.vue | 23 -- .../frontend/src/components/grid/types.ts | 87 ++++- .../pages/admin/custom-emojis-grid.impl.ts | 17 +- .../src/pages/admin/custom-emojis-grid.vue | 22 +- .../misskey-js/src/autogen/apiClientJSDoc.ts | 4 +- packages/misskey-js/src/autogen/endpoint.ts | 7 +- packages/misskey-js/src/autogen/entities.ts | 5 +- packages/misskey-js/src/autogen/models.ts | 4 +- packages/misskey-js/src/autogen/types.ts | 13 +- packages/misskey-reversi/package.json | 3 +- pnpm-lock.yaml | 15 +- 23 files changed, 1082 insertions(+), 139 deletions(-) delete mode 100644 packages/frontend/src/components/grid/MkCell.vue create mode 100644 packages/frontend/src/components/grid/MkDataCell.vue create mode 100644 packages/frontend/src/components/grid/MkDataRow.vue create mode 100644 packages/frontend/src/components/grid/MkHeaderCell.vue create mode 100644 packages/frontend/src/components/grid/MkHeaderRow.vue create mode 100644 packages/frontend/src/components/grid/MkNumberCell.vue delete mode 100644 packages/frontend/src/components/grid/MkRow.vue diff --git a/packages/frontend/package.json b/packages/frontend/package.json index fd86da79af..106c941483 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -27,7 +27,7 @@ "@syuilo/aiscript": "0.17.0", "@tabler/icons-webfont": "2.44.0", "@twemoji/parser": "15.0.0", - "@vitejs/plugin-vue": "5.0.2", + "@vitejs/plugin-vue": "5.0.3", "@vue/compiler-sfc": "3.4.3", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6", "astring": "1.8.6", diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue index 09c5ad9222..a941e89fc6 100644 --- a/packages/frontend/src/components/MkMediaList.vue +++ b/packages/frontend/src/components/MkMediaList.vue @@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only > - + diff --git a/packages/frontend/src/components/MkTutorialDialog.PostNote.vue b/packages/frontend/src/components/MkTutorialDialog.PostNote.vue index b395f64853..e419843992 100644 --- a/packages/frontend/src/components/MkTutorialDialog.PostNote.vue +++ b/packages/frontend/src/components/MkTutorialDialog.PostNote.vue @@ -90,7 +90,7 @@ const exampleCWNote = reactive({ background: var(--divider); } -.image { +.viewImage { max-width: 300px; margin: 0 auto; } diff --git a/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue b/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue index 896db5eb3a..44a05e5ce9 100644 --- a/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue +++ b/packages/frontend/src/components/MkTutorialDialog.Sensitive.vue @@ -100,7 +100,7 @@ const exampleNote = reactive({ background: var(--divider); } -.image { +.viewImage { max-width: 300px; margin: 0 auto; } diff --git a/packages/frontend/src/components/MkTutorialDialog.Timeline.vue b/packages/frontend/src/components/MkTutorialDialog.Timeline.vue index 93181cf2b1..93826fed7b 100644 --- a/packages/frontend/src/components/MkTutorialDialog.Timeline.vue +++ b/packages/frontend/src/components/MkTutorialDialog.Timeline.vue @@ -22,7 +22,6 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.help }} - @@ -42,7 +41,7 @@ import { i18n } from '@/i18n.js'; background: var(--divider); } -.image { +.viewImage { max-width: 300px; margin: 0 auto; } diff --git a/packages/frontend/src/components/grid/MkCell.vue b/packages/frontend/src/components/grid/MkCell.vue deleted file mode 100644 index e29431c0a2..0000000000 --- a/packages/frontend/src/components/grid/MkCell.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - {{ cell.value }} - - - - - - diff --git a/packages/frontend/src/components/grid/MkDataCell.vue b/packages/frontend/src/components/grid/MkDataCell.vue new file mode 100644 index 0000000000..8d3f71034f --- /dev/null +++ b/packages/frontend/src/components/grid/MkDataCell.vue @@ -0,0 +1,304 @@ + + + + + + + {{ cell.value }} + + + + + + + + + + + + + + + + + + + + diff --git a/packages/frontend/src/components/grid/MkDataRow.vue b/packages/frontend/src/components/grid/MkDataRow.vue new file mode 100644 index 0000000000..393238bdb0 --- /dev/null +++ b/packages/frontend/src/components/grid/MkDataRow.vue @@ -0,0 +1,48 @@ + + + emit('selection:row', sender)" + /> + emit('edit:begin', sender)" + @edit:end="(sender) => emit('edit:end', sender)" + @selection:move="(sender, next) => emit('selection:move', sender, next)" + /> + + + + + + diff --git a/packages/frontend/src/components/grid/MkGrid.vue b/packages/frontend/src/components/grid/MkGrid.vue index a5f82406e8..f4ee5bbfe9 100644 --- a/packages/frontend/src/components/grid/MkGrid.vue +++ b/packages/frontend/src/components/grid/MkGrid.vue @@ -1,23 +1,56 @@ - - - - {{ column.setting.title ?? column.setting.bindTo }} - - - - + + + + + + + + + + diff --git a/packages/frontend/src/components/grid/MkHeaderRow.vue b/packages/frontend/src/components/grid/MkHeaderRow.vue new file mode 100644 index 0000000000..7ff1e25b3e --- /dev/null +++ b/packages/frontend/src/components/grid/MkHeaderRow.vue @@ -0,0 +1,45 @@ + + + + emit('width:begin-change', sender)" + @width:endChange="(sender) => emit('width:end-change', sender)" + @width:changing="(sender, width) => emit('width:changing', sender, width)" + @width:largest="(sender) => emit('width:largest', sender)" + @selection:column="(sender) => emit('selection:column', sender)" + /> + + + + + + diff --git a/packages/frontend/src/components/grid/MkNumberCell.vue b/packages/frontend/src/components/grid/MkNumberCell.vue new file mode 100644 index 0000000000..8b870d68d3 --- /dev/null +++ b/packages/frontend/src/components/grid/MkNumberCell.vue @@ -0,0 +1,46 @@ + + + {{ content }} + + + + + + diff --git a/packages/frontend/src/components/grid/MkRow.vue b/packages/frontend/src/components/grid/MkRow.vue deleted file mode 100644 index 5e25681b7a..0000000000 --- a/packages/frontend/src/components/grid/MkRow.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - diff --git a/packages/frontend/src/components/grid/types.ts b/packages/frontend/src/components/grid/types.ts index 2834255f48..6b26f6bd60 100644 --- a/packages/frontend/src/components/grid/types.ts +++ b/packages/frontend/src/components/grid/types.ts @@ -1,14 +1,38 @@ +import { EventEmitter } from 'eventemitter3'; + export type CellValue = string | boolean | number | undefined | null +export type DataSource = Record; + +export type GridState = 'normal' | 'cellSelecting' | 'cellEditing' | 'colResizing' + +export type RowState = 'normal' | 'added' | 'deleted' + +export type Size = { + width: number; + height: number; +} + +export type SizeStyle = number | 'auto' | undefined; + export type CellAddress = { row: number; col: number; } +export const CELL_ADDRESS_NONE: CellAddress = { + row: -1, + col: -1, +}; + export type GridCell = { address: CellAddress; value: CellValue; - columnSetting: ColumnSetting; + column: GridColumn; + row: GridRow; + selected: boolean; + ranged: boolean; + contentSize: Size; } export type ColumnType = 'text' | 'number' | 'date' | 'boolean' | 'image'; @@ -17,19 +41,70 @@ export type ColumnSetting = { bindTo: string; title?: string; type: ColumnType; - width?: number | 'auto'; + width: SizeStyle; editable?: boolean; }; -export type DataSource = Record; - export type GridColumn = { index: number; setting: ColumnSetting; - cells: GridCell[]; + width: string; + contentSize: Size; } export type GridRow = { index: number; - cells: GridCell[]; +} + +export class GridEventEmitter extends EventEmitter<{}> { +} + +export function isElement(elem: any): elem is HTMLElement { + return elem instanceof HTMLElement; +} + +export function isCellElement(elem: any): elem is HTMLTableCellElement { + return elem instanceof HTMLTableCellElement; +} + +export function isRowElement(elem: any): elem is HTMLTableRowElement { + return elem instanceof HTMLTableRowElement; +} + +export function getCellAddress(elem: HTMLElement, parentNodeCount = 5): CellAddress { + let node = elem; + for (let i = 0; i < parentNodeCount; i++) { + if (isCellElement(node) && isRowElement(node.parentElement)) { + return { + // ヘッダ行ぶんを除く + row: node.parentElement.rowIndex - 1, + // 数値列ぶんを除く + col: node.cellIndex - 1, + }; + } + + if (!node.parentElement) { + break; + } + + node = node.parentElement; + } + + throw new Error('Cannot get cell address'); +} + +export function equalCellAddress(a: CellAddress, b: CellAddress): boolean { + return a.row === b.row && a.col === b.col; +} + +export function calcCellWidth(widthSetting: SizeStyle): string { + switch (widthSetting) { + case undefined: + case 'auto': { + return 'auto'; + } + default: { + return `${widthSetting}px`; + } + } } diff --git a/packages/frontend/src/pages/admin/custom-emojis-grid.impl.ts b/packages/frontend/src/pages/admin/custom-emojis-grid.impl.ts index 64795da57d..8c967f4105 100644 --- a/packages/frontend/src/pages/admin/custom-emojis-grid.impl.ts +++ b/packages/frontend/src/pages/admin/custom-emojis-grid.impl.ts @@ -43,7 +43,18 @@ export class GridItem { } static ofEmojiDetailed(it: Misskey.entities.EmojiDetailed): GridItem { - return new GridItem(it.id, it.url, undefined, it.name, it.category ?? '', it.aliases.join(', '), it.license ?? '', it.isSensitive, it.localOnly, it.roleIdsThatCanBeUsedThisEmojiAsReaction.join(', ')); + return new GridItem( + it.id, + it.url, + undefined, + it.name, + it.category ?? '', + it.aliases.join(', '), + it.license ?? '', + it.isSensitive, + it.localOnly, + it.roleIdsThatCanBeUsedThisEmojiAsReaction.join(', '), + ); } public get edited(): boolean { @@ -51,7 +62,7 @@ export class GridItem { return JSON.stringify(_this) !== origin; } - public asRecord(): Record { - return this as Record; + public asRecord(): Record { + return this as Record; } } diff --git a/packages/frontend/src/pages/admin/custom-emojis-grid.vue b/packages/frontend/src/pages/admin/custom-emojis-grid.vue index 2227d3e8ec..0d1649f96c 100644 --- a/packages/frontend/src/pages/admin/custom-emojis-grid.vue +++ b/packages/frontend/src/pages/admin/custom-emojis-grid.vue @@ -5,14 +5,14 @@ - +