Skip to content
代码片段 群组 项目
提交 ca34650f 编辑于 作者: Kushal Pandya's avatar Kushal Pandya
浏览文件

Merge branch 'ph/customEmojiListComponent' into 'master'

Added list component for custom emoji settings page

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127509



Merged-by: default avatarKushal Pandya <kushal@gitlab.com>
Approved-by: default avatarKushal Pandya <kushal@gitlab.com>
Reviewed-by: default avatarKushal Pandya <kushal@gitlab.com>
Co-authored-by: default avatarPhil Hughes <me@iamphill.com>
No related branches found
No related tags found
无相关合并请求
<script>
import { GlLoadingIcon, GlTableLite, GlTabs, GlTab, GlBadge, GlKeysetPagination } from '@gitlab/ui';
import { __ } from '~/locale';
import { formatDate } from '~/lib/utils/datetime/date_format_utility';
export default {
components: {
GlTableLite,
GlLoadingIcon,
GlTabs,
GlTab,
GlBadge,
GlKeysetPagination,
},
props: {
loading: {
type: Boolean,
required: false,
default: false,
},
customEmojis: {
type: Array,
required: true,
},
pageInfo: {
type: Object,
required: true,
},
count: {
type: Number,
required: true,
},
},
methods: {
prevPage() {
this.$emit('input', {
before: this.pageInfo.startCursor,
});
},
nextPage() {
this.$emit('input', {
after: this.pageInfo.endCursor,
});
},
formatDate(date) {
return formatDate(date, 'mmmm d, yyyy');
},
},
primaryAction: {
text: __('New custom emoji'),
attributes: {
variant: 'info',
to: '/new',
},
},
fields: [
{
key: 'emoji',
label: __('Image'),
thClass: 'gl-border-t-0!',
tdClass: 'gl-vertical-align-middle!',
columnWidth: '70px',
},
{
key: 'name',
label: __('Name'),
thClass: 'gl-border-t-0!',
tdClass: 'gl-vertical-align-middle! gl-font-monospace',
},
{
key: 'created_at',
label: __('Created date'),
thClass: 'gl-border-t-0!',
tdClass: 'gl-vertical-align-middle!',
columnWidth: '25%',
},
{
key: 'action',
label: '',
thClass: 'gl-border-t-0!',
columnWidth: '64px',
},
],
};
</script>
<template>
<div>
<gl-loading-icon v-if="loading" size="lg" />
<template v-else>
<gl-tabs content-class="gl-pt-0" :action-primary="$options.primaryAction">
<gl-tab>
<template #title>
{{ __('Emoji') }}
<gl-badge size="sm" class="gl-tab-counter-badge">{{ count }}</gl-badge>
</template>
<gl-table-lite
:items="customEmojis"
:fields="$options.fields"
table-class="gl-table-layout-fixed"
>
<template #table-colgroup="scope">
<col
v-for="field in scope.fields"
:key="field.key"
:style="{ width: field.columnWidth }"
/>
</template>
<template #cell(emoji)="data">
<gl-emoji
:data-name="data.item.name"
:data-fallback-src="data.item.url"
data-unicode-version="custom"
/>
</template>
<template #cell(action)> </template>
<template #cell(created_at)="data">
{{ formatDate(data.item.createdAt) }}
</template>
<template #cell(name)="data">
<strong class="gl-str-truncated">:{{ data.item.name }}:</strong>
</template>
</gl-table-lite>
<gl-keyset-pagination
v-if="pageInfo.hasPreviousPage || pageInfo.hasNextPage"
v-bind="pageInfo"
class="gl-mt-4"
@prev="prevPage"
@next="nextPage"
/>
</gl-tab>
</gl-tabs>
</template>
</div>
</template>
<script> <script>
export default {}; import { fetchPolicies } from '~/lib/graphql';
import customEmojisQuery from '../queries/custom_emojis.query.graphql';
import List from '../components/list.vue';
export default {
apollo: {
customEmojis: {
fetchPolicy: fetchPolicies.NETWORK_ONLY,
query: customEmojisQuery,
update: (r) => r.group?.customEmoji?.nodes,
variables() {
return {
groupPath: this.groupPath,
...this.pagination,
};
},
result({ data }) {
const pageInfo = data.group?.customEmoji?.pageInfo;
this.count = data.group?.customEmoji?.count;
if (pageInfo) {
this.pageInfo = pageInfo;
}
},
},
},
components: {
List,
},
inject: {
groupPath: {
default: '',
},
},
data() {
return {
customEmojis: [],
count: 0,
pageInfo: {},
pagination: {},
};
},
methods: {
refetchCustomEmojis() {
this.$apollo.queries.customEmojis.refetch();
},
changePage(pageInfo) {
this.pagination = pageInfo;
},
},
};
</script> </script>
<template> <template>
<div></div> <list
:count="count"
:loading="$apollo.queries.customEmojis.loading"
:page-info="pageInfo"
:custom-emojis="customEmojis"
@input="changePage"
/>
</template> </template>
#import "~/graphql_shared/fragments/page_info.fragment.graphql"
query getCustomEmojis($groupPath: ID!, $after: String = "", $before: String = "") {
group(fullPath: $groupPath) {
id
customEmoji(after: $after, before: $before) {
count
pageInfo {
...PageInfo
}
nodes {
id
name
url
createdAt
}
}
}
}
...@@ -17412,6 +17412,9 @@ msgstr "" ...@@ -17412,6 +17412,9 @@ msgstr ""
msgid "Embed" msgid "Embed"
msgstr "" msgstr ""
   
msgid "Emoji"
msgstr ""
msgid "Empty file" msgid "Empty file"
msgstr "" msgstr ""
   
...@@ -23567,6 +23570,9 @@ msgstr "" ...@@ -23567,6 +23570,9 @@ msgstr ""
msgid "Ignored" msgid "Ignored"
msgstr "" msgstr ""
   
msgid "Image"
msgstr ""
msgid "ImageDiffViewer|2-up" msgid "ImageDiffViewer|2-up"
msgstr "" msgstr ""
   
...@@ -30672,6 +30678,9 @@ msgstr "" ...@@ -30672,6 +30678,9 @@ msgstr ""
msgid "New confidential issue title" msgid "New confidential issue title"
msgstr "" msgstr ""
   
msgid "New custom emoji"
msgstr ""
msgid "New deploy key" msgid "New deploy key"
msgstr "" msgstr ""
   
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Custom emoji settings list component renders table of custom emoji 1`] = `
<div>
<div
class="tabs gl-tabs"
>
<!---->
<div
class=""
>
<ul
class="nav gl-tabs-nav"
role="tablist"
>
<div
class="gl-actions-tabs-start"
data-testid="actions-tabs-start"
>
<a
class="btn btn-info btn-md gl-button"
data-testid="action-primary"
href="/new"
to="/new"
>
<!---->
<!---->
<span
class="gl-button-text"
>
New custom emoji
</span>
</a>
<!---->
<!---->
</div>
<div
class="gl-actions-tabs-end"
data-testid="actions-tabs-end"
>
<a
class="btn btn-info btn-md gl-button"
data-testid="action-primary"
href="/new"
to="/new"
>
<!---->
<!---->
<span
class="gl-button-text"
>
New custom emoji
</span>
</a>
<!---->
<!---->
</div>
</ul>
</div>
<div
class="tab-content gl-pt-0 gl-tab-content"
>
<transition-stub
css="true"
enteractiveclass=""
enterclass=""
entertoclass="show"
leaveactiveclass=""
leaveclass="show"
leavetoclass=""
mode="out-in"
name=""
>
<div
aria-hidden="true"
class="tab-pane"
role="tabpanel"
style="display: none;"
>
<table
aria-busy=""
aria-colcount="4"
class="table b-table gl-table gl-table-layout-fixed"
role="table"
>
<!---->
<colgroup>
<col
style="width: 70px;"
/>
<col />
<col
style="width: 25%;"
/>
<col
style="width: 64px;"
/>
</colgroup>
<thead
class=""
role="rowgroup"
>
<!---->
<tr
class=""
role="row"
>
<th
aria-colindex="1"
class="gl-border-t-0!"
role="columnheader"
scope="col"
>
<div>
Image
</div>
</th>
<th
aria-colindex="2"
class="gl-border-t-0!"
role="columnheader"
scope="col"
>
<div>
Name
</div>
</th>
<th
aria-colindex="3"
class="gl-border-t-0!"
role="columnheader"
scope="col"
>
<div>
Created date
</div>
</th>
<th
aria-colindex="4"
aria-label="Action"
class="gl-border-t-0!"
role="columnheader"
scope="col"
>
<div />
</th>
</tr>
</thead>
<tbody
role="rowgroup"
>
<!---->
<tr
class=""
role="row"
>
<td
aria-colindex="1"
class="gl-vertical-align-middle!"
role="cell"
>
<gl-emoji
data-fallback-src="https://gitlab.com/custom_emoji/custom_emoji/-/raw/main/img/confused_husky.gif"
data-name="confused_husky"
data-unicode-version="custom"
/>
</td>
<td
aria-colindex="2"
class="gl-vertical-align-middle! gl-font-monospace"
role="cell"
>
<strong
class="gl-str-truncated"
>
:confused_husky:
</strong>
</td>
<td
aria-colindex="3"
class="gl-vertical-align-middle!"
role="cell"
>
created-at
</td>
<td
aria-colindex="4"
class=""
role="cell"
/>
</tr>
<!---->
<!---->
</tbody>
<!---->
</table>
<!---->
</div>
</transition-stub>
<!---->
</div>
</div>
</div>
`;
import Vue from 'vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import List from '~/custom_emoji/components/list.vue';
import { CUSTOM_EMOJI } from '../mock_data';
jest.mock('~/lib/utils/datetime/date_format_utility', () => ({
formatDate: (date) => date,
}));
Vue.config.ignoredElements = ['gl-emoji'];
let wrapper;
function createComponent(propsData = {}) {
wrapper = mountExtended(List, {
propsData: {
customEmojis: CUSTOM_EMOJI,
pageInfo: {},
count: CUSTOM_EMOJI.length,
...propsData,
},
});
}
describe('Custom emoji settings list component', () => {
it('renders table of custom emoji', () => {
createComponent();
expect(wrapper.element).toMatchSnapshot();
});
describe('pagination', () => {
it.each`
emits | button | pageInfo
${{ before: 'startCursor' }} | ${'prevButton'} | ${{ hasPreviousPage: true, startCursor: 'startCursor' }}
${{ after: 'endCursor' }} | ${'nextButton'} | ${{ hasNextPage: true, endCursor: 'endCursor' }}
`('emits $emits when $button is clicked', async ({ emits, button, pageInfo }) => {
createComponent({ pageInfo });
await wrapper.findByTestId(button).vm.$emit('click');
expect(wrapper.emitted('input')[0]).toEqual([emits]);
});
});
});
export const CUSTOM_EMOJI = [
{
id: 'gid://gitlab/CustomEmoji/1',
name: 'confused_husky',
url: 'https://gitlab.com/custom_emoji/custom_emoji/-/raw/main/img/confused_husky.gif',
createdAt: 'created-at',
},
];
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册