diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-14 09:09:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-14 09:09:22 +0300 |
commit | 067b3d04573d1473dbc6c81ef775d70c6636ff3f (patch) | |
tree | e05bfa986e49c1527fa93f03b2592f0c1a3da735 /app/assets/javascripts/sidebar | |
parent | ef9eff8e7e1b38f48a354f90ecaeeb67da35b08c (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/sidebar')
4 files changed, 106 insertions, 10 deletions
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/graphql/cache_update.js b/app/assets/javascripts/sidebar/components/time_tracking/graphql/cache_update.js new file mode 100644 index 00000000000..70177d84b1b --- /dev/null +++ b/app/assets/javascripts/sidebar/components/time_tracking/graphql/cache_update.js @@ -0,0 +1,20 @@ +import produce from 'immer'; + +export function removeTimelogFromStore(store, deletedTimelogId, query, variables) { + const sourceData = store.readQuery({ + query, + variables, + }); + + const data = produce(sourceData, (draftData) => { + draftData.issuable.timelogs.nodes = draftData.issuable.timelogs.nodes.filter( + ({ id }) => id !== deletedTimelogId, + ); + }); + + store.writeQuery({ + query, + variables, + data, + }); +} diff --git a/app/assets/javascripts/sidebar/components/time_tracking/graphql/mutations/delete_timelog.mutation.graphql b/app/assets/javascripts/sidebar/components/time_tracking/graphql/mutations/delete_timelog.mutation.graphql new file mode 100644 index 00000000000..17bbad1acb1 --- /dev/null +++ b/app/assets/javascripts/sidebar/components/time_tracking/graphql/mutations/delete_timelog.mutation.graphql @@ -0,0 +1,5 @@ +mutation deleteTimelog($input: TimelogDeleteInput!) { + timelogDelete(input: $input) { + errors + } +} diff --git a/app/assets/javascripts/sidebar/components/time_tracking/report.vue b/app/assets/javascripts/sidebar/components/time_tracking/report.vue index b4c4c31bd7a..79ef5a32474 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/report.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/report.vue @@ -1,11 +1,13 @@ <script> -import { GlLoadingIcon, GlTableLite } from '@gitlab/ui'; +import { GlLoadingIcon, GlTableLite, GlButton, GlTooltipDirective } from '@gitlab/ui'; import createFlash from '~/flash'; import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { formatDate, parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility'; -import { __ } from '~/locale'; +import { __, s__ } from '~/locale'; import { timelogQueries } from '~/sidebar/constants'; +import deleteTimelogMutation from './graphql/mutations/delete_timelog.mutation.graphql'; +import { removeTimelogFromStore } from './graphql/cache_update'; const TIME_DATE_FORMAT = 'mmmm d, yyyy, HH:MM ("UTC:" o)'; @@ -13,6 +15,10 @@ export default { components: { GlLoadingIcon, GlTableLite, + GlButton, + }, + directives: { + GlTooltip: GlTooltipDirective, }, inject: ['issuableType'], props: { @@ -27,7 +33,7 @@ export default { }, }, data() { - return { report: [], isLoading: true }; + return { report: [], isLoading: true, removingIds: [] }; }, apollo: { report: { @@ -35,9 +41,7 @@ export default { return timelogQueries[this.issuableType].query; }, variables() { - return { - id: convertToGraphQLId(this.getGraphQLEntityType(), this.issuableId), - }; + return this.getQueryVariables(); }, update(data) { this.isLoading = false; @@ -48,10 +52,23 @@ export default { }, }, }, + computed: { + deleteButtonTooltip() { + return s__('TimeTracking|Delete time spent'); + }, + }, methods: { + isDeletingTimelog(timelogId) { + return this.removingIds.includes(timelogId); + }, isIssue() { return this.issuableType === 'issue'; }, + getQueryVariables() { + return { + id: convertToGraphQLId(this.getGraphQLEntityType(), this.issuableId), + }; + }, getGraphQLEntityType() { return this.isIssue() ? TYPE_ISSUE : TYPE_MERGE_REQUEST; }, @@ -76,12 +93,44 @@ export default { stringifyTime(parseSeconds(seconds, { limitToHours: this.limitToHours })) ); }, + deleteTimelog(timelogId) { + this.removingIds.push(timelogId); + this.$apollo + .mutate({ + mutation: deleteTimelogMutation, + variables: { input: { id: timelogId } }, + update: (store) => { + removeTimelogFromStore( + store, + timelogId, + timelogQueries[this.issuableType].query, + this.getQueryVariables(), + ); + }, + }) + .then(({ data }) => { + if (data.timelogDelete?.errors?.length) { + throw new Error(data.timelogDelete.errors[0]); + } + }) + .catch((error) => { + createFlash({ + message: s__('TimeTracking|An error occurred while removing the timelog.'), + captureError: true, + error, + }); + }) + .finally(() => { + this.removingIds.splice(this.removingIds.indexOf(timelogId), 1); + }); + }, }, fields: [ - { key: 'spentAt', label: __('Spent At'), sortable: true, tdClass: 'gl-w-quarter' }, + { key: 'spentAt', label: __('Spent at'), sortable: true, tdClass: 'gl-w-quarter' }, { key: 'user', label: __('User'), sortable: true }, - { key: 'timeSpent', label: __('Time Spent'), sortable: true, tdClass: 'gl-w-15' }, - { key: 'summary', label: __('Summary / Note'), sortable: true }, + { key: 'timeSpent', label: __('Time spent'), sortable: true, tdClass: 'gl-w-15' }, + { key: 'summary', label: __('Summary / note'), sortable: true }, + { key: 'actions', label: '', tdClass: 'gl-w-10' }, ], }; </script> @@ -110,7 +159,28 @@ export default { <template #cell(summary)="{ item: { summary, note } }"> <div>{{ getSummary(summary, note) }}</div> </template> - <template #foot(note)> </template> + <template #foot(summary)> </template> + + <template + #cell(actions)="{ + item: { + id, + userPermissions: { adminTimelog }, + }, + }" + > + <div v-if="adminTimelog"> + <gl-button + v-gl-tooltip="{ title: deleteButtonTooltip }" + category="secondary" + icon="remove" + data-testid="deleteButton" + :loading="isDeletingTimelog(id)" + @click="deleteTimelog(id)" + /> + </div> + </template> + <template #foot(actions)> </template> </gl-table-lite> </div> </template> diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue index 057bb9f0100..e39d9f9fb49 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue @@ -252,6 +252,7 @@ export default { size="lg" :title="__('Time tracking report')" :hide-footer="true" + @hide="refresh" > <time-tracking-report :limit-to-hours="limitToHours" :issuable-id="issuableId" /> </gl-modal> |