wip
This commit is contained in:
parent
e3240c556a
commit
171b596ac7
|
@ -4,8 +4,8 @@
|
|||
:class="$style.cell"
|
||||
:style="{ maxWidth: cellWidth, minWidth: cellWidth }"
|
||||
:tabindex="-1"
|
||||
@dblclick="onCellDoubleClick"
|
||||
@keydown="onCellKeyDown"
|
||||
@dblclick="onCellDoubleClick"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
|
@ -53,11 +53,13 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { computed, defineAsyncComponent, nextTick, onMounted, onUnmounted, ref, shallowRef, toRefs, watch } from 'vue';
|
||||
import { GridEventEmitter, GridSetting, Size } from '@/components/grid/grid.js';
|
||||
import { GridEventEmitter, Size } from '@/components/grid/grid.js';
|
||||
import { useTooltip } from '@/scripts/use-tooltip.js';
|
||||
import * as os from '@/os.js';
|
||||
import { CellValue, GridCell } from '@/components/grid/cell.js';
|
||||
import { equalCellAddress, getCellAddress } from '@/components/grid/grid-utils.js';
|
||||
import { GridRowSetting } from '@/components/grid/row.js';
|
||||
import { selectFile } from '@/scripts/select-file.js';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'operation:beginEdit', sender: GridCell): void;
|
||||
|
@ -67,7 +69,7 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
const props = defineProps<{
|
||||
cell: GridCell,
|
||||
gridSetting: GridSetting,
|
||||
gridSetting: GridRowSetting,
|
||||
bus: GridEventEmitter,
|
||||
}>();
|
||||
|
||||
|
@ -162,7 +164,7 @@ function unregisterOutsideMouseDown() {
|
|||
removeEventListener('mousedown', onOutsideMouseDown);
|
||||
}
|
||||
|
||||
function beginEditing() {
|
||||
async function beginEditing() {
|
||||
if (editing.value || !cell.value.column.setting.editable) {
|
||||
return;
|
||||
}
|
||||
|
@ -174,7 +176,7 @@ function beginEditing() {
|
|||
registerOutsideMouseDown();
|
||||
emit('operation:beginEdit', cell.value);
|
||||
|
||||
nextTick(() => {
|
||||
await nextTick(() => {
|
||||
// inputの展開後にフォーカスを当てたい
|
||||
if (inputAreaEl.value) {
|
||||
(inputAreaEl.value.querySelector('*') as HTMLElement).focus();
|
||||
|
@ -187,6 +189,13 @@ function beginEditing() {
|
|||
emitValueChange(!cell.value.value);
|
||||
break;
|
||||
}
|
||||
case 'image': {
|
||||
const file = await selectFile(rootEl.value);
|
||||
if (file) {
|
||||
emitValueChange(JSON.stringify(file));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +238,7 @@ useTooltip(rootEl, (showing) => {
|
|||
os.popup(defineAsyncComponent(() => import('@/components/grid/MkCellTooltip.vue')), {
|
||||
showing,
|
||||
content,
|
||||
targetElement: rootEl.value,
|
||||
targetElement: rootEl.value!,
|
||||
}, {}, 'closed');
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
<template>
|
||||
<tr :class="[$style.row, [row.ranged ? $style.ranged : {}]]">
|
||||
<tr
|
||||
:class="[
|
||||
$style.row,
|
||||
row.ranged ? $style.ranged : {},
|
||||
row.additionalStyle?.className ? row.additionalStyle.className : {},
|
||||
]"
|
||||
:style="[
|
||||
row.additionalStyle?.style ? row.additionalStyle.style : {},
|
||||
]"
|
||||
>
|
||||
<MkNumberCell
|
||||
v-if="gridSetting.rowNumberVisible"
|
||||
v-if="gridSetting.showNumber"
|
||||
:content="(row.index + 1).toString()"
|
||||
:row="row"
|
||||
/>
|
||||
|
@ -20,11 +29,11 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GridEventEmitter, GridSetting, Size } from '@/components/grid/grid.js';
|
||||
import { GridEventEmitter, Size } from '@/components/grid/grid.js';
|
||||
import MkDataCell from '@/components/grid/MkDataCell.vue';
|
||||
import MkNumberCell from '@/components/grid/MkNumberCell.vue';
|
||||
import { CellValue, GridCell } from '@/components/grid/cell.js';
|
||||
import { GridRow } from '@/components/grid/row.js';
|
||||
import { GridRow, GridRowSetting } from '@/components/grid/row.js';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'operation:beginEdit', sender: GridCell): void;
|
||||
|
@ -35,7 +44,7 @@ const emit = defineEmits<{
|
|||
defineProps<{
|
||||
row: GridRow,
|
||||
cells: GridCell[],
|
||||
gridSetting: GridSetting,
|
||||
gridSetting: GridRowSetting,
|
||||
bus: GridEventEmitter,
|
||||
}>();
|
||||
|
||||
|
|
|
@ -40,14 +40,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, toRefs, watch } from 'vue';
|
||||
import {
|
||||
DataSource,
|
||||
defaultGridSetting,
|
||||
GridEventEmitter,
|
||||
GridSetting,
|
||||
GridState,
|
||||
Size,
|
||||
} from '@/components/grid/grid.js';
|
||||
import { DataSource, GridEventEmitter, GridState, Size } from '@/components/grid/grid.js';
|
||||
import MkDataRow from '@/components/grid/MkDataRow.vue';
|
||||
import MkHeaderRow from '@/components/grid/MkHeaderRow.vue';
|
||||
import { cellValidation } from '@/components/grid/cell-validators.js';
|
||||
|
@ -56,8 +49,8 @@ import { equalCellAddress, getCellAddress, getCellElement } from '@/components/g
|
|||
import { MenuItem } from '@/types/menu.js';
|
||||
import * as os from '@/os.js';
|
||||
import { GridCurrentState, GridEvent } from '@/components/grid/grid-event.js';
|
||||
import { ColumnSetting, createColumn, GridColumn } from '@/components/grid/column.js';
|
||||
import { createRow, GridRow, resetRow } from '@/components/grid/row.js';
|
||||
import { createColumn, GridColumn, GridColumnSetting } from '@/components/grid/column.js';
|
||||
import { createRow, defaultGridSetting, GridRow, GridRowSetting, resetRow } from '@/components/grid/row.js';
|
||||
|
||||
type RowHolder = {
|
||||
row: GridRow,
|
||||
|
@ -70,13 +63,13 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
|
||||
const props = defineProps<{
|
||||
gridSetting?: GridSetting,
|
||||
columnSettings: ColumnSetting[],
|
||||
gridSetting?: GridRowSetting,
|
||||
columnSettings: GridColumnSetting[],
|
||||
data: DataSource[]
|
||||
}>();
|
||||
|
||||
// non-reactive
|
||||
const gridSetting: Required<GridSetting> = {
|
||||
const gridSetting: Required<GridRowSetting> = {
|
||||
...props.gridSetting,
|
||||
...defaultGridSetting,
|
||||
};
|
||||
|
@ -856,8 +849,7 @@ function emitGridEvent(ev: GridEvent) {
|
|||
emit(
|
||||
'event',
|
||||
ev,
|
||||
// 直接書き換えられると状態が狂う可能性があるのでコピーを渡す
|
||||
JSON.parse(JSON.stringify(currentState)),
|
||||
currentState,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -980,7 +972,7 @@ function expandCellRange(leftTop: CellAddress, rightBottom: CellAddress) {
|
|||
* {@link top}から{@link bottom}までの行を範囲選択状態にする。
|
||||
*/
|
||||
function expandRowRange(top: number, bottom: number) {
|
||||
if (!gridSetting.rowSelectable) {
|
||||
if (!gridSetting.selectable) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1026,9 +1018,9 @@ function refreshData() {
|
|||
}
|
||||
|
||||
const _data: DataSource[] = data.value;
|
||||
const _rows: GridRow[] = (_data.length > gridSetting.rowMinimumDefinitionCount)
|
||||
const _rows: GridRow[] = (_data.length > gridSetting.minimumDefinitionCount)
|
||||
? _data.map((_, index) => createRow(index, true))
|
||||
: Array.from({ length: gridSetting.rowMinimumDefinitionCount }, (_, index) => createRow(index, index < _data.length));
|
||||
: Array.from({ length: gridSetting.minimumDefinitionCount }, (_, index) => createRow(index, index < _data.length));
|
||||
const _cols: GridColumn[] = columns.value;
|
||||
|
||||
// 行・列の定義から、元データの配列より値を取得してセルを作成する。
|
||||
|
@ -1036,11 +1028,11 @@ function refreshData() {
|
|||
const _cells: RowHolder[] = _rows.map(row => {
|
||||
const cells = row.using
|
||||
? _cols.map(col => {
|
||||
const cell = createCell(col, row, _data[row.index][col.setting.bindTo]);
|
||||
const cell = createCell(col, row, _data[row.index][col.setting.bindTo], col.setting.cellSetting ?? {});
|
||||
cell.violation = cellValidation(cell, cell.value);
|
||||
return cell;
|
||||
})
|
||||
: _cols.map(col => createCell(col, row, undefined));
|
||||
: _cols.map(col => createCell(col, row, undefined, col.setting.cellSetting ?? {}));
|
||||
|
||||
return { row, cells, origin: _data[row.index] };
|
||||
});
|
||||
|
@ -1080,7 +1072,7 @@ function patchData(newItems: DataSource[]) {
|
|||
newRows.push(newRow);
|
||||
newCells.push({
|
||||
row: newRow,
|
||||
cells: _cols.map(col => createCell(col, newRow, newItems[rowIdx][col.setting.bindTo])),
|
||||
cells: _cols.map(col => createCell(col, newRow, newItems[rowIdx][col.setting.bindTo], col.setting.cellSetting ?? {})),
|
||||
origin: newItems[rowIdx],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<tr :class="$style.header">
|
||||
<MkNumberCell
|
||||
v-if="gridSetting.rowNumberVisible"
|
||||
v-if="gridSetting.showNumber"
|
||||
content="#"
|
||||
:top="true"
|
||||
/>
|
||||
|
@ -20,10 +20,11 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GridEventEmitter, GridSetting, Size } from '@/components/grid/grid.js';
|
||||
import { GridEventEmitter, Size } from '@/components/grid/grid.js';
|
||||
import MkHeaderCell from '@/components/grid/MkHeaderCell.vue';
|
||||
import MkNumberCell from '@/components/grid/MkNumberCell.vue';
|
||||
import { GridColumn } from '@/components/grid/column.js';
|
||||
import { GridRowSetting } from '@/components/grid/row.js';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'operation:beginWidthChange', sender: GridColumn): void;
|
||||
|
@ -35,7 +36,7 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
defineProps<{
|
||||
columns: GridColumn[],
|
||||
gridSetting: GridSetting,
|
||||
gridSetting: GridRowSetting,
|
||||
bus: GridEventEmitter,
|
||||
}>();
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { ValidateViolation, ValidateViolationItem } from '@/components/grid/cell-validators.js';
|
||||
import { Size } from '@/components/grid/grid.js';
|
||||
import { ValidateViolation } from '@/components/grid/cell-validators.js';
|
||||
import { AdditionalStyle, EventOptions, Size } from '@/components/grid/grid.js';
|
||||
import { GridColumn } from '@/components/grid/column.js';
|
||||
import { GridRow } from '@/components/grid/row.js';
|
||||
import { MenuItem } from '@/types/menu.js';
|
||||
|
||||
export type CellValue = string | boolean | number | undefined | null
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { CellValidator } from '@/components/grid/cell-validators.js';
|
||||
import { Size, SizeStyle } from '@/components/grid/grid.js';
|
||||
import { AdditionalStyle, EventOptions, Size, SizeStyle } from '@/components/grid/grid.js';
|
||||
import { calcCellWidth } from '@/components/grid/grid-utils.js';
|
||||
import { CellValue, GridCell, GridCellSetting } from '@/components/grid/cell.js';
|
||||
import { GridRow } from '@/components/grid/row.js';
|
||||
|
||||
export type ColumnType = 'text' | 'number' | 'date' | 'boolean' | 'image';
|
||||
|
||||
export type ColumnSetting = {
|
||||
export type GridColumnSetting = {
|
||||
bindTo: string;
|
||||
title?: string;
|
||||
icon?: string;
|
||||
|
@ -12,16 +14,25 @@ export type ColumnSetting = {
|
|||
width: SizeStyle;
|
||||
editable?: boolean;
|
||||
validators?: CellValidator[];
|
||||
valueConverter?: GridColumnValueConverter;
|
||||
cellSetting?: GridCellSetting;
|
||||
};
|
||||
|
||||
export type GridColumn = {
|
||||
index: number;
|
||||
setting: ColumnSetting;
|
||||
setting: GridColumnSetting;
|
||||
width: string;
|
||||
contentSize: Size;
|
||||
}
|
||||
|
||||
export function createColumn(setting: ColumnSetting, index: number): GridColumn {
|
||||
export type GridColumnValueConverter = (row: GridRow, col: GridColumn, value: CellValue) => CellValue;
|
||||
|
||||
export type GridColumnEventArgs = {
|
||||
col: GridColumn;
|
||||
cells: GridCell[];
|
||||
} & EventOptions;
|
||||
|
||||
export function createColumn(setting: GridColumnSetting, index: number): GridColumn {
|
||||
return {
|
||||
index,
|
||||
setting,
|
||||
|
@ -29,3 +40,4 @@ export function createColumn(setting: ColumnSetting, index: number): GridColumn
|
|||
contentSize: { width: 0, height: 0 },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { GridSetting, SizeStyle } from '@/components/grid/grid.js';
|
||||
import { SizeStyle } from '@/components/grid/grid.js';
|
||||
import { CELL_ADDRESS_NONE, CellAddress } from '@/components/grid/cell.js';
|
||||
import { GridRowSetting } from '@/components/grid/row.js';
|
||||
|
||||
export function isCellElement(elem: any): elem is HTMLTableCellElement {
|
||||
return elem instanceof HTMLTableCellElement;
|
||||
|
@ -21,7 +22,7 @@ export function calcCellWidth(widthSetting: SizeStyle): string {
|
|||
}
|
||||
}
|
||||
|
||||
export function getCellAddress(elem: HTMLElement, gridSetting: GridSetting, parentNodeCount = 10): CellAddress {
|
||||
export function getCellAddress(elem: HTMLElement, gridSetting: GridRowSetting, parentNodeCount = 10): CellAddress {
|
||||
let node = elem;
|
||||
for (let i = 0; i < parentNodeCount; i++) {
|
||||
if (isCellElement(node) && isRowElement(node.parentElement)) {
|
||||
|
@ -29,7 +30,7 @@ export function getCellAddress(elem: HTMLElement, gridSetting: GridSetting, pare
|
|||
// ヘッダ行ぶんを除く
|
||||
row: node.parentElement.rowIndex - 1,
|
||||
// 数値列ぶんを除く
|
||||
col: gridSetting.rowNumberVisible ? node.cellIndex - 1 : node.cellIndex,
|
||||
col: gridSetting.showNumber ? node.cellIndex - 1 : node.cellIndex,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
import { EventEmitter } from 'eventemitter3';
|
||||
import { CellValue } from '@/components/grid/cell.js';
|
||||
import { GridColumnSetting } from '@/components/grid/column.js';
|
||||
import { GridRowSetting } from '@/components/grid/row.js';
|
||||
|
||||
export type GridSetting = {
|
||||
rowNumberVisible?: boolean;
|
||||
rowSelectable?: boolean;
|
||||
rowMinimumDefinitionCount?: number;
|
||||
}
|
||||
|
||||
export const defaultGridSetting: Required<GridSetting> = {
|
||||
rowNumberVisible: true,
|
||||
rowSelectable: true,
|
||||
rowMinimumDefinitionCount: 100,
|
||||
row: GridRowSetting;
|
||||
cols: GridColumnSetting[];
|
||||
};
|
||||
|
||||
export type DataSource = Record<string, CellValue>;
|
||||
|
@ -32,6 +27,16 @@ export type Size = {
|
|||
|
||||
export type SizeStyle = number | 'auto' | undefined;
|
||||
|
||||
export type EventOptions = {
|
||||
preventDefault?: boolean;
|
||||
stopPropagation?: boolean;
|
||||
}
|
||||
|
||||
export type AdditionalStyle = {
|
||||
className?: string;
|
||||
style?: Record<string, string | number>;
|
||||
}
|
||||
|
||||
export class GridEventEmitter extends EventEmitter<{
|
||||
'forceRefreshContentSize': void;
|
||||
}> {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Ref } from 'vue';
|
||||
import { GridCurrentState, GridKeyDownEvent } from '@/components/grid/grid-event.js';
|
||||
import copyToClipboard from '@/scripts/copy-to-clipboard.js';
|
||||
import { ColumnSetting } from '@/components/grid/column.js';
|
||||
import { GridColumnSetting } from '@/components/grid/column.js';
|
||||
import { CellValue } from '@/components/grid/cell.js';
|
||||
import { DataSource } from '@/components/grid/grid.js';
|
||||
|
||||
|
@ -67,7 +67,7 @@ class OptInGridUtils {
|
|||
gridItems: Ref<DataSource[]>,
|
||||
currentState: GridCurrentState,
|
||||
) {
|
||||
function parseValue(value: string, type: ColumnSetting['type']): CellValue {
|
||||
function parseValue(value: string, type: GridColumnSetting['type']): CellValue {
|
||||
switch (type) {
|
||||
case 'number': {
|
||||
return Number(value);
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
import { AdditionalStyle } from '@/components/grid/grid.js';
|
||||
|
||||
export const defaultGridSetting: Required<GridRowSetting> = {
|
||||
showNumber: true,
|
||||
selectable: true,
|
||||
minimumDefinitionCount: 100,
|
||||
};
|
||||
|
||||
export type GridRowSetting = {
|
||||
showNumber?: boolean;
|
||||
selectable?: boolean;
|
||||
minimumDefinitionCount?: number;
|
||||
}
|
||||
|
||||
export type GridRow = {
|
||||
index: number;
|
||||
ranged: boolean;
|
||||
using: boolean;
|
||||
additionalStyle?: AdditionalStyle;
|
||||
}
|
||||
|
||||
export function createRow(index: number, using: boolean): GridRow {
|
||||
|
@ -15,4 +30,6 @@ export function createRow(index: number, using: boolean): GridRow {
|
|||
export function resetRow(row: GridRow): void {
|
||||
row.ranged = false;
|
||||
row.using = false;
|
||||
row.additionalStyle = undefined;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ import MkGrid from '@/components/grid/MkGrid.vue';
|
|||
import { i18n } from '@/i18n.js';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { ColumnSetting } from '@/components/grid/column.js';
|
||||
import { GridColumnSetting } from '@/components/grid/column.js';
|
||||
import { validators } from '@/components/grid/cell-validators.js';
|
||||
import {
|
||||
GridCellContextMenuEvent,
|
||||
|
@ -125,13 +125,13 @@ import {
|
|||
GridRowContextMenuEvent,
|
||||
} from '@/components/grid/grid-event.js';
|
||||
import { optInGridUtils } from '@/components/grid/optin-utils.js';
|
||||
import { GridSetting } from '@/components/grid/grid.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import MkPagingButtons from '@/components/MkPagingButtons.vue';
|
||||
import XRegisterLogs from '@/pages/admin/custom-emojis-grid.local.logs.vue';
|
||||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkSelect from '@/components/MkSelect.vue';
|
||||
import { deviceKind } from '@/scripts/device-kind.js';
|
||||
import { GridRowSetting } from '@/components/grid/row.js';
|
||||
|
||||
type GridItem = {
|
||||
checked: boolean;
|
||||
|
@ -145,16 +145,17 @@ type GridItem = {
|
|||
isSensitive: boolean;
|
||||
localOnly: boolean;
|
||||
roleIdsThatCanBeUsedThisEmojiAsReaction: string;
|
||||
fileId?: string;
|
||||
}
|
||||
|
||||
const gridSetting: GridSetting = {
|
||||
rowNumberVisible: true,
|
||||
rowSelectable: false,
|
||||
const gridSetting: GridRowSetting = {
|
||||
showNumber: true,
|
||||
selectable: false,
|
||||
};
|
||||
|
||||
const required = validators.required();
|
||||
const regex = validators.regex(/^[a-zA-Z0-9_]+$/);
|
||||
const columnSettings: ColumnSetting[] = [
|
||||
const columnSettings: GridColumnSetting[] = [
|
||||
{ bindTo: 'checked', icon: 'ti-trash', type: 'boolean', editable: true, width: 34 },
|
||||
{ bindTo: 'url', icon: 'ti-icons', type: 'image', editable: false, width: 'auto', validators: [required] },
|
||||
{ bindTo: 'name', title: 'name', type: 'text', editable: true, width: 140, validators: [required, regex] },
|
||||
|
@ -228,6 +229,7 @@ async function onUpdateButtonClicked() {
|
|||
isSensitive: item.isSensitive,
|
||||
localOnly: item.localOnly,
|
||||
roleIdsThatCanBeUsedThisEmojiAsReaction: emptyStrToEmptyArray(item.roleIdsThatCanBeUsedThisEmojiAsReaction),
|
||||
fileId: item.fileId,
|
||||
})
|
||||
.then(() => ({ item, success: true, err: undefined }))
|
||||
.catch(err => ({ item, success: false, err })),
|
||||
|
@ -390,14 +392,32 @@ function onGridCellContextMenu(event: GridCellContextMenuEvent, currentState: Gr
|
|||
function onGridCellValueChange(event: GridCellValueChangeEvent) {
|
||||
const { row, column, newValue } = event;
|
||||
if (gridItems.value.length > row.index && column.setting.bindTo in gridItems.value[row.index]) {
|
||||
if (column.setting.bindTo === 'url') {
|
||||
const file = JSON.parse(newValue as string) as Misskey.entities.DriveFile;
|
||||
gridItems.value[row.index].url = file.url;
|
||||
gridItems.value[row.index].fileId = file.id;
|
||||
} else {
|
||||
gridItems.value[row.index][column.setting.bindTo] = newValue;
|
||||
}
|
||||
|
||||
const originItem = originGridItems.value[row.index][column.setting.bindTo];
|
||||
if (originItem !== newValue) {
|
||||
row.additionalStyle = {
|
||||
className: 'editedRow',
|
||||
};
|
||||
} else {
|
||||
row.additionalStyle = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function onGridKeyDown(event: GridKeyDownEvent, currentState: GridCurrentState) {
|
||||
const { ctrlKey, code } = event.event;
|
||||
const { ctrlKey, shiftKey, code } = event.event;
|
||||
|
||||
switch (true) {
|
||||
case ctrlKey && shiftKey: {
|
||||
break;
|
||||
}
|
||||
case ctrlKey: {
|
||||
switch (code) {
|
||||
case 'KeyC': {
|
||||
|
@ -411,6 +431,37 @@ async function onGridKeyDown(event: GridKeyDownEvent, currentState: GridCurrentS
|
|||
}
|
||||
break;
|
||||
}
|
||||
case shiftKey: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
switch (code) {
|
||||
case 'Delete': {
|
||||
if (currentState.rangedRows.length > 0) {
|
||||
for (const row of currentState.rangedRows) {
|
||||
gridItems.value[row.index].checked = true;
|
||||
}
|
||||
} else {
|
||||
const ranges = currentState.rangedCells;
|
||||
for (const cell of ranges) {
|
||||
if (cell.column.setting.editable) {
|
||||
gridItems.value[cell.row.index][cell.column.setting.bindTo] = undefined;
|
||||
const originItem = originGridItems.value[cell.row.index][cell.column.setting.bindTo];
|
||||
if (originItem !== undefined) {
|
||||
cell.row.additionalStyle = {
|
||||
className: 'editedRow',
|
||||
};
|
||||
} else {
|
||||
cell.row.additionalStyle = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,8 +481,6 @@ async function refreshCustomEmojis() {
|
|||
hostType: 'local',
|
||||
};
|
||||
|
||||
console.log(queryUpdatedAtTo.value);
|
||||
|
||||
if (JSON.stringify(query) !== previousQuery.value) {
|
||||
currentPage.value = 1;
|
||||
}
|
||||
|
@ -481,6 +530,10 @@ onMounted(async () => {
|
|||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.editedRow {
|
||||
background-color: var(--infoBg);
|
||||
}
|
||||
|
||||
.row1 {
|
||||
grid-row: 1 / 2;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<script setup lang="ts">
|
||||
|
||||
import { computed, ref, toRefs } from 'vue';
|
||||
import { ColumnSetting } from '@/components/grid/column.js';
|
||||
import { GridColumnSetting } from '@/components/grid/column.js';
|
||||
import { RequestLogItem } from '@/pages/admin/custom-emojis-grid.impl.js';
|
||||
import {
|
||||
GridCellContextMenuEvent,
|
||||
|
@ -40,7 +40,7 @@ import { optInGridUtils } from '@/components/grid/optin-utils.js';
|
|||
import MkGrid from '@/components/grid/MkGrid.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
|
||||
const columnSettings: ColumnSetting[] = [
|
||||
const columnSettings: GridColumnSetting[] = [
|
||||
{ bindTo: 'failed', title: 'failed', type: 'boolean', editable: false, width: 50 },
|
||||
{ bindTo: 'url', icon: 'ti-icons', type: 'image', editable: false, width: 'auto' },
|
||||
{ bindTo: 'name', title: 'name', type: 'text', editable: false, width: 140 },
|
||||
|
|
|
@ -100,7 +100,7 @@ import {
|
|||
GridKeyDownEvent,
|
||||
GridRowContextMenuEvent,
|
||||
} from '@/components/grid/grid-event.js';
|
||||
import { ColumnSetting } from '@/components/grid/column.js';
|
||||
import { GridColumnSetting } from '@/components/grid/column.js';
|
||||
import { DroppedFile, extractDroppedItems, flattenDroppedFiles } from '@/scripts/file-drop.js';
|
||||
import { optInGridUtils } from '@/components/grid/optin-utils.js';
|
||||
import XRegisterLogs from '@/pages/admin/custom-emojis-grid.local.logs.vue';
|
||||
|
@ -127,7 +127,7 @@ type GridItem = {
|
|||
|
||||
const required = validators.required();
|
||||
const regex = validators.regex(/^[a-zA-Z0-9_]+$/);
|
||||
const columnSettings: ColumnSetting[] = [
|
||||
const columnSettings: GridColumnSetting[] = [
|
||||
{ bindTo: 'url', icon: 'ti-icons', type: 'image', editable: false, width: 'auto', validators: [required] },
|
||||
{ bindTo: 'name', title: 'name', type: 'text', editable: true, width: 140, validators: [required, regex] },
|
||||
{ bindTo: 'category', title: 'category', type: 'text', editable: true, width: 140 },
|
||||
|
|
|
@ -51,7 +51,7 @@ import { i18n } from '@/i18n.js';
|
|||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import MkGrid from '@/components/grid/MkGrid.vue';
|
||||
import { ColumnSetting } from '@/components/grid/column.js';
|
||||
import { GridColumnSetting } from '@/components/grid/column.js';
|
||||
import { RequestLogItem } from '@/pages/admin/custom-emojis-grid.impl.js';
|
||||
import {
|
||||
GridCellContextMenuEvent,
|
||||
|
@ -74,7 +74,7 @@ type GridItem = {
|
|||
host: string;
|
||||
}
|
||||
|
||||
const columnSettings: ColumnSetting[] = [
|
||||
const columnSettings: GridColumnSetting[] = [
|
||||
{ bindTo: 'checked', icon: 'ti-download', type: 'boolean', editable: true, width: 34 },
|
||||
{ bindTo: 'url', icon: 'ti-icons', type: 'image', editable: false, width: 'auto' },
|
||||
{ bindTo: 'name', title: 'name', type: 'text', editable: false, width: 'auto' },
|
||||
|
|
Loading…
Reference in New Issue