Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-07-23 12:09:18 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-23 12:09:18 +0300
commitdefde9698e1d87e7d8c09e487ed75675d1d67323 (patch)
treeec74808523206172b81bd83baf7dd0f579b933f0 /app/assets/javascripts/incidents
parent6520b1366e604be8c9c43f36159ecd6a5284a2b0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/incidents')
-rw-r--r--app/assets/javascripts/incidents/components/incidents_list.vue129
-rw-r--r--app/assets/javascripts/incidents/constants.js7
-rw-r--r--app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql22
-rw-r--r--app/assets/javascripts/incidents/list.js34
4 files changed, 192 insertions, 0 deletions
diff --git a/app/assets/javascripts/incidents/components/incidents_list.vue b/app/assets/javascripts/incidents/components/incidents_list.vue
new file mode 100644
index 00000000000..a974afbe539
--- /dev/null
+++ b/app/assets/javascripts/incidents/components/incidents_list.vue
@@ -0,0 +1,129 @@
+<script>
+import { GlLoadingIcon, GlTable, GlAlert } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import getIncidents from '../graphql/queries/get_incidents.query.graphql';
+import { I18N } from '../constants';
+
+const tdClass =
+ 'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
+const thClass = 'gl-hover-bg-blue-50';
+const bodyTrClass =
+ 'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-bg-blue-50 gl-hover-border-b-solid gl-hover-border-blue-200';
+
+export default {
+ i18n: I18N,
+ fields: [
+ {
+ key: 'title',
+ label: s__('IncidentManagement|Incident'),
+ thClass: `gl-pointer-events-none gl-w-half`,
+ tdClass,
+ },
+ {
+ key: 'createdAt',
+ label: s__('IncidentManagement|Date created'),
+ thClass: `${thClass} gl-pointer-events-none`,
+ tdClass,
+ },
+ {
+ key: 'assignees',
+ label: s__('IncidentManagement|Assignees'),
+ thClass: 'gl-pointer-events-none',
+ tdClass,
+ },
+ ],
+ components: {
+ GlLoadingIcon,
+ GlTable,
+ GlAlert,
+ },
+ inject: ['projectPath'],
+ apollo: {
+ incidents: {
+ query: getIncidents,
+ variables() {
+ return {
+ projectPath: this.projectPath,
+ labelNames: ['incident'],
+ };
+ },
+ update: ({ project: { issues: { nodes = [] } = {} } = {} }) => nodes,
+ error() {
+ this.errored = true;
+ },
+ },
+ },
+ data() {
+ return {
+ errored: false,
+ isErrorAlertDismissed: false,
+ };
+ },
+ computed: {
+ showErrorMsg() {
+ return this.errored && !this.isErrorAlertDismissed;
+ },
+ loading() {
+ return this.$apollo.queries.incidents.loading;
+ },
+ hasIncidents() {
+ return this.incidents?.length;
+ },
+ tbodyTrClass() {
+ return {
+ [bodyTrClass]: !this.loading && this.hasIncidents,
+ };
+ },
+ },
+ methods: {
+ getAssignees(assignees) {
+ return assignees.nodes?.length > 0
+ ? assignees.nodes[0]?.username
+ : s__('IncidentManagement|Unassigned');
+ },
+ },
+};
+</script>
+<template>
+ <div class="incident-management-list">
+ <gl-alert v-if="showErrorMsg" variant="danger" @dismiss="isErrorAlertDismissed = true">
+ {{ $options.i18n.errorMsg }}
+ </gl-alert>
+
+ <h4 class="gl-display-block d-md-none my-3">
+ {{ s__('IncidentManagement|Incidents') }}
+ </h4>
+ <gl-table
+ :items="incidents"
+ :fields="$options.fields"
+ :show-empty="true"
+ :busy="loading"
+ stacked="md"
+ :tbody-tr-class="tbodyTrClass"
+ :no-local-sorting="true"
+ fixed
+ >
+ <template #cell(title)="{ item }">
+ <div class="gl-max-w-full text-truncate" :title="item.title">{{ item.title }}</div>
+ </template>
+
+ <template #cell(createdAt)="{ item }">
+ {{ item.createdAt }}
+ </template>
+
+ <template #cell(assignees)="{ item }">
+ <div class="gl-max-w-full text-truncate" data-testid="assigneesField">
+ {{ getAssignees(item.assignees) }}
+ </div>
+ </template>
+
+ <template #table-busy>
+ <gl-loading-icon size="lg" color="dark" class="mt-3" />
+ </template>
+
+ <template #empty>
+ {{ $options.i18n.noIncidents }}
+ </template>
+ </gl-table>
+ </div>
+</template>
diff --git a/app/assets/javascripts/incidents/constants.js b/app/assets/javascripts/incidents/constants.js
new file mode 100644
index 00000000000..572a8d851cb
--- /dev/null
+++ b/app/assets/javascripts/incidents/constants.js
@@ -0,0 +1,7 @@
+/* eslint-disable import/prefer-default-export */
+import { s__ } from '~/locale';
+
+export const I18N = {
+ errorMsg: s__('IncidentManagement|There was an error displaying the incidents.'),
+ noIncidents: s__('IncidentManagement|No incidents to display.'),
+};
diff --git a/app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql b/app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql
new file mode 100644
index 00000000000..4478aa56ee7
--- /dev/null
+++ b/app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql
@@ -0,0 +1,22 @@
+query getIncidents($projectPath: ID!, $labelNames: [String], $state: IssuableState) {
+ project(fullPath: $projectPath) {
+ issues(state: $state, labelName: $labelNames) {
+ nodes {
+ iid
+ title
+ createdAt
+ labels {
+ nodes {
+ title
+ color
+ }
+ }
+ assignees {
+ nodes {
+ username
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/incidents/list.js b/app/assets/javascripts/incidents/list.js
new file mode 100644
index 00000000000..f1599477c1a
--- /dev/null
+++ b/app/assets/javascripts/incidents/list.js
@@ -0,0 +1,34 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import IncidentsList from './components/incidents_list.vue';
+
+Vue.use(VueApollo);
+export default () => {
+ const selector = '#js-incidents';
+
+ const domEl = document.querySelector(selector);
+ const { projectPath } = domEl.dataset;
+
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+ });
+
+ return new Vue({
+ el: selector,
+ provide: {
+ projectPath,
+ },
+ apolloProvider,
+ components: {
+ IncidentsList,
+ },
+ render(createElement) {
+ return createElement('incidents-list', {
+ props: {
+ projectPath,
+ },
+ });
+ },
+ });
+};