summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/members/components/table/expiration_datepicker.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/members/components/table/expiration_datepicker.vue')
-rw-r--r--app/assets/javascripts/members/components/table/expiration_datepicker.vue99
1 files changed, 99 insertions, 0 deletions
diff --git a/app/assets/javascripts/members/components/table/expiration_datepicker.vue b/app/assets/javascripts/members/components/table/expiration_datepicker.vue
new file mode 100644
index 00000000000..0a8af81c1d1
--- /dev/null
+++ b/app/assets/javascripts/members/components/table/expiration_datepicker.vue
@@ -0,0 +1,99 @@
+<script>
+import { GlDatepicker } from '@gitlab/ui';
+import { mapActions } from 'vuex';
+import { getDateInFuture } from '~/lib/utils/datetime_utility';
+import { s__ } from '~/locale';
+
+export default {
+ name: 'ExpirationDatepicker',
+ components: { GlDatepicker },
+ props: {
+ member: {
+ type: Object,
+ required: true,
+ },
+ permissions: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ selectedDate: null,
+ busy: false,
+ };
+ },
+ computed: {
+ minDate() {
+ // Members expire at the beginning of the day.
+ // The first selectable day should be tomorrow.
+ const today = new Date();
+ const beginningOfToday = new Date(today.setHours(0, 0, 0, 0));
+
+ return getDateInFuture(beginningOfToday, 1);
+ },
+ disabled() {
+ return (
+ this.busy ||
+ !this.permissions.canUpdate ||
+ (this.permissions.canOverride && !this.member.isOverridden)
+ );
+ },
+ },
+ mounted() {
+ if (this.member.expiresAt) {
+ this.selectedDate = new Date(this.member.expiresAt);
+ }
+ },
+ methods: {
+ ...mapActions(['updateMemberExpiration']),
+ handleInput(date) {
+ this.busy = true;
+ this.updateMemberExpiration({
+ memberId: this.member.id,
+ expiresAt: date,
+ })
+ .then(() => {
+ this.$toast.show(s__('Members|Expiration date updated successfully.'));
+ this.busy = false;
+ })
+ .catch(() => {
+ this.busy = false;
+ });
+ },
+ handleClear() {
+ this.busy = true;
+
+ this.updateMemberExpiration({
+ memberId: this.member.id,
+ expiresAt: null,
+ })
+ .then(() => {
+ this.$toast.show(s__('Members|Expiration date removed successfully.'));
+ this.selectedDate = null;
+ this.busy = false;
+ })
+ .catch(() => {
+ this.busy = false;
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <!-- `:target="null"` allows the datepicker to be opened on focus -->
+ <!-- `:container="null"` renders the datepicker in the body to prevent conflicting CSS table styles -->
+ <gl-datepicker
+ v-model="selectedDate"
+ class="gl-max-w-full"
+ show-clear-button
+ :target="null"
+ :container="null"
+ :min-date="minDate"
+ :placeholder="__('Expiration date')"
+ :disabled="disabled"
+ @input="handleInput"
+ @clear="handleClear"
+ />
+</template>