diff options
Diffstat (limited to 'app/assets/javascripts/import_entities/import_groups/components/import_table.vue')
-rw-r--r-- | app/assets/javascripts/import_entities/import_groups/components/import_table.vue | 212 |
1 files changed, 159 insertions, 53 deletions
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_table.vue b/app/assets/javascripts/import_entities/import_groups/components/import_table.vue index 80e2e73f420..7c5f48dcafc 100644 --- a/app/assets/javascripts/import_entities/import_groups/components/import_table.vue +++ b/app/assets/javascripts/import_entities/import_groups/components/import_table.vue @@ -1,78 +1,184 @@ <script> -import { GlLoadingIcon } from '@gitlab/ui'; -import bulkImportSourceGroupsQuery from '../graphql/queries/bulk_import_source_groups.query.graphql'; -import availableNamespacesQuery from '../graphql/queries/available_namespaces.query.graphql'; -import setTargetNamespaceMutation from '../graphql/mutations/set_target_namespace.mutation.graphql'; -import setNewNameMutation from '../graphql/mutations/set_new_name.mutation.graphql'; +import { + GlEmptyState, + GlIcon, + GlLink, + GlLoadingIcon, + GlSearchBoxByClick, + GlSprintf, +} from '@gitlab/ui'; +import { s__ } from '~/locale'; +import PaginationLinks from '~/vue_shared/components/pagination_links.vue'; import importGroupMutation from '../graphql/mutations/import_group.mutation.graphql'; +import setNewNameMutation from '../graphql/mutations/set_new_name.mutation.graphql'; +import setTargetNamespaceMutation from '../graphql/mutations/set_target_namespace.mutation.graphql'; +import availableNamespacesQuery from '../graphql/queries/available_namespaces.query.graphql'; +import bulkImportSourceGroupsQuery from '../graphql/queries/bulk_import_source_groups.query.graphql'; import ImportTableRow from './import_table_row.vue'; -const mapApolloMutations = (mutations) => - Object.fromEntries( - Object.entries(mutations).map(([key, mutation]) => [ - key, - function mutate(config) { - return this.$apollo.mutate({ - mutation, - ...config, - }); - }, - ]), - ); - export default { components: { + GlEmptyState, + GlIcon, + GlLink, GlLoadingIcon, + GlSearchBoxByClick, + GlSprintf, ImportTableRow, + PaginationLinks, + }, + + props: { + sourceUrl: { + type: String, + required: true, + }, + }, + + data() { + return { + filter: '', + page: 1, + }; }, apollo: { - bulkImportSourceGroups: bulkImportSourceGroupsQuery, + bulkImportSourceGroups: { + query: bulkImportSourceGroupsQuery, + variables() { + return { page: this.page, filter: this.filter }; + }, + }, availableNamespaces: availableNamespacesQuery, }, + computed: { + hasGroups() { + return this.bulkImportSourceGroups?.nodes?.length > 0; + }, + + hasEmptyFilter() { + return this.filter.length > 0 && !this.hasGroups; + }, + + statusMessage() { + return this.filter.length === 0 + ? s__('BulkImport|Showing %{start}-%{end} of %{total} from %{link}') + : s__( + 'BulkImport|Showing %{start}-%{end} of %{total} matching filter "%{filter}" from %{link}', + ); + }, + + paginationInfo() { + const { page, perPage, total } = this.bulkImportSourceGroups?.pageInfo ?? { + page: 1, + perPage: 0, + total: 0, + }; + const start = (page - 1) * perPage + 1; + const end = start + (this.bulkImportSourceGroups.nodes?.length ?? 0) - 1; + + return { start, end, total }; + }, + }, + + watch: { + filter() { + this.page = 1; + }, + }, + methods: { - ...mapApolloMutations({ - setTargetNamespace: setTargetNamespaceMutation, - setNewName: setNewNameMutation, - importGroup: importGroupMutation, - }), + setPage(page) { + this.page = page; + }, + + updateTargetNamespace(sourceGroupId, targetNamespace) { + this.$apollo.mutate({ + mutation: setTargetNamespaceMutation, + variables: { sourceGroupId, targetNamespace }, + }); + }, + + updateNewName(sourceGroupId, newName) { + this.$apollo.mutate({ + mutation: setNewNameMutation, + variables: { sourceGroupId, newName }, + }); + }, + + importGroup(sourceGroupId) { + this.$apollo.mutate({ + mutation: importGroupMutation, + variables: { sourceGroupId }, + }); + }, }, }; </script> <template> <div> - <gl-loading-icon v-if="$apollo.loading" size="md" class="gl-mt-5" /> - <div v-else-if="bulkImportSourceGroups.length"> - <table class="gl-w-full"> - <thead class="gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1"> - <th class="gl-py-4 import-jobs-from-col">{{ s__('BulkImport|From source group') }}</th> - <th class="gl-py-4 import-jobs-to-col">{{ s__('BulkImport|To new group') }}</th> - <th class="gl-py-4 import-jobs-status-col">{{ __('Status') }}</th> - <th class="gl-py-4 import-jobs-cta-col"></th> - </thead> - <tbody> - <template v-for="group in bulkImportSourceGroups"> - <import-table-row - :key="group.id" - :group="group" - :available-namespaces="availableNamespaces" - @update-target-namespace=" - setTargetNamespace({ - variables: { sourceGroupId: group.id, targetNamespace: $event }, - }) - " - @update-new-name=" - setNewName({ - variables: { sourceGroupId: group.id, newName: $event }, - }) - " - @import-group="importGroup({ variables: { sourceGroupId: group.id } })" - /> + <div + class="gl-py-5 gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1 gl-display-flex gl-align-items-center" + > + <span> + <gl-sprintf v-if="!$apollo.loading && hasGroups" :message="statusMessage"> + <template #start> + <strong>{{ paginationInfo.start }}</strong> + </template> + <template #end> + <strong>{{ paginationInfo.end }}</strong> </template> - </tbody> - </table> + <template #total> + <strong>{{ n__('%d group', '%d groups', paginationInfo.total) }}</strong> + </template> + <template #filter> + <strong>{{ filter }}</strong> + </template> + <template #link> + <gl-link class="gl-display-inline-block" :href="sourceUrl" target="_blank"> + {{ sourceUrl }} <gl-icon name="external-link" class="vertical-align-middle" /> + </gl-link> + </template> + </gl-sprintf> + </span> + <gl-search-box-by-click class="gl-ml-auto" @submit="filter = $event" @clear="filter = ''" /> </div> + <gl-loading-icon v-if="$apollo.loading" size="md" class="gl-mt-5" /> + <template v-else> + <gl-empty-state v-if="hasEmptyFilter" :title="__('Sorry, your filter produced no results')" /> + <gl-empty-state + v-else-if="!hasGroups" + :title="s__('BulkImport|No groups available for import')" + /> + <div v-else class="gl-display-flex gl-flex-direction-column gl-align-items-center"> + <table class="gl-w-full"> + <thead class="gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1"> + <th class="gl-py-4 import-jobs-from-col">{{ s__('BulkImport|From source group') }}</th> + <th class="gl-py-4 import-jobs-to-col">{{ s__('BulkImport|To new group') }}</th> + <th class="gl-py-4 import-jobs-status-col">{{ __('Status') }}</th> + <th class="gl-py-4 import-jobs-cta-col"></th> + </thead> + <tbody> + <template v-for="group in bulkImportSourceGroups.nodes"> + <import-table-row + :key="group.id" + :group="group" + :available-namespaces="availableNamespaces" + @update-target-namespace="updateTargetNamespace(group.id, $event)" + @update-new-name="updateNewName(group.id, $event)" + @import-group="importGroup(group.id)" + /> + </template> + </tbody> + </table> + <pagination-links + :change="setPage" + :page-info="bulkImportSourceGroups.pageInfo" + class="gl-mt-3" + /> + </div> + </template> </div> </template> |