diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-01 12:10:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-08-01 12:10:08 +0300 |
commit | 1fb5861e0a89e67369a6ab36ffa6dd29d2445bff (patch) | |
tree | 801201c3902dea6be771e811830f18e4c4ea4563 /app | |
parent | adc17b84d11174d88a945d51a575292046a51a2c (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
4 files changed, 213 insertions, 3 deletions
diff --git a/app/assets/javascripts/custom_emoji/components/list.vue b/app/assets/javascripts/custom_emoji/components/list.vue new file mode 100644 index 00000000000..82d5f3320b4 --- /dev/null +++ b/app/assets/javascripts/custom_emoji/components/list.vue @@ -0,0 +1,135 @@ +<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> diff --git a/app/assets/javascripts/custom_emoji/pages/index.vue b/app/assets/javascripts/custom_emoji/pages/index.vue index 6d32ba41eae..b8e9f0a62d7 100644 --- a/app/assets/javascripts/custom_emoji/pages/index.vue +++ b/app/assets/javascripts/custom_emoji/pages/index.vue @@ -1,7 +1,63 @@ <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> <template> - <div></div> + <list + :count="count" + :loading="$apollo.queries.customEmojis.loading" + :page-info="pageInfo" + :custom-emojis="customEmojis" + @input="changePage" + /> </template> diff --git a/app/assets/javascripts/custom_emoji/queries/custom_emojis.query.graphql b/app/assets/javascripts/custom_emoji/queries/custom_emojis.query.graphql new file mode 100644 index 00000000000..5f8af6cf42d --- /dev/null +++ b/app/assets/javascripts/custom_emoji/queries/custom_emojis.query.graphql @@ -0,0 +1,19 @@ +#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 + } + } + } +} diff --git a/app/controllers/organizations/application_controller.rb b/app/controllers/organizations/application_controller.rb index 43cc7014f62..cce76395cbd 100644 --- a/app/controllers/organizations/application_controller.rb +++ b/app/controllers/organizations/application_controller.rb @@ -16,7 +16,7 @@ module Organizations strong_memoize_attr :organization def authorize_action!(action) - access_denied! if Feature.disabled?(:ui_for_organizations) + access_denied! if Feature.disabled?(:ui_for_organizations, current_user) access_denied! unless can?(current_user, action, organization) end end |