diff options
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/sidebar')
4 files changed, 348 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue new file mode 100644 index 00000000000..a88e1310131 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon.vue @@ -0,0 +1,46 @@ +<script> + export default { + name: 'collapsedCalendarIcon', + props: { + containerClass: { + type: String, + required: false, + default: '', + }, + text: { + type: String, + required: false, + default: '', + }, + showIcon: { + type: Boolean, + required: false, + default: true, + }, + }, + methods: { + click() { + this.$emit('click'); + }, + }, + }; +</script> + +<template> + <div + :class="containerClass" + @click="click" + > + <i + v-if="showIcon" + class="fa fa-calendar" + aria-hidden="true" + > + </i> + <slot> + <span> + {{ text }} + </span> + </slot> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue new file mode 100644 index 00000000000..9ede5553bc5 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue @@ -0,0 +1,109 @@ +<script> + import { dateInWords } from '../../../lib/utils/datetime_utility'; + import toggleSidebar from './toggle_sidebar.vue'; + import collapsedCalendarIcon from './collapsed_calendar_icon.vue'; + + export default { + name: 'sidebarCollapsedGroupedDatePicker', + props: { + collapsed: { + type: Boolean, + required: false, + default: true, + }, + showToggleSidebar: { + type: Boolean, + required: false, + default: false, + }, + minDate: { + type: Date, + required: false, + }, + maxDate: { + type: Date, + required: false, + }, + disableClickableIcons: { + type: Boolean, + required: false, + default: false, + }, + }, + components: { + toggleSidebar, + collapsedCalendarIcon, + }, + computed: { + hasMinAndMaxDates() { + return this.minDate && this.maxDate; + }, + hasNoMinAndMaxDates() { + return !this.minDate && !this.maxDate; + }, + showMinDateBlock() { + return this.minDate || this.hasNoMinAndMaxDates; + }, + showFromText() { + return !this.maxDate && this.minDate; + }, + iconClass() { + const disabledClass = this.disableClickableIcons ? 'disabled' : ''; + return `block sidebar-collapsed-icon calendar-icon ${disabledClass}`; + }, + }, + methods: { + toggleSidebar() { + this.$emit('toggleCollapse'); + }, + dateText(dateType = 'min') { + const date = this[`${dateType}Date`]; + const dateWords = dateInWords(date, true); + const parsedDateWords = dateWords ? dateWords.replace(',', '') : dateWords; + + return date ? parsedDateWords : 'None'; + }, + }, + }; +</script> + +<template> + <div class="block sidebar-grouped-item"> + <div + v-if="showToggleSidebar" + class="issuable-sidebar-header" + > + <toggle-sidebar + :collapsed="collapsed" + @toggle="toggleSidebar" + /> + </div> + <collapsed-calendar-icon + v-if="showMinDateBlock" + :container-class="iconClass" + @click="toggleSidebar" + > + <span class="sidebar-collapsed-value"> + <span v-if="showFromText">From</span> + <span>{{ dateText('min') }}</span> + </span> + </collapsed-calendar-icon> + <div + v-if="hasMinAndMaxDates" + class="text-center sidebar-collapsed-divider" + > + - + </div> + <collapsed-calendar-icon + v-if="maxDate" + :container-class="iconClass" + :show-icon="!minDate" + @click="toggleSidebar" + > + <span class="sidebar-collapsed-value"> + <span v-if="!minDate">Until</span> + <span>{{ dateText('max') }}</span> + </span> + </collapsed-calendar-icon> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue new file mode 100644 index 00000000000..9c3413377a3 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue @@ -0,0 +1,163 @@ +<script> + import datePicker from '../pikaday.vue'; + import loadingIcon from '../loading_icon.vue'; + import toggleSidebar from './toggle_sidebar.vue'; + import collapsedCalendarIcon from './collapsed_calendar_icon.vue'; + import { dateInWords } from '../../../lib/utils/datetime_utility'; + + export default { + name: 'sidebarDatePicker', + props: { + collapsed: { + type: Boolean, + required: false, + default: true, + }, + showToggleSidebar: { + type: Boolean, + required: false, + default: false, + }, + isLoading: { + type: Boolean, + required: false, + default: false, + }, + editable: { + type: Boolean, + required: false, + default: false, + }, + label: { + type: String, + required: false, + default: 'Date picker', + }, + selectedDate: { + type: Date, + required: false, + }, + minDate: { + type: Date, + required: false, + }, + maxDate: { + type: Date, + required: false, + }, + }, + data() { + return { + editing: false, + }; + }, + components: { + datePicker, + toggleSidebar, + loadingIcon, + collapsedCalendarIcon, + }, + computed: { + selectedAndEditable() { + return this.selectedDate && this.editable; + }, + selectedDateWords() { + return dateInWords(this.selectedDate, true); + }, + collapsedText() { + return this.selectedDateWords ? this.selectedDateWords : 'None'; + }, + }, + methods: { + stopEditing() { + this.editing = false; + }, + toggleDatePicker() { + this.editing = !this.editing; + }, + newDateSelected(date = null) { + this.date = date; + this.editing = false; + this.$emit('saveDate', date); + }, + toggleSidebar() { + this.$emit('toggleCollapse'); + }, + }, + }; +</script> + +<template> + <div class="block"> + <div class="issuable-sidebar-header"> + <toggle-sidebar + :collapsed="collapsed" + @toggle="toggleSidebar" + /> + </div> + <collapsed-calendar-icon + class="sidebar-collapsed-icon" + :text="collapsedText" + /> + <div class="title"> + {{ label }} + <loading-icon + v-if="isLoading" + :inline="true" + /> + <div class="pull-right"> + <button + v-if="editable && !editing" + type="button" + class="btn-blank btn-link btn-primary-hover-link btn-sidebar-action" + @click="toggleDatePicker" + > + Edit + </button> + <toggle-sidebar + v-if="showToggleSidebar" + :collapsed="collapsed" + @toggle="toggleSidebar" + /> + </div> + </div> + <div class="value"> + <date-picker + v-if="editing" + :selected-date="selectedDate" + :min-date="minDate" + :max-date="maxDate" + :label="label" + @newDateSelected="newDateSelected" + @hidePicker="stopEditing" + /> + <span + v-else + class="value-content" + > + <template v-if="selectedDate"> + <strong>{{ selectedDateWords }}</strong> + <span + v-if="selectedAndEditable" + class="no-value" + > + - + <button + type="button" + class="btn-blank btn-link btn-secondary-hover-link" + @click="newDateSelected(null)" + > + remove + </button> + </span> + </template> + <span + v-else + class="no-value" + > + None + </span> + </span> + </div> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/toggle_sidebar.vue b/app/assets/javascripts/vue_shared/components/sidebar/toggle_sidebar.vue new file mode 100644 index 00000000000..5ae76adad71 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/toggle_sidebar.vue @@ -0,0 +1,30 @@ +<script> + export default { + name: 'toggleSidebar', + props: { + collapsed: { + type: Boolean, + required: true, + }, + }, + methods: { + toggle() { + this.$emit('toggle'); + }, + }, + }; +</script> + +<template> + <button + type="button" + class="btn btn-blank gutter-toggle btn-sidebar-action" + @click="toggle" + > + <i + aria-label="toggle collapse" + class="fa" + :class="{ 'fa-angle-double-right': !collapsed, 'fa-angle-double-left': collapsed }" + ></i> + </button> +</template> |