This commit is contained in:
samunohito 2024-02-12 20:10:49 +09:00
parent 5dd1fd7c5f
commit 763cac0aad
5 changed files with 203 additions and 3 deletions

View file

@ -409,6 +409,7 @@ function toStories(component: string): Promise<string> {
glob('src/components/MkUserSetupDialog.vue'),
glob('src/components/MkUserSetupDialog.*.vue'),
glob('src/components/MkInviteCode.vue'),
glob('src/components/MkTagItem.vue'),
glob('src/pages/user/home.vue'),
]);
const components = globs.flat();

View file

@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
>
<KeepAlive>
<div v-show="opened">
<MkSpacer :marginMin="14" :marginMax="22">
<MkSpacer :marginMin="spacerMin" :marginMax="spacerMax">
<slot></slot>
</MkSpacer>
</div>
@ -56,9 +56,13 @@ import { defaultStore } from '@/store.js';
const props = withDefaults(defineProps<{
defaultOpen?: boolean;
maxHeight?: number | null;
spacerMin?: number;
spacerMax?: number;
}>(), {
defaultOpen: false,
maxHeight: null,
spacerMin: 14,
spacerMax: 22,
});
const getBgColor = (el: HTMLElement) => {

View file

@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { action } from '@storybook/addon-actions';
import { StoryObj } from '@storybook/vue3';
import MkTagItem from './MkTagItem.vue';
export const Default = {
render(args) {
return {
components: {
MkTagItem: MkTagItem,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
events() {
return {
click: action('click'),
exButtonClick: action('exButtonClick'),
};
},
},
template: '<MkTagItem v-bind="props" v-on="events"></MkTagItem>',
};
},
args: {
content: 'name',
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkTagItem>;
export const Icon = {
...Default,
args: {
...Default.args,
iconClass: 'ti ti-arrow-up',
},
} satisfies StoryObj<typeof MkTagItem>;
export const ExButton = {
...Default,
args: {
...Default.args,
exButtonIconClass: 'ti ti-x',
},
} satisfies StoryObj<typeof MkTagItem>;
export const IconExButton = {
...Default,
args: {
...Default.args,
iconClass: 'ti ti-arrow-up',
exButtonIconClass: 'ti ti-x',
},
} satisfies StoryObj<typeof MkTagItem>;

View file

@ -0,0 +1,61 @@
<template>
<div :class="$style.root" @click="(ev) => emit('click', ev)">
<span v-if="iconClass" :class="[$style.icon, iconClass]"/>
<span :class="$style.content">{{ content }}</span>
<MkButton v-if="exButtonIconClass" :class="$style.exButton" @click="(ev) => emit('exButtonClick', ev)">
<span :class="exButtonIconClass"/>
</MkButton>
</div>
</template>
<script setup lang="ts">
import MkButton from '@/components/MkButton.vue';
const emit = defineEmits<{
(ev: 'click', payload: MouseEvent): void;
(ev: 'exButtonClick', payload: MouseEvent): void;
}>();
defineProps<{
iconClass?: string;
content: string;
exButtonIconClass?: string
}>();
</script>
<style module lang="scss">
$buttonSize : 2em;
.root {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 9999px;
padding: 4px 4px;
gap: 4px;
background-color: var(--buttonBg);
&:hover {
background-color: var(--buttonBgHover);
}
}
.icon {
font-size: 0.80em;
}
.exButton {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 9999px;
max-height: $buttonSize;
max-width: $buttonSize;
min-height: $buttonSize;
min-width: $buttonSize;
padding: 0;
box-sizing: border-box;
font-size: 0.65em;
}
</style>

View file

@ -58,7 +58,24 @@
</MkInput>
</div>
<div role="separator" :class="$style.divider"></div>
<MkFolder :spacerMax="8" :spacerMin="8">
<template #icon><i class="ti ti-arrows-sort"></i></template>
<template #label>ソート順</template>
<div :class="$style.sortOrderArea">
<div :class="$style.sortOrderAreaTags">
<MkTagItem
v-for="order in sortOrders"
:key="order.column"
:iconClass="order.direction === 'ASC' ? 'ti ti-arrow-up' : 'ti ti-arrow-down'"
:exButtonIconClass="'ti ti-x'"
:content="order.column"
/>
</div>
<MkButton :class="$style.sortOrderAddButton">
<span class="ti ti-plus"/>
</MkButton>
</div>
</MkFolder>
<div :class="[[spMode ? $style.searchButtonsSp : $style.searchButtons]]">
<MkButton primary @click="onSearchButtonClicked">
@ -134,6 +151,7 @@ import MkFolder from '@/components/MkFolder.vue';
import MkSelect from '@/components/MkSelect.vue';
import { deviceKind } from '@/scripts/device-kind.js';
import { GridSetting } from '@/components/grid/grid.js';
import MkTagItem from '@/components/MkTagItem.vue';
type GridItem = {
checked: boolean;
@ -153,6 +171,21 @@ type GridItem = {
originalUrl?: string | null;
}
type GridSortOrderKey =
'name' |
'category' |
'aliases' |
'type' |
'license' |
'isSensitive' |
'localOnly' |
'updatedAt';
type GridSortOrder = {
column: GridSortOrderKey;
direction: 'ASC' | 'DESC';
}
function setupGrid(): GridSetting {
const required = validators.required();
const regex = validators.regex(/^[a-zA-Z0-9_]+$/);
@ -203,7 +236,8 @@ const queryUpdatedAtTo = ref<string | null>(null);
const querySensitive = ref<string | null>(null);
const queryLocalOnly = ref<string | null>(null);
const previousQuery = ref<string | undefined>(undefined);
const sortOrders = ref<GridSortOrder[]>([]);
sortOrders.value.push({ column: 'updatedAt', direction: 'DESC' }, { column: 'name', direction: 'ASC' });
const requestLogs = ref<RequestLogItem[]>([]);
const gridItems = ref<GridItem[]>([]);
@ -608,6 +642,36 @@ onMounted(async () => {
gap: 8px;
}
.sortOrderArea {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
}
.sortOrderAreaTags {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
gap: 8px;
}
.sortOrderAddButton {
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
min-width: 2.0em;
min-height: 2.0em;
max-width: 2.0em;
max-height: 2.0em;
padding: 8px;
margin-left: auto;
border-radius: 9999px;
background-color: var(--buttonBg);
}
.gridArea {
overflow: scroll;
padding-top: 8px;