web/satellite: DatePicker rework (#3157)
This commit is contained in:
parent
d29946d3d7
commit
ef2615fcf4
557
web/satellite/src/components/common/VDatePicker.vue
Normal file
557
web/satellite/src/components/common/VDatePicker.vue
Normal file
@ -0,0 +1,557 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
<div class="cov-vue-date">
|
||||
<div class="datepickbox">
|
||||
<input type="text" title="input date" class="cov-datepicker" readonly="readonly" :style="option.inputStyle ? option.inputStyle : {}" />
|
||||
</div>
|
||||
<div class="datepicker-overlay" v-if="isChecking" @click.self="dismiss" :style="{'background' : option.overlayOpacity? 'rgba(0,0,0,'+option.overlayOpacity+')' : 'rgba(0,0,0,0.5)'}">
|
||||
<div class="cov-date-body" :style="{'background-color': option.color ? option.color.header : '#3f51b5'}">
|
||||
<div class="cov-date-monthly">
|
||||
<div class="cov-date-previous" @click="onPreviousMonthClick">«</div>
|
||||
<div class="cov-date-caption" :style="{'color': option.color ? option.color.headerText : '#fff'}">
|
||||
<span class="year-selection" @click="showYear">{{selectedDateState.year}}</span>
|
||||
<span class="month-selection" @click="showMonth">{{displayedMonth}}</span>
|
||||
</div>
|
||||
<div class="cov-date-next" @click="onNextMonthClick">»</div>
|
||||
</div>
|
||||
<div class="cov-date-box" v-if="isDaysChoiceShown">
|
||||
<div class="cov-picker-box">
|
||||
<div class="week">
|
||||
<ul>
|
||||
<li v-for="week in daysInWeek" :key="week">{{week}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="day" v-for="(day, index) in daysToShow" :key="index" @click="checkDay(day)" :class="{'checked':day.checked,'unavailable':day.unavailable,'passive-day': !(day.inMonth), 'today': day.today}" :style="day.checked ? (option.color && option.color.checkedDay ? { background: option.color.checkedDay } : { background: '#2683FF' }) : {}">{{day.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cov-date-box list-box" v-if="isYearChoiceShown">
|
||||
<div class="cov-picker-box date-list" id="yearList">
|
||||
<div class="date-item year" v-for="yearItem in years" :key="yearItem" @click="setYear(yearItem)">{{yearItem}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cov-date-box list-box" v-if="isMonthChoiceShown">
|
||||
<div class="cov-picker-box date-list">
|
||||
<div class="date-item month" v-for="monthItem in monthsNames" :key="monthItem" @click="setMonth(monthItem)">{{monthItem}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
|
||||
import {
|
||||
DateGenerator,
|
||||
DateStamp,
|
||||
DayAction,
|
||||
DayItem,
|
||||
DisplayedType,
|
||||
Options,
|
||||
} from '@/utils/datepicker';
|
||||
|
||||
@Component
|
||||
export default class VDatePicker extends Vue {
|
||||
@Prop({default: () => new Options()})
|
||||
private option: Options;
|
||||
@Prop({default: () => false})
|
||||
private isSundayFirst: boolean;
|
||||
|
||||
private readonly MAX_DAYS_SELECTED: number = 2;
|
||||
public selectedDays: Date[] = [];
|
||||
|
||||
private showType: number = DisplayedType.Day;
|
||||
private dateGenerator: DateGenerator = new DateGenerator();
|
||||
|
||||
// daysInWeek contains days names abbreviations
|
||||
public readonly daysInWeek: string[] = [];
|
||||
public readonly monthsNames: string[] = [];
|
||||
// years contains years numbers available to choose
|
||||
public readonly years: number[] = [];
|
||||
|
||||
// isChecking indicates when calendar is shown
|
||||
public isChecking: boolean = false;
|
||||
public displayedMonth: string;
|
||||
// daysToShow contains days of selected month with a few extra days from adjacent months
|
||||
public daysToShow: DayItem[] = [];
|
||||
|
||||
// Combination of selected year, month and day
|
||||
public selectedDateState: DateStamp = new DateStamp(0, 0, 0);
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
this.daysInWeek = this.isSundayFirst ? this.option.sundayFirstWeek : this.option.mondayFirstWeek;
|
||||
this.monthsNames = this.option.month;
|
||||
this.displayedMonth = this.monthsNames[0];
|
||||
this.years = this.dateGenerator.populateYears();
|
||||
}
|
||||
|
||||
/**
|
||||
* computed value that indicates should days view be shown
|
||||
*/
|
||||
public get isDaysChoiceShown(): boolean {
|
||||
return this.showType === DisplayedType.Day;
|
||||
}
|
||||
|
||||
/**
|
||||
* computed value that indicates should month choice view be shown
|
||||
*/
|
||||
public get isMonthChoiceShown(): boolean {
|
||||
return this.showType === DisplayedType.Month;
|
||||
}
|
||||
|
||||
/**
|
||||
* computed value that indicates should year choice view be shown
|
||||
*/
|
||||
public get isYearChoiceShown(): boolean {
|
||||
return this.showType === DisplayedType.Year;
|
||||
}
|
||||
|
||||
/**
|
||||
* onPreviousMonthClick set previous month
|
||||
*/
|
||||
public onPreviousMonthClick(): void {
|
||||
this.nextMonth(DayAction.Previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* onNextMonthClick set next month
|
||||
*/
|
||||
public onNextMonthClick(): void {
|
||||
this.nextMonth(DayAction.Next);
|
||||
}
|
||||
|
||||
/**
|
||||
* checkDay toggles checked property of day object
|
||||
*
|
||||
* @param day represent day object to check/uncheck
|
||||
*/
|
||||
public checkDay(day: DayItem): void {
|
||||
if (day.unavailable || !day.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!day.inMonth) {
|
||||
this.nextMonth(day.action);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (day.checked) {
|
||||
day.checked = false;
|
||||
this.selectedDays.splice(this.selectedDays.indexOf(day.moment), 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selectedDays.length < this.MAX_DAYS_SELECTED) {
|
||||
this.selectedDays.push(day.moment);
|
||||
day.checked = true;
|
||||
}
|
||||
|
||||
if (this.selectedDays.length === this.MAX_DAYS_SELECTED) {
|
||||
this.submitSelectedDays();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* setYear selects chosen year
|
||||
*
|
||||
* @param year
|
||||
*/
|
||||
public setYear(year): void {
|
||||
this.populateDays(new Date(year, this.selectedDateState.month, this.selectedDateState.day));
|
||||
}
|
||||
|
||||
/**
|
||||
* setYear selects chosen month
|
||||
*
|
||||
* @param month
|
||||
*/
|
||||
public setMonth(month: string): void {
|
||||
const monthIndex = this.monthsNames.indexOf(month);
|
||||
this.populateDays(new Date(this.selectedDateState.year, monthIndex, this.selectedDateState.day));
|
||||
}
|
||||
|
||||
/**
|
||||
* dismiss closes popup and clears values
|
||||
*/
|
||||
public dismiss(): void {
|
||||
if (!this.option.dismissible) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectedDays = [];
|
||||
this.isChecking = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* showCheck used for external popup opening
|
||||
*/
|
||||
public showCheck(): void {
|
||||
this.populateDays();
|
||||
this.isChecking = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* showYear used for opening choose year view
|
||||
*/
|
||||
public showYear(): void {
|
||||
this.showType = DisplayedType.Year;
|
||||
}
|
||||
|
||||
/**
|
||||
* showMonth used for opening choose month view
|
||||
*/
|
||||
public showMonth(): void {
|
||||
this.showType = DisplayedType.Month;
|
||||
}
|
||||
|
||||
/**
|
||||
* nextMonth set month depends on day action (next or previous)
|
||||
*
|
||||
* @param action represents next or previous type of action
|
||||
*/
|
||||
private nextMonth(action: DayAction): void {
|
||||
const currentMoment = new Date(this.selectedDateState.year, this.selectedDateState.month, this.selectedDateState.day);
|
||||
const currentMonth = currentMoment.getMonth();
|
||||
const now = new Date();
|
||||
|
||||
switch (action) {
|
||||
case DayAction.Next:
|
||||
if (currentMonth === now.getMonth() && currentMoment.getFullYear() === now.getFullYear()) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentMoment.setMonth(currentMonth + 1);
|
||||
break;
|
||||
case DayAction.Previous:
|
||||
currentMoment.setMonth(currentMonth - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
this.populateDays(currentMoment);
|
||||
}
|
||||
|
||||
/**
|
||||
* submitSelectedDays emits function to receive selected dates externally and then clears state
|
||||
*/
|
||||
private submitSelectedDays(): void {
|
||||
this.$emit('change', this.selectedDays);
|
||||
this.isChecking = false;
|
||||
this.selectedDays = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* populateDays used for populating date items into calendars depending on selected date
|
||||
*
|
||||
* @param date represents Date which is used to create current date items to show
|
||||
*/
|
||||
private populateDays(date: Date = new Date()): void {
|
||||
this.selectedDateState.fromDate(date);
|
||||
this.showType = DisplayedType.Day;
|
||||
this.displayedMonth = this.monthsNames[this.selectedDateState.month];
|
||||
this.daysToShow = this.dateGenerator.populateDays(this.selectedDateState, this.isSundayFirst);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.datepicker-overlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
-webkit-animation: fadein 0.5s;
|
||||
/* Safari, Chrome and Opera > 12.1 */
|
||||
-moz-animation: fadein 0.5s;
|
||||
/* Firefox < 16 */
|
||||
-ms-animation: fadein 0.5s;
|
||||
/* Internet Explorer */
|
||||
-o-animation: fadein 0.5s;
|
||||
/* Opera < 12.1 */
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Firefox < 16 */
|
||||
@-moz-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Safari, Chrome and Opera > 12.1 */
|
||||
@-webkit-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Internet Explorer */
|
||||
@-ms-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Opera < 12.1 */
|
||||
@-o-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.cov-date-body {
|
||||
background: #3F51B5;
|
||||
overflow: hidden;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
position: fixed;
|
||||
display: block;
|
||||
width: 400px;
|
||||
max-width: 100%;
|
||||
z-index: 999;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
font-family: 'font_medium';
|
||||
}
|
||||
|
||||
.cov-picker-box {
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
padding: 25px;
|
||||
box-sizing: border-box !important;
|
||||
-moz-box-sizing: border-box !important;
|
||||
-webkit-box-sizing: border-box !important;
|
||||
-ms-box-sizing: border-box !important;
|
||||
width: 400px;
|
||||
max-width: 100%;
|
||||
height: 280px;
|
||||
text-align: start !important;
|
||||
}
|
||||
|
||||
.day {
|
||||
width: 14.2857143%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
height: 34px;
|
||||
padding: 0;
|
||||
line-height: 34px;
|
||||
color: #000;
|
||||
background: #fff;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.week ul {
|
||||
margin: 0 0 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.week ul li {
|
||||
width: 14.2%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
background: transparent;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.passive-day {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.checked {
|
||||
background: #2683FF;
|
||||
color: #FFF !important;
|
||||
}
|
||||
|
||||
.unavailable {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.cov-date-monthly {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.cov-date-monthly > div {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
color: #fff;
|
||||
height: 50px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cov-date-previous,
|
||||
.cov-date-next {
|
||||
position: relative;
|
||||
width: 20% !important;
|
||||
text-indent: -300px;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.cov-date-caption {
|
||||
width: 60%;
|
||||
padding: 10px 0 !important;
|
||||
box-sizing: border-box;
|
||||
font-size: 18px;
|
||||
font-family: 'font_medium';
|
||||
line-height: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.month-selection,
|
||||
.year-selection {
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
.cov-date-previous:hover,
|
||||
.cov-date-next:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.day:hover {
|
||||
background: #EAEAEA;
|
||||
}
|
||||
|
||||
.unavailable:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.cov-date-next::before,
|
||||
.cov-date-previous::before {
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
margin-left: -7px;
|
||||
left: 50%;
|
||||
line-height: 0;
|
||||
content: '';
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.cov-date-next::after,
|
||||
.cov-date-previous::after {
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
margin-top: 6px;
|
||||
margin-left: -7px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
line-height: 0;
|
||||
content: '';
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.cov-date-previous::after {
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.cov-date-previous::before {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.date-item {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
padding: 10px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.date-item:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.date-list {
|
||||
overflow: auto;
|
||||
vertical-align: top;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cov-vue-date {
|
||||
display: inline-block;
|
||||
color: #5D5D5D;
|
||||
}
|
||||
|
||||
.watch-box {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: #E3E3E3;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #C1C1C1;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.cov-date-box {
|
||||
font-family: 'font_medium';
|
||||
}
|
||||
|
||||
.today {
|
||||
background: lightblue;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
@ -1,855 +0,0 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
// TODO: temporary file
|
||||
<style scoped lang="scss">
|
||||
.datepicker-overlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
-webkit-animation: fadein 0.5s;
|
||||
/* Safari, Chrome and Opera > 12.1 */
|
||||
-moz-animation: fadein 0.5s;
|
||||
/* Firefox < 16 */
|
||||
-ms-animation: fadein 0.5s;
|
||||
/* Internet Explorer */
|
||||
-o-animation: fadein 0.5s;
|
||||
/* Opera < 12.1 */
|
||||
animation: fadein 0.5s;
|
||||
}
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
/* Firefox < 16 */
|
||||
@-moz-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
/* Safari, Chrome and Opera > 12.1 */
|
||||
@-webkit-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
/* Internet Explorer */
|
||||
@-ms-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
/* Opera < 12.1 */
|
||||
@-o-keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.cov-date-body {
|
||||
display: inline-block;
|
||||
background: #3F51B5;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
font-family: 'Roboto';
|
||||
font-weight: 400;
|
||||
position: fixed;
|
||||
display: block;
|
||||
width: 400px;
|
||||
max-width: 100%;
|
||||
z-index: 999;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
font-family: 'font_medium';
|
||||
}
|
||||
.cov-picker-box {
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
padding: 25px;
|
||||
box-sizing: border-box !important;
|
||||
-moz-box-sizing: border-box !important;
|
||||
-webkit-box-sizing: border-box !important;
|
||||
-ms-box-sizing: border-box !important;
|
||||
width: 400px;
|
||||
max-width: 100%;
|
||||
height: 280px;
|
||||
text-align: start!important;
|
||||
}
|
||||
.cov-picker-box td {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
padding: 0;
|
||||
line-height: 34px;
|
||||
color: #000;
|
||||
background: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cov-picker-box td:hover {
|
||||
background: #E6E6E6;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.day {
|
||||
width: 14.2857143%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
height: 34px;
|
||||
padding: 0;
|
||||
line-height: 34px;
|
||||
color: #000;
|
||||
background: #fff;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.week ul {
|
||||
margin: 0 0 8px;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.week ul li {
|
||||
width: 14.2%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
background: transparent;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.passive-day {
|
||||
color: #bbb;
|
||||
}
|
||||
.checked {
|
||||
background: #2683FF;
|
||||
color: #FFF !important;
|
||||
}
|
||||
.unavailable {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.cov-date-monthly {
|
||||
height: 50px;
|
||||
}
|
||||
.cov-date-monthly > div {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
color: #fff;
|
||||
height: 50px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
}
|
||||
.cov-date-previous,
|
||||
.cov-date-next {
|
||||
position: relative;
|
||||
width: 20% !important;
|
||||
text-indent: -300px;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
}
|
||||
.cov-date-caption {
|
||||
width: 60%;
|
||||
padding: 10px 0!important;
|
||||
box-sizing: border-box;
|
||||
font-size: 18px;
|
||||
font-family: 'font_medium';
|
||||
line-height: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
padding: 0 3px;
|
||||
}
|
||||
}
|
||||
.cov-date-previous:hover,
|
||||
.cov-date-next:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.day:hover {
|
||||
background: #EAEAEA;
|
||||
}
|
||||
.unavailable:hover {
|
||||
background: none;
|
||||
}
|
||||
.cov-date-next::before,
|
||||
.cov-date-previous::before {
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
margin-left: -7px;
|
||||
left: 50%;
|
||||
line-height: 0;
|
||||
content: '';
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.cov-date-next::after,
|
||||
.cov-date-previous::after {
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
margin-top: 6px;
|
||||
margin-left: -7px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
line-height: 0;
|
||||
content: '';
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.cov-date-previous::after {
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.cov-date-previous::before {
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.date-item {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
padding: 10px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.date-item:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
.date-list {
|
||||
overflow: auto;
|
||||
vertical-align: top;
|
||||
padding: 0;
|
||||
}
|
||||
.cov-vue-date {
|
||||
display: inline-block;
|
||||
color: #5D5D5D;
|
||||
}
|
||||
.button-box {
|
||||
background: #fff;
|
||||
vertical-align: top;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: right;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.button-box span {
|
||||
cursor: pointer;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.watch-box {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hour-box,
|
||||
.min-box {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
float: left;
|
||||
}
|
||||
.hour-box ul,
|
||||
.min-box ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.hour-item,
|
||||
.min-item {
|
||||
padding: 10px;
|
||||
font-size: 36px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.hour-item:hover,
|
||||
.min-item:hover {
|
||||
background: #E3E3E3;
|
||||
}
|
||||
.hour-box .active,
|
||||
.min-box .active {
|
||||
background: #F50057;
|
||||
color: #FFF !important;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 2px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #E3E3E3;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #C1C1C1;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.cov-date-box {
|
||||
font-family: 'font_medium';
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="cov-vue-date">
|
||||
<div class="datepickbox">
|
||||
<input type="text" title="input date" class="cov-datepicker" readonly="readonly" :placeholder="option.placeholder" v-model="date.time" :required="required" :style="option.inputStyle ? option.inputStyle : {}" />
|
||||
</div>
|
||||
<div class="datepicker-overlay" v-if="showInfo.check" @click="dismiss($event)" v-bind:style="{'background' : option.overlayOpacity? 'rgba(0,0,0,'+option.overlayOpacity+')' : 'rgba(0,0,0,0.5)'}">
|
||||
<div class="cov-date-body" :style="{'background-color': option.color ? option.color.header : '#3f51b5'}">
|
||||
<div class="cov-date-monthly">
|
||||
<div class="cov-date-previous" @click="nextMonth('pre')">«</div>
|
||||
<div class="cov-date-caption" :style="{'color': option.color ? option.color.headerText : '#fff'}">
|
||||
<span @click="showYear">{{checked.year}}</span>
|
||||
<span @click="showMonth">{{displayInfo.month}}</span>
|
||||
</div>
|
||||
<div class="cov-date-next" @click="nextMonth('next')">»</div>
|
||||
</div>
|
||||
<div class="cov-date-box" v-if="showInfo.day">
|
||||
<div class="cov-picker-box">
|
||||
<div class="week">
|
||||
<ul>
|
||||
<li v-for="weekie in library.week">{{weekie}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="day" v-for="day in dayList" track-by="$index" @click="checkDay(day)" :class="{'checked':day.checked,'unavailable':day.unavailable,'passive-day': !(day.inMonth)}" :style="day.checked ? (option.color && option.color.checkedDay ? { background: option.color.checkedDay } : { background: '#2683FF' }) : {}">{{day.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cov-date-box list-box" v-if="showInfo.year">
|
||||
<div class="cov-picker-box date-list" id="yearList">
|
||||
<div class="date-item" v-for="yearItem in library.year" track-by="$index" @click="setYear(yearItem)">{{yearItem}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cov-date-box list-box" v-if="showInfo.month">
|
||||
<div class="cov-picker-box date-list">
|
||||
<div class="date-item" v-for="monthItem in library.month" track-by="$index" @click="setMonth(monthItem)">{{monthItem}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cov-date-box list-box" v-if="showInfo.hour">
|
||||
<div class="cov-picker-box date-list">
|
||||
<div class="watch-box">
|
||||
<div class="hour-box">
|
||||
<div class="mui-pciker-rule mui-pciker-rule-ft"></div>
|
||||
<ul>
|
||||
<li class="hour-item" v-for="hitem in hours" @click="setTime('hour', hitem, hours)" :class="{'active':hitem.checked}">{{hitem.value}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="min-box">
|
||||
<div class="mui-pciker-rule mui-pciker-rule-ft"></div>
|
||||
<div class="min-item" v-for="mitem in mins" @click="setTime('min',mitem, mins)" :class="{'active':mitem.checked}">{{mitem.value}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="js">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
let _moment = require('moment');
|
||||
|
||||
let _moment2 = _interopRequireDefault(_moment);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
@Component({
|
||||
props: {
|
||||
required: false,
|
||||
date: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
option: {
|
||||
type: Object,
|
||||
default: function _default() {
|
||||
return {
|
||||
type: 'multi-day',
|
||||
SundayFirst: false,
|
||||
week: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
||||
month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||||
format: 'YYYY-DD-MM',
|
||||
color: {
|
||||
checked: '#2683FF',
|
||||
header: '#2683FF',
|
||||
headerText: '#444C63'
|
||||
},
|
||||
inputStyle: {
|
||||
'visibility': 'hidden',
|
||||
'width': '0',
|
||||
},
|
||||
placeholder: '',
|
||||
buttons: {
|
||||
ok: 'OK',
|
||||
cancel: 'Cancel'
|
||||
},
|
||||
overlayOpacity: 0.5,
|
||||
dismissible: true
|
||||
};
|
||||
}
|
||||
},
|
||||
limit: {
|
||||
type: Array,
|
||||
default: function _default() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data: function data() {
|
||||
function hours() {
|
||||
let list = [];
|
||||
let hour = 24;
|
||||
while (hour > 0) {
|
||||
hour--;
|
||||
list.push({
|
||||
checked: false,
|
||||
value: hour < 10 ? '0' + hour : hour
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
function mins() {
|
||||
let list = [];
|
||||
let min = 60;
|
||||
while (min > 0) {
|
||||
min--;
|
||||
list.push({
|
||||
checked: false,
|
||||
value: min < 10 ? '0' + min : min
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return {
|
||||
hours: hours(),
|
||||
mins: mins(),
|
||||
showInfo: {
|
||||
hour: false,
|
||||
day: false,
|
||||
month: false,
|
||||
year: false,
|
||||
check: false
|
||||
},
|
||||
displayInfo: {
|
||||
month: ''
|
||||
},
|
||||
library: {
|
||||
week: this.option.week,
|
||||
month: this.option.month,
|
||||
year: []
|
||||
},
|
||||
checked: {
|
||||
oldtime: '',
|
||||
currentMoment: null,
|
||||
year: '',
|
||||
month: '',
|
||||
day: '',
|
||||
hour: '00',
|
||||
min: '00'
|
||||
},
|
||||
dayList: [],
|
||||
selectedDays: []
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
pad: function pad(n) {
|
||||
n = Math.floor(n);
|
||||
|
||||
return n < 10 ? '0' + n : n;
|
||||
},
|
||||
nextMonth: function nextMonth(type) {
|
||||
let next = null;
|
||||
let currentMoment = (0, _moment2.default)(this.checked.currentMoment);
|
||||
if (type === 'next') {
|
||||
if (currentMoment.format('MM') === (0, _moment2.default)(new Date()).format('MM')) {
|
||||
return;
|
||||
}
|
||||
next = (0, _moment2.default)(this.checked.currentMoment).add(1, 'M');
|
||||
} else {
|
||||
next = (0, _moment2.default)(this.checked.currentMoment).add(-1, 'M');
|
||||
}
|
||||
this.showDay(next);
|
||||
},
|
||||
showDay: function showDay(time) {
|
||||
if (time === undefined || !Date.parse(time)) {
|
||||
this.checked.currentMoment = (0, _moment2.default)();
|
||||
} else {
|
||||
this.checked.currentMoment = (0, _moment2.default)(time, this.option.format);
|
||||
}
|
||||
this.showOne('day');
|
||||
this.checked.year = (0, _moment2.default)(this.checked.currentMoment).format('YYYY');
|
||||
this.checked.month = (0, _moment2.default)(this.checked.currentMoment).format('MM');
|
||||
this.checked.day = (0, _moment2.default)(this.checked.currentMoment).format('DD');
|
||||
this.displayInfo.month = this.library.month[(0, _moment2.default)(this.checked.currentMoment).month()];
|
||||
let days = [];
|
||||
let currentMoment = this.checked.currentMoment;
|
||||
let firstDay = (0, _moment2.default)(currentMoment).date(1).day();
|
||||
// getting previous and next month
|
||||
// let currentMonth = moment(currentMoment)
|
||||
let previousMonth = (0, _moment2.default)(currentMoment);
|
||||
let nextMonth = (0, _moment2.default)(currentMoment);
|
||||
nextMonth.add(1, 'months');
|
||||
previousMonth.subtract(1, 'months');
|
||||
let monthDays = (0, _moment2.default)(currentMoment).daysInMonth();
|
||||
let now = (0, _moment2.default)(new Date());
|
||||
let oldtime = this.checked.oldtime;
|
||||
for (let i = 1; i <= monthDays; ++i) {
|
||||
days.push({
|
||||
value: i,
|
||||
inMonth: this.checked.month !== now.format('MM') || (this.checked.month === now.format('MM') && i<= now.format('DD')),
|
||||
unavailable: false,
|
||||
checked: false,
|
||||
moment: (0, _moment2.default)(currentMoment).date(i)
|
||||
});
|
||||
if (i === Math.ceil((0, _moment2.default)(currentMoment).format('D')) && (0, _moment2.default)(oldtime, this.option.format).year() === (0, _moment2.default)(currentMoment).year() && (0, _moment2.default)(oldtime, this.option.format).month() === (0, _moment2.default)(currentMoment).month()) {
|
||||
days[i - 1].checked = true;
|
||||
}
|
||||
this.checkBySelectDays(i, days);
|
||||
}
|
||||
if (firstDay === 0) firstDay = 7;
|
||||
for (let _i = 0; _i < firstDay - (this.option.SundayFirst ? 0 : 1); _i++) {
|
||||
let passiveDay = {
|
||||
value: previousMonth.daysInMonth() - _i,
|
||||
inMonth: false,
|
||||
action: 'previous',
|
||||
unavailable: false,
|
||||
checked: false,
|
||||
moment: (0, _moment2.default)(currentMoment).date(1).subtract(_i + 1, 'days')
|
||||
};
|
||||
days.unshift(passiveDay);
|
||||
}
|
||||
if (this.limit.length > 0) {
|
||||
let _iteratorNormalCompletion = true;
|
||||
let _didIteratorError = false;
|
||||
let _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (let _iterator = this.limit[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
let li = _step.value;
|
||||
|
||||
switch (li.type) {
|
||||
case 'fromto':
|
||||
days = this.limitFromTo(li, days);
|
||||
break;
|
||||
case 'weekday':
|
||||
days = this.limitWeekDay(li, days);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let passiveDaysAtFinal = 42 - days.length;
|
||||
for (let _i2 = 1; _i2 <= passiveDaysAtFinal; _i2++) {
|
||||
let _passiveDay = {
|
||||
value: _i2,
|
||||
inMonth: false,
|
||||
action: 'next',
|
||||
unavailable: false,
|
||||
checked: false,
|
||||
moment: (0, _moment2.default)(currentMoment).add(1, 'months').date(_i2)
|
||||
};
|
||||
days.push(_passiveDay);
|
||||
}
|
||||
this.dayList = days;
|
||||
},
|
||||
checkBySelectDays: function checkBySelectDays(d, days) {
|
||||
let _this = this;
|
||||
|
||||
this.selectedDays.forEach(function (day) {
|
||||
if (_this.checked.year === (0, _moment2.default)(day).format('YYYY') && _this.checked.month === (0, _moment2.default)(day).format('MM') && d === Math.ceil((0, _moment2.default)(day).format('D'))) {
|
||||
days[d - 1].checked = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
limitWeekDay: function limitWeekDay(limit, days) {
|
||||
days.map(function (day) {
|
||||
if (limit.available.indexOf(Math.floor(day.moment.format('d'))) === -1) {
|
||||
day.unavailable = true;
|
||||
}
|
||||
});
|
||||
|
||||
return days;
|
||||
},
|
||||
limitFromTo: function limitFromTo(limit, days) {
|
||||
let _this2 = this;
|
||||
|
||||
if (limit.from || limit.to) {
|
||||
days.map(function (day) {
|
||||
if (_this2.getLimitCondition(limit, day)) {
|
||||
day.unavailable = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return days;
|
||||
},
|
||||
getLimitCondition: function getLimitCondition(limit, day) {
|
||||
let tmpMoment = (0, _moment2.default)(this.checked.year + '-' + this.pad(this.checked.month) + '-' + this.pad(day.value));
|
||||
if (limit.from && !limit.to) {
|
||||
return !tmpMoment.isAfter(limit.from);
|
||||
} else if (!limit.from && limit.to) {
|
||||
return !tmpMoment.isBefore(limit.to);
|
||||
} else {
|
||||
return !tmpMoment.isBetween(limit.from, limit.to);
|
||||
}
|
||||
},
|
||||
checkDay: function checkDay(obj) {
|
||||
if (obj.unavailable || obj.value === '') {
|
||||
return false;
|
||||
}
|
||||
if (!obj.inMonth) {
|
||||
// this.nextMonth(obj.action);
|
||||
return;
|
||||
}
|
||||
if (this.option.type === 'day' || this.option.type === 'min') {
|
||||
this.dayList.forEach(function (x) {
|
||||
x.checked = false;
|
||||
});
|
||||
this.checked.day = this.pad(obj.value);
|
||||
obj.checked = true;
|
||||
} else {
|
||||
let day = this.pad(obj.value);
|
||||
let ctime = this.checked.year + '-' + this.checked.month + '-' + day;
|
||||
if (obj.checked === true) {
|
||||
obj.checked = false;
|
||||
this.selectedDays.splice(this.selectedDays.indexOf(ctime), 1);
|
||||
} else {
|
||||
if (this.selectedDays.length < 2) {
|
||||
this.selectedDays.push(ctime);
|
||||
obj.checked = true;
|
||||
}
|
||||
|
||||
if (this.selectedDays.length === 2) {
|
||||
this.$emit('change', this.selectedDays);
|
||||
this.showInfo.check = false;
|
||||
this.selectedDays = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (this.option.type) {
|
||||
case 'day':
|
||||
this.picked();
|
||||
break;
|
||||
case 'min':
|
||||
this.showOne('hour');
|
||||
// shift activated time items to visible position.
|
||||
this.shiftActTime();
|
||||
break;
|
||||
}
|
||||
},
|
||||
showYear: function showYear() {
|
||||
let _this3 = this;
|
||||
|
||||
let year = (0, _moment2.default)(this.checked.currentMoment).year();
|
||||
this.library.year = [];
|
||||
let yearTmp = [];
|
||||
for (let i = year - 100; i < year + 5; ++i) {
|
||||
yearTmp.push(i);
|
||||
}
|
||||
this.library.year = yearTmp;
|
||||
this.showOne('year');
|
||||
this.$nextTick(function () {
|
||||
let listDom = document.getElementById('yearList');
|
||||
listDom.scrollTop = listDom.scrollHeight - 100;
|
||||
_this3.addYear();
|
||||
});
|
||||
},
|
||||
showOne: function showOne(type) {
|
||||
switch (type) {
|
||||
case 'year':
|
||||
this.showInfo.hour = false;
|
||||
this.showInfo.day = false;
|
||||
this.showInfo.year = true;
|
||||
this.showInfo.month = false;
|
||||
break;
|
||||
case 'month':
|
||||
this.showInfo.hour = false;
|
||||
this.showInfo.day = false;
|
||||
this.showInfo.year = false;
|
||||
this.showInfo.month = true;
|
||||
break;
|
||||
case 'day':
|
||||
this.showInfo.hour = false;
|
||||
this.showInfo.day = true;
|
||||
this.showInfo.year = false;
|
||||
this.showInfo.month = false;
|
||||
break;
|
||||
case 'hour':
|
||||
this.showInfo.hour = true;
|
||||
this.showInfo.day = false;
|
||||
this.showInfo.year = false;
|
||||
this.showInfo.month = false;
|
||||
break;
|
||||
default:
|
||||
this.showInfo.day = true;
|
||||
this.showInfo.year = false;
|
||||
this.showInfo.month = false;
|
||||
this.showInfo.hour = false;
|
||||
}
|
||||
},
|
||||
showMonth: function showMonth() {
|
||||
this.showOne('month');
|
||||
},
|
||||
addYear: function addYear() {
|
||||
let _this4 = this;
|
||||
|
||||
let listDom = document.getElementById('yearList');
|
||||
listDom.addEventListener('scroll', function (e) {
|
||||
if (listDom.scrollTop >= listDom.scrollHeight - 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
let len = _this4.library.year.length;
|
||||
let lastYear = _this4.library.year[len - 1];
|
||||
_this4.library.year.push(lastYear + 1);
|
||||
}, false);
|
||||
},
|
||||
setYear: function setYear(year) {
|
||||
this.checked.currentMoment = (0, _moment2.default)(year + '-' + this.checked.month + '-' + this.checked.day);
|
||||
this.showDay(this.checked.currentMoment);
|
||||
},
|
||||
setMonth: function setMonth(month) {
|
||||
let mo = this.library.month.indexOf(month) + 1;
|
||||
if (mo < 10) {
|
||||
mo = '0' + '' + mo;
|
||||
}
|
||||
this.checked.currentMoment = (0, _moment2.default)(this.checked.year + '-' + mo + '-' + this.checked.day);
|
||||
this.showDay(this.checked.currentMoment);
|
||||
},
|
||||
showCheck: function showCheck() {
|
||||
if (this.date.time === '') {
|
||||
this.showDay();
|
||||
} else {
|
||||
if (this.option.type === 'day' || this.option.type === 'min') {
|
||||
this.checked.oldtime = this.date.time;
|
||||
this.showDay(this.date.time);
|
||||
} else {
|
||||
this.selectedDays = JSON.parse(this.date.time);
|
||||
if (this.selectedDays.length) {
|
||||
this.checked.oldtime = this.selectedDays[0];
|
||||
this.showDay(this.selectedDays[0]);
|
||||
} else {
|
||||
this.showDay();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.showInfo.check = true;
|
||||
},
|
||||
setTime: function setTime(type, obj, list) {
|
||||
let _iteratorNormalCompletion2 = true;
|
||||
let _didIteratorError2 = false;
|
||||
let _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (let _iterator2 = list[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
let item = _step2.value;
|
||||
|
||||
item.checked = false;
|
||||
if (item.value === obj.value) {
|
||||
item.checked = true;
|
||||
this.checked[type] = item.value;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
picked: function picked() {
|
||||
if (this.option.type === 'day' || this.option.type === 'min') {
|
||||
let ctime = this.checked.year + '-' + this.checked.month + '-' + this.checked.day + ' ' + this.checked.hour + ':' + this.checked.min;
|
||||
this.checked.currentMoment = (0, _moment2.default)(ctime, 'YYYY-MM-DD HH:mm');
|
||||
this.date.time = (0, _moment2.default)(this.checked.currentMoment).format(this.option.format);
|
||||
} else {
|
||||
this.date.time = JSON.stringify(this.selectedDays);
|
||||
}
|
||||
this.showInfo.check = false;
|
||||
this.$emit('change', this.date.time);
|
||||
},
|
||||
dismiss: function dismiss(evt) {
|
||||
if (evt.target.className !== 'datepicker-overlay') {
|
||||
return;
|
||||
}
|
||||
if (!this.option.dismissible) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showInfo.check = false;
|
||||
this.$emit('cancel');
|
||||
},
|
||||
shiftActTime: function shiftActTime() {
|
||||
// shift activated time items to visible position.
|
||||
this.$nextTick(function () {
|
||||
if (!document.querySelector('.hour-item.active')) {
|
||||
return false;
|
||||
}
|
||||
document.querySelector('.hour-box').scrollTop = (document.querySelector('.hour-item.active').offsetTop || 0) - 250;
|
||||
document.querySelector('.min-box').scrollTop = (document.querySelector('.min-item.active').offsetTop || 0) - 250;
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default class DatePicker extends Vue {}
|
||||
</script>
|
@ -15,7 +15,7 @@
|
||||
</div>
|
||||
<div class="usage-report-container__options-area__option" @click.prevent.self="onCustomDateClick">
|
||||
<p class="usage-report-container__options-area__option__label" @click.prevent.self="onCustomDateClick">Custom Date Range</p>
|
||||
<Datepicker
|
||||
<VDatepicker
|
||||
ref="datePicker"
|
||||
:date="startTime"
|
||||
@change="getDates"
|
||||
@ -58,7 +58,7 @@
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
import Datepicker from '@/components/project/DatePicker.vue';
|
||||
import VDatepicker from '@/components/common/VDatePicker.vue';
|
||||
|
||||
import { RouteConfig } from '@/router';
|
||||
import { PROJECT_USAGE_ACTIONS } from '@/store/modules/usage';
|
||||
@ -68,15 +68,15 @@ import { toUnixTimestamp } from '@/utils/time';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
Datepicker,
|
||||
VDatepicker,
|
||||
},
|
||||
})
|
||||
export default class UsageReport extends Vue {
|
||||
public startTime: any = {
|
||||
time: '',
|
||||
public readonly startTime = {
|
||||
time: null,
|
||||
};
|
||||
|
||||
private readonly dateRange: any;
|
||||
private readonly dateRange;
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
@ -179,7 +179,7 @@ export default class UsageReport extends Vue {
|
||||
window.open(url.href, '_blank');
|
||||
}
|
||||
|
||||
public async getDates(datesArray: string[]): Promise<void> {
|
||||
public async getDates(datesArray: Date[]): Promise<void> {
|
||||
const now = new Date();
|
||||
const firstDate = new Date(datesArray[0]);
|
||||
const secondDate = new Date(datesArray[1]);
|
||||
@ -240,7 +240,7 @@ export default class UsageReport extends Vue {
|
||||
<style scoped lang="scss">
|
||||
.usage-report-container {
|
||||
position: relative;
|
||||
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -424,7 +424,7 @@ export default class UsageReport extends Vue {
|
||||
|
||||
@media screen and (max-width: 1600px) {
|
||||
.usage-report-container {
|
||||
|
||||
|
||||
&__header {
|
||||
|
||||
&__title {
|
||||
|
200
web/satellite/src/utils/datepicker.ts
Normal file
200
web/satellite/src/utils/datepicker.ts
Normal file
@ -0,0 +1,200 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
/**
|
||||
* Options is a set of options used for VDatePicker.vue
|
||||
*/
|
||||
export class Options {
|
||||
public constructor(
|
||||
public mondayFirstWeek: string[] = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
||||
public sundayFirstWeek: string[] = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
|
||||
public month: string[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||||
public color = {
|
||||
checked: '#2683FF',
|
||||
header: '#2683FF',
|
||||
headerText: '#444C63',
|
||||
},
|
||||
public inputStyle = {
|
||||
'visibility': 'hidden',
|
||||
'width': '0',
|
||||
},
|
||||
public overlayOpacity: number = 0.5,
|
||||
public dismissible: boolean = true,
|
||||
) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* DayItem is used to store information about day cell in calendar
|
||||
*/
|
||||
export class DayItem {
|
||||
public constructor(
|
||||
public value: number,
|
||||
public inMonth: boolean,
|
||||
public unavailable: boolean,
|
||||
public checked: boolean,
|
||||
public moment: Date,
|
||||
public action: DayAction = DayAction.Default,
|
||||
public today: boolean = false,
|
||||
) {}
|
||||
|
||||
public equals(dateToCompare: Date): boolean {
|
||||
const isDayEqual = this.moment.getDate() === dateToCompare.getDate();
|
||||
const isMonthEqual = this.moment.getMonth() === dateToCompare.getMonth();
|
||||
const isYearEqual = this.moment.getFullYear() === dateToCompare.getFullYear();
|
||||
|
||||
return isDayEqual && isMonthEqual && isYearEqual;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DayAction is enum represents month change direction on day click
|
||||
*/
|
||||
export enum DayAction {
|
||||
Next,
|
||||
Previous,
|
||||
Default,
|
||||
}
|
||||
|
||||
/**
|
||||
* DateStamp is cozy representation of Date for view
|
||||
*/
|
||||
export class DateStamp {
|
||||
public constructor(
|
||||
public year: number,
|
||||
public month: number,
|
||||
public day: number,
|
||||
) {}
|
||||
|
||||
public fromDate(date: Date): void {
|
||||
this.year = date.getFullYear();
|
||||
this.month = date.getMonth();
|
||||
this.day = date.getDate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DisplayedType is enum represents view type to show in calendar to check
|
||||
*/
|
||||
export enum DisplayedType {
|
||||
Day,
|
||||
Month,
|
||||
Year,
|
||||
}
|
||||
|
||||
/**
|
||||
* DateGenerator is utility class used for generating DayItem and year lists for calendar
|
||||
*/
|
||||
export class DateGenerator {
|
||||
private current: DateStamp;
|
||||
private isSundayFirst: boolean;
|
||||
|
||||
public populateDays(current: DateStamp, isSundayFirst: boolean): DayItem[] {
|
||||
this.current = current;
|
||||
this.isSundayFirst = isSundayFirst;
|
||||
|
||||
const days: DayItem[] = [];
|
||||
|
||||
this.populateSelectedMonthDays(days);
|
||||
this.populatePreviousMonthDays(days);
|
||||
this.populateNextMonthDays(days);
|
||||
this.markToday(days);
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
public populateYears(): number[] {
|
||||
const year = new Date().getFullYear();
|
||||
const years: number[] = [];
|
||||
for (let i = year - 99; i <= year; i++) {
|
||||
years.unshift(i);
|
||||
}
|
||||
|
||||
return years;
|
||||
}
|
||||
|
||||
private populateSelectedMonthDays(days: DayItem[]): void {
|
||||
const daysInSelectedMonth = new Date(this.current.year, this.current.month + 1, 0).getDate();
|
||||
const now = new Date();
|
||||
const daysInCurrentMonth = now.getMonth();
|
||||
|
||||
for (let i = 1; i <= daysInSelectedMonth; i++) {
|
||||
const moment = new Date(this.current.year, this.current.month, this.current.day);
|
||||
moment.setDate(i);
|
||||
|
||||
days.push(
|
||||
new DayItem(
|
||||
i,
|
||||
this.current.month !== daysInCurrentMonth || (this.current.month === daysInCurrentMonth && i <= now.getDate()),
|
||||
false,
|
||||
false,
|
||||
moment,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private populatePreviousMonthDays(days: DayItem[]): void {
|
||||
const previousMonth = new Date(this.current.year, this.current.month, this.current.day);
|
||||
previousMonth.setMonth(previousMonth.getMonth() - 1);
|
||||
|
||||
const firstDate = new Date(this.current.year, this.current.month, this.current.day);
|
||||
firstDate.setDate(1);
|
||||
let firstDay = firstDate.getDay();
|
||||
|
||||
if (firstDay === 0) firstDay = 7;
|
||||
const daysInPreviousMonth = new Date(previousMonth.getFullYear(), previousMonth.getMonth() + 1, 0).getDate();
|
||||
|
||||
for (let i = 0; i < firstDay - (this.isSundayFirst ? 0 : 1); i++) {
|
||||
const moment = new Date(this.current.year, this.current.month, this.current.day);
|
||||
moment.setDate(1);
|
||||
moment.setMonth(moment.getMonth() - 1);
|
||||
moment.setDate(new Date(moment.getFullYear(), moment.getMonth() + 1, 0).getDate() - i);
|
||||
|
||||
days.unshift(
|
||||
new DayItem(
|
||||
daysInPreviousMonth - i,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
moment,
|
||||
DayAction.Previous,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private populateNextMonthDays(days: DayItem[]): void {
|
||||
const passiveDaysAtFinal = 42 - days.length;
|
||||
|
||||
for (let i = 1; i <= passiveDaysAtFinal; i++) {
|
||||
const moment = new Date(this.current.year, this.current.month, this.current.day);
|
||||
moment.setMonth(moment.getMonth() + 1);
|
||||
moment.setDate(i);
|
||||
|
||||
days.push(
|
||||
new DayItem(
|
||||
i,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
moment,
|
||||
DayAction.Next,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private markToday(days: DayItem[]): void {
|
||||
const now = new Date();
|
||||
const daysCount = days.length;
|
||||
|
||||
for (let i = 0; i < daysCount; i++) {
|
||||
const day: DayItem = days[i];
|
||||
|
||||
if (day.equals(now)) {
|
||||
day.today = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
196
web/satellite/tests/unit/common/VDatePicker.spec.ts
Normal file
196
web/satellite/tests/unit/common/VDatePicker.spec.ts
Normal file
@ -0,0 +1,196 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import VDatePicker from '@/components/common/VDatePicker.vue';
|
||||
|
||||
import { mount } from '@vue/test-utils';
|
||||
|
||||
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
|
||||
describe('VDatePicker.vue', () => {
|
||||
it('renders correctly', function () {
|
||||
const wrapper = mount(VDatePicker, {});
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
|
||||
expect(wrapper.findAll('li').at(0).text()).toBe('Mo');
|
||||
expect(wrapper.findAll('.day').length).toBe(42);
|
||||
|
||||
wrapper.vm.showYear();
|
||||
|
||||
expect(wrapper.findAll('.year').length).toBe(100);
|
||||
|
||||
wrapper.vm.showMonth();
|
||||
|
||||
expect(wrapper.findAll('.month').length).toBe(12);
|
||||
});
|
||||
|
||||
it('renders correctly with props', function () {
|
||||
const wrapper = mount(VDatePicker, {
|
||||
propsData: {
|
||||
isSundayFirst: true,
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
|
||||
expect(wrapper.findAll('li').at(0).text()).toBe('Su');
|
||||
expect(wrapper.findAll('.day').length).toBe(42);
|
||||
});
|
||||
|
||||
it('triggers correct functionality on normal check', function () {
|
||||
const wrapper = mount(VDatePicker);
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
wrapper.vm.setYear(2019);
|
||||
wrapper.vm.setMonth(months[9]);
|
||||
|
||||
wrapper.findAll('.day').at(1).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDays.length).toBe(1);
|
||||
const selectedDay = wrapper.vm.selectedDays[0];
|
||||
expect(selectedDay.getDate()).toBe(1);
|
||||
expect(selectedDay.getMonth()).toBe(9);
|
||||
expect(selectedDay.getFullYear()).toBe(2019);
|
||||
|
||||
wrapper.findAll('.day').at(2).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDays.length).toBe(0);
|
||||
});
|
||||
|
||||
it('triggers correct functionality on toggle checking', function () {
|
||||
const wrapper = mount(VDatePicker);
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
wrapper.vm.setYear(2019);
|
||||
wrapper.vm.setMonth(months[9]);
|
||||
|
||||
wrapper.findAll('.day').at(1).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDays.length).toBe(1);
|
||||
const selectedDay1 = wrapper.vm.selectedDays[0];
|
||||
expect(selectedDay1.getDate()).toBe(1);
|
||||
expect(selectedDay1.getMonth()).toBe(9);
|
||||
expect(selectedDay1.getFullYear()).toBe(2019);
|
||||
|
||||
wrapper.findAll('.day').at(1).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDays.length).toBe(0);
|
||||
|
||||
wrapper.findAll('.day').at(2).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDays.length).toBe(1);
|
||||
const selectedDay2 = wrapper.vm.selectedDays[0];
|
||||
expect(selectedDay2.getDate()).toBe(2);
|
||||
expect(selectedDay2.getMonth()).toBe(9);
|
||||
expect(selectedDay2.getFullYear()).toBe(2019);
|
||||
});
|
||||
|
||||
it('triggers correct functionality on month selection', function () {
|
||||
const wrapper = mount(VDatePicker);
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
wrapper.vm.setYear(2019);
|
||||
wrapper.vm.setMonth(months[9]);
|
||||
|
||||
expect(wrapper.findAll('.month').length).toBe(0);
|
||||
|
||||
wrapper.find('.month-selection').trigger('click');
|
||||
|
||||
expect(wrapper.findAll('.month').length).toBe(12);
|
||||
|
||||
wrapper.findAll('.month').at(0).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(0);
|
||||
expect(wrapper.find('.month-selection').text()).toBe(months[0]);
|
||||
});
|
||||
|
||||
it('triggers correct functionality on year selection', function () {
|
||||
const wrapper = mount(VDatePicker);
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
wrapper.vm.setYear(2019);
|
||||
wrapper.vm.setMonth(months[9]);
|
||||
|
||||
expect(wrapper.findAll('.year').length).toBe(0);
|
||||
|
||||
wrapper.find('.year-selection').trigger('click');
|
||||
|
||||
expect(wrapper.findAll('.year').length).toBe(100);
|
||||
expect(wrapper.findAll('.year').at(0).text()).toBe('2019');
|
||||
|
||||
wrapper.find('.year-selection').trigger('click');
|
||||
wrapper.findAll('.year').at(1).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.year).toBe(2018);
|
||||
expect(wrapper.find('.year-selection').text()).toBe('2018');
|
||||
});
|
||||
|
||||
it('triggers correct functionality on month incrementation', function () {
|
||||
const wrapper = mount(VDatePicker);
|
||||
const now = new Date();
|
||||
const nowYear = now.getFullYear();
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
wrapper.vm.setYear(nowYear);
|
||||
wrapper.vm.setMonth(months[now.getMonth() - 1]);
|
||||
|
||||
const actualDates = wrapper.findAll('.day');
|
||||
|
||||
actualDates.at(actualDates.length - 1).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.year).toBe(nowYear);
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(now.getMonth());
|
||||
|
||||
wrapper.find('.cov-date-next').trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.year).toBe(nowYear);
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(now.getMonth());
|
||||
|
||||
wrapper.vm.setYear(nowYear - 1);
|
||||
wrapper.vm.setMonth(months[0]);
|
||||
|
||||
const changedDates = wrapper.findAll('.day');
|
||||
|
||||
changedDates.at(changedDates.length - 1).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.year).toBe(nowYear - 1);
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(1);
|
||||
|
||||
wrapper.find('.cov-date-next').trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.year).toBe(nowYear - 1);
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(2);
|
||||
});
|
||||
|
||||
it('triggers correct functionality on month decrementation', function () {
|
||||
const wrapper = mount(VDatePicker);
|
||||
|
||||
wrapper.vm.showCheck();
|
||||
wrapper.vm.setYear(2019);
|
||||
wrapper.vm.setMonth(months[9]);
|
||||
|
||||
wrapper.findAll('.day').at(0).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(8);
|
||||
|
||||
wrapper.find('.cov-date-previous').trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(7);
|
||||
|
||||
wrapper.vm.setMonth(months[0]);
|
||||
|
||||
wrapper.find('.cov-date-previous').trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.year).toBe(2018);
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(11);
|
||||
|
||||
wrapper.vm.setYear(2019);
|
||||
wrapper.vm.setMonth(months[0]);
|
||||
|
||||
wrapper.findAll('.day').at(0).trigger('click');
|
||||
|
||||
expect(wrapper.vm.selectedDateState.year).toBe(2018);
|
||||
expect(wrapper.vm.selectedDateState.month).toBe(11);
|
||||
});
|
||||
});
|
80
web/satellite/tests/unit/utils/datepicker.spec.ts
Normal file
80
web/satellite/tests/unit/utils/datepicker.spec.ts
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import {
|
||||
DateGenerator,
|
||||
DateStamp,
|
||||
DayItem,
|
||||
} from '@/utils/datepicker';
|
||||
|
||||
describe('datepicker', () => {
|
||||
it('DateGenerator populate years correctly', () => {
|
||||
const dateGenerator = new DateGenerator();
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
const years = dateGenerator.populateYears();
|
||||
|
||||
expect(years.length).toBe(100);
|
||||
expect(years[0]).toBe(currentYear);
|
||||
});
|
||||
|
||||
it('DateGenerator populate days correctly with exact date and isSundayFirst', () => {
|
||||
const dateGenerator = new DateGenerator();
|
||||
// 8th month is september
|
||||
const currentDate = new DateStamp(2019, 8, 30);
|
||||
const firstExpectedDay = new DayItem(
|
||||
25,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
new Date(2019, 7, 25),
|
||||
1,
|
||||
false,
|
||||
);
|
||||
const lastExpectedDay = new DayItem(
|
||||
5,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
new Date(2019, 9, 5),
|
||||
1,
|
||||
false,
|
||||
);
|
||||
|
||||
const days = dateGenerator.populateDays(currentDate, true);
|
||||
|
||||
expect(days.length).toBe(42);
|
||||
expect(days[0].equals(firstExpectedDay.moment)).toBe(true);
|
||||
expect(days[days.length - 1].equals(lastExpectedDay.moment)).toBe(true);
|
||||
});
|
||||
|
||||
it('DateGenerator populate days correctly with exact date and no isSundayFirst', () => {
|
||||
const dateGenerator = new DateGenerator();
|
||||
// 8th month is september
|
||||
const currentDate = new DateStamp(2019, 8, 30);
|
||||
const firstExpectedDay = new DayItem(
|
||||
26,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
new Date(2019, 7, 26),
|
||||
1,
|
||||
false,
|
||||
);
|
||||
const lastExpectedDay = new DayItem(
|
||||
6,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
new Date(2019, 9, 6),
|
||||
1,
|
||||
false,
|
||||
);
|
||||
|
||||
const days = dateGenerator.populateDays(currentDate, false);
|
||||
|
||||
expect(days.length).toBe(42);
|
||||
expect(days[0].equals(firstExpectedDay.moment)).toBe(true);
|
||||
expect(days[days.length - 1].equals(lastExpectedDay.moment)).toBe(true);
|
||||
});
|
||||
});
|
@ -37,8 +37,6 @@
|
||||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
// TODO: temporary file
|
||||
"src/components/project/DatePicker.vue"
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
|
@ -5,9 +5,7 @@
|
||||
],
|
||||
"linterOptions": {
|
||||
"exclude": [
|
||||
"node_modules/**",
|
||||
// TODO: temporary file
|
||||
"src/components/project/DatePicker.vue"
|
||||
"node_modules/**"
|
||||
]
|
||||
},
|
||||
"rules": {
|
||||
@ -15,7 +13,6 @@
|
||||
"align": [true, "parameters", "statements"],
|
||||
"array-type": [true, "array-simple"],
|
||||
"arrow-return-shorthand": true,
|
||||
"check-format": true,
|
||||
"class-name": true,
|
||||
"comment-format": [true, "check-space"],
|
||||
"comment-type": [true, "doc", "singleline"],
|
||||
|
Loading…
Reference in New Issue
Block a user