mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-11 18:42:54 +00:00
perf: 优化日历
This commit is contained in:
parent
52babf82ae
commit
168650649f
@ -59,8 +59,8 @@
|
|||||||
"stylus": "^0.59.0",
|
"stylus": "^0.59.0",
|
||||||
"stylus-loader": "^7.1.0",
|
"stylus-loader": "^7.1.0",
|
||||||
"tinymce": "^5.10.3",
|
"tinymce": "^5.10.3",
|
||||||
"tui-calendar-hi": "^1.15.1-5",
|
"tui-calendar-hi": "^2.1.3-3",
|
||||||
"view-design-hi": "^4.7.0-70",
|
"view-design-hi": "^4.7.0-71",
|
||||||
"vite": "^2.9.15",
|
"vite": "^2.9.15",
|
||||||
"vite-plugin-file-copy": "^1.0.0",
|
"vite-plugin-file-copy": "^1.0.0",
|
||||||
"vite-plugin-require": "^1.1.10",
|
"vite-plugin-require": "^1.1.10",
|
||||||
|
|||||||
@ -4,54 +4,54 @@
|
|||||||
<div class="calendar-head">
|
<div class="calendar-head">
|
||||||
<div class="calendar-titbox">
|
<div class="calendar-titbox">
|
||||||
<div class="calendar-title">
|
<div class="calendar-title">
|
||||||
<div class="common-nav-back portrait" @click="goForward({name: 'manage-application'},true)"><i class="taskfont"></i></div>
|
<div class="common-nav-back portrait" @click="goForward({name: 'manage-application'}, true)"><i class="taskfont"></i></div>
|
||||||
<h1>{{rangeText}}</h1>
|
<h1>{{ rangeText }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<ButtonGroup class="calendar-arrow" size="small">
|
<ButtonGroup class="calendar-arrow" size="small">
|
||||||
<Button @click="preMonth"><Icon type="ios-arrow-back"></Icon></Button>
|
<Button @click="onMove(-1)">
|
||||||
<Button @click="afterMonth"><Icon type="ios-arrow-forward"></Icon></Button>
|
<Icon type="ios-arrow-back"></Icon>
|
||||||
|
</Button>
|
||||||
|
<Button @click="onMove(1)">
|
||||||
|
<Icon type="ios-arrow-forward"></Icon>
|
||||||
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
<ButtonGroup class="calendar-arrow" size="small">
|
<ButtonGroup class="calendar-arrow" size="small">
|
||||||
<Button @click="curMonth">{{$L('今天')}}</Button>
|
<Button @click="onToDay">{{ $L('今天') }}</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
<ButtonGroup class="calendar-view">
|
<ButtonGroup class="calendar-view">
|
||||||
<Button @click="setView('day')" :type="calendarView == 'day' ? 'primary' : 'default'">{{$L('日')}}</Button>
|
<Button @click="setView('day')" :type="options.view == 'day' ? 'primary' : 'default'">{{ $L('日') }}</Button>
|
||||||
<Button @click="setView('week')" :type="calendarView == 'week' ? 'primary' : 'default'">{{$L('周')}}</Button>
|
<Button @click="setView('week')" :type="options.view == 'week' ? 'primary' : 'default'">{{ $L('周') }}</Button>
|
||||||
<Button @click="setView('month')" :type="calendarView == 'month' ? 'primary' : 'default'">{{$L('月')}}</Button>
|
<Button @click="setView('month')" :type="options.view == 'month' ? 'primary' : 'default'">{{ $L('月') }}</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="calendar-box">
|
<div class="calendar-box">
|
||||||
<Calendar
|
<Calendar
|
||||||
ref="cal"
|
ref="calendar"
|
||||||
:view="calendarView"
|
:view="options.view"
|
||||||
:week="calendarWeek"
|
:week="options.week"
|
||||||
:month="calendarMonth"
|
:month="options.month"
|
||||||
:theme="calendarTheme"
|
:theme="options.theme"
|
||||||
:template="calendarTemplate"
|
:template="options.template"
|
||||||
:schedules="list"
|
:events="events"
|
||||||
:taskView="false"
|
@selectDateTime="onSelectDateTime"
|
||||||
:useCreationPopup="false"
|
@beforeUpdateEvent="onBeforeUpdateEvent"
|
||||||
@beforeCreateSchedule="onBeforeCreateSchedule"
|
@clickDayName="onClickDayName"
|
||||||
@beforeClickSchedule="onBeforeClickSchedule"
|
@clickEvent="onClickEvent"/>
|
||||||
@beforeUpdateSchedule="onBeforeUpdateSchedule"
|
|
||||||
disable-click/>
|
|
||||||
</div>
|
|
||||||
<div class="calendar-menu" :style="calendarMenuStyles">
|
|
||||||
<TaskMenu ref="calendarTaskMenu" :task="calendarTask" updateBefore/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapState, mapGetters} from "vuex";
|
import 'tui-calendar-hi/toastui-calendar.css';
|
||||||
import Calendar from "./components/Calendar";
|
import Calendar from "./components/Calendar";
|
||||||
import TaskMenu from "./components/TaskMenu";
|
import {theme} from './components/Calendar/theme';
|
||||||
import {addLanguage} from "../../language";
|
|
||||||
import emitter from "../../store/events";
|
import emitter from "../../store/events";
|
||||||
|
import {addLanguage} from "../../language";
|
||||||
|
import {mapGetters, mapState} from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {TaskMenu, Calendar},
|
components: {Calendar},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
lists: [],
|
lists: [],
|
||||||
@ -59,19 +59,26 @@ export default {
|
|||||||
rangeText: 'Calendar',
|
rangeText: 'Calendar',
|
||||||
rangeTime: [],
|
rangeTime: [],
|
||||||
|
|
||||||
calendarView: 'month',
|
|
||||||
calendarWeek: {},
|
|
||||||
calendarMonth: {},
|
|
||||||
calendarTheme: {},
|
|
||||||
calendarTemplate: {},
|
|
||||||
calendarTask: {},
|
|
||||||
calendarMenuStyles: {
|
|
||||||
top: 0,
|
|
||||||
left: 0
|
|
||||||
},
|
|
||||||
|
|
||||||
loadIng: 0,
|
loadIng: 0,
|
||||||
loadTimeout: null,
|
loadTimer: null,
|
||||||
|
|
||||||
|
options: {
|
||||||
|
view: 'month',
|
||||||
|
week: {
|
||||||
|
showTimezoneCollapseButton: true,
|
||||||
|
timezonesCollapsed: false,
|
||||||
|
eventView: true,
|
||||||
|
taskView: false,
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
startDayOfWeek: 0
|
||||||
|
},
|
||||||
|
theme: theme,
|
||||||
|
template: {
|
||||||
|
allday: this.getTemplateForGeneral,
|
||||||
|
time: this.getTemplateForGeneral,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -85,7 +92,7 @@ export default {
|
|||||||
{"key": "{五}", "zh": "五", "general": "Fri"},
|
{"key": "{五}", "zh": "五", "general": "Fri"},
|
||||||
{"key": "{六}", "zh": "六", "general": "Sat"},
|
{"key": "{六}", "zh": "六", "general": "Sat"},
|
||||||
]);
|
]);
|
||||||
let daynames = [
|
const dayNames = [
|
||||||
this.$L('{日}'),
|
this.$L('{日}'),
|
||||||
this.$L('{一}'),
|
this.$L('{一}'),
|
||||||
this.$L('{二}'),
|
this.$L('{二}'),
|
||||||
@ -94,41 +101,13 @@ export default {
|
|||||||
this.$L('{五}'),
|
this.$L('{五}'),
|
||||||
this.$L('{六}')
|
this.$L('{六}')
|
||||||
];
|
];
|
||||||
this.calendarWeek = {daynames};
|
this.options.week.dayNames = dayNames;
|
||||||
this.calendarMonth = {daynames};
|
this.options.month.dayNames = dayNames;
|
||||||
this.calendarTheme = {
|
this.options.view = this.$store.state.cacheCalendarView || this.options.view;
|
||||||
'common.border': '1px solid rgba(0,0,0,0)',
|
|
||||||
'month.dayname.fontSize': '14px',
|
|
||||||
'month.dayname.borderLeft': '1px solid rgba(0,0,0,0)',
|
|
||||||
'month.dayname.height': '50px',
|
|
||||||
}
|
|
||||||
if (this.windowLandscape) {
|
|
||||||
this.calendarTheme = {
|
|
||||||
'common.border': '1px solid #f4f5f5',
|
|
||||||
'month.dayname.fontSize': '14px',
|
|
||||||
'month.dayname.borderLeft': '1px solid #f4f5f5',
|
|
||||||
'month.dayname.height': '50px',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.calendarTemplate = {
|
|
||||||
titlePlaceholder: () => {
|
|
||||||
return this.$L("任务描述")
|
|
||||||
},
|
|
||||||
popupSave: () => {
|
|
||||||
return this.$L("保存");
|
|
||||||
},
|
|
||||||
popupEdit: () => {
|
|
||||||
return this.$L("详情");
|
|
||||||
},
|
|
||||||
popupDelete: () => {
|
|
||||||
return this.$L("删除");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
this.$refs.cal.resetRender();
|
this.setDateRangeText();
|
||||||
this.setRenderRange();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
deactivated() {
|
deactivated() {
|
||||||
@ -137,11 +116,13 @@ export default {
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['cacheTasks', 'taskCompleteTemps', 'wsOpenNum', 'themeName']),
|
...mapState(['cacheTasks', 'taskCompleteTemps', 'wsOpenNum', 'themeName']),
|
||||||
|
|
||||||
...mapGetters(['transforTasks']),
|
...mapGetters(['transforTasks']),
|
||||||
|
|
||||||
list() {
|
calendar() {
|
||||||
const {cacheTasks, taskCompleteTemps} = this;
|
return this.$refs.calendar.getInstance();
|
||||||
|
},
|
||||||
|
|
||||||
|
events({cacheTasks, taskCompleteTemps}) {
|
||||||
const filterTask = (task, chackCompleted = true) => {
|
const filterTask = (task, chackCompleted = true) => {
|
||||||
if (task.archived_at) {
|
if (task.archived_at) {
|
||||||
return false;
|
return false;
|
||||||
@ -162,61 +143,39 @@ export default {
|
|||||||
array.push(...tmps);
|
array.push(...tmps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const todayStartPlusOne = $A.dayjs().startOf('day').add(1, 'second');
|
||||||
|
const todayEndMinusOne = $A.dayjs().endOf('day').subtract(1, 'second');
|
||||||
return this.transforTasks(array).map(data => {
|
return this.transforTasks(array).map(data => {
|
||||||
const isAllday = $A.rightExists(data.start_at, "00:00:00") && $A.rightExists(data.end_at, "23:59:59")
|
const start = $A.dayjs(data.start_at);
|
||||||
|
const end = $A.dayjs(data.end_at);
|
||||||
|
const isAllday = start.isBefore(todayStartPlusOne) && end.isAfter(todayEndMinusOne);
|
||||||
const task = {
|
const task = {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
calendarId: String(data.project_id),
|
calendarId: String(data.project_id),
|
||||||
title: data.name,
|
title: data.name,
|
||||||
body: data.desc,
|
body: data.desc,
|
||||||
isAllDay: isAllday,
|
isAllday: isAllday,
|
||||||
category: isAllday ? 'allday' : 'time',
|
category: isAllday ? 'allday' : 'time',
|
||||||
start: $A.dayjs(data.start_at).toISOString(),
|
start: start,
|
||||||
end: $A.dayjs(data.end_at).toISOString(),
|
end: end,
|
||||||
color: "#515a6e",
|
color: "#515a6e",
|
||||||
bgColor: data.color || '#E3EAFD',
|
backgroundColor: data.color || '#E3EAFD',
|
||||||
borderColor: data.p_color,
|
borderColor: data.p_color,
|
||||||
priority: '',
|
raw: data,
|
||||||
preventClick: true,
|
|
||||||
preventCheckHide: true,
|
|
||||||
isChecked: !!data.complete_at,
|
|
||||||
//
|
|
||||||
complete_at: data.complete_at,
|
|
||||||
start_at: data.start_at,
|
|
||||||
end_at: data.end_at,
|
|
||||||
_time: data._time,
|
|
||||||
};
|
|
||||||
if (data.p_name) {
|
|
||||||
let priorityStyle = `background-color:${data.p_color}`;
|
|
||||||
if (this.themeName === 'dark') {
|
|
||||||
priorityStyle = `color:${data.p_color};border:1px solid ${data.p_color};padding:1px 3px;`;
|
|
||||||
}
|
|
||||||
task.priority = `<span class="priority" style="${priorityStyle}">${data.p_name}</span>`;
|
|
||||||
}
|
|
||||||
if (data.sub_my && data.sub_my.length > 0) {
|
|
||||||
task.title = `[+${data.sub_my.length}] ${task.title}`
|
|
||||||
}
|
|
||||||
if (data.sub_top === true) {
|
|
||||||
task.title = `[${this.$L('子任务')}] ${task.title}`
|
|
||||||
}
|
|
||||||
if (data.flow_item_name) {
|
|
||||||
task.title = `[${data.flow_item_name}] ${task.title}`
|
|
||||||
}
|
}
|
||||||
if (data.complete_at) {
|
if (data.complete_at) {
|
||||||
task.color = "#c3c2c2"
|
task.color = "#c3c2c2"
|
||||||
task.bgColor = "#f3f3f3"
|
task.backgroundColor = "#f3f3f3"
|
||||||
task.borderColor = "#e3e3e3"
|
task.borderColor = "#e3e3e3"
|
||||||
} else if (data.overdue) {
|
} else if (data.overdue) {
|
||||||
task.title = `[${this.$L('超期')}] ${task.title}`
|
|
||||||
task.color = "#f56c6c"
|
task.color = "#f56c6c"
|
||||||
task.bgColor = data.color || "#fef0f0"
|
task.backgroundColor = data.color || "#fef0f0"
|
||||||
task.priority+= `<span class="overdue">${this.$L('超期未完成')}</span>`;
|
|
||||||
}
|
}
|
||||||
if (!task.borderColor) {
|
if (!task.borderColor) {
|
||||||
task.borderColor = task.bgColor;
|
task.borderColor = task.backgroundColor;
|
||||||
}
|
}
|
||||||
return task;
|
return task
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -227,20 +186,22 @@ export default {
|
|||||||
|
|
||||||
wsOpenNum(num) {
|
wsOpenNum(num) {
|
||||||
if (num <= 1) return
|
if (num <= 1) return
|
||||||
this.wsOpenTimeout && clearTimeout(this.wsOpenTimeout)
|
this.wsTimer && clearTimeout(this.wsTimer)
|
||||||
this.wsOpenTimeout = setTimeout(() => {
|
this.wsTimer = setTimeout(() => {
|
||||||
this.$route.name == 'manage-calendar' && this.setRenderRange();
|
this.$route.name == 'manage-calendar' && this.setDateRangeText();
|
||||||
}, 5000)
|
}, 5000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* 获取任务
|
||||||
|
* @param time
|
||||||
|
*/
|
||||||
getTask(time) {
|
getTask(time) {
|
||||||
if (this.loadIng > 0) {
|
if (this.loadIng > 0) {
|
||||||
clearTimeout(this.loadTimeout)
|
this.loadTimer && clearTimeout(this.loadTimer)
|
||||||
this.loadTimeout = setTimeout(() => {
|
this.loadTimer = setTimeout(() => this.getTask(time), 100)
|
||||||
this.getTask(time)
|
|
||||||
}, 100)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -250,158 +211,168 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
preMonth() {
|
/**
|
||||||
this.$refs.cal.getInstance().prev();
|
* 任务标题
|
||||||
this.setRenderRange()
|
* @param title
|
||||||
},
|
* @param data
|
||||||
|
* @returns {string}
|
||||||
curMonth() {
|
*/
|
||||||
this.$refs.cal.getInstance().today();
|
getTemplateForGeneral({title, raw: data}) {
|
||||||
this.setRenderRange()
|
if (data.sub_my && data.sub_my.length > 0) {
|
||||||
},
|
title = `[+${data.sub_my.length}] ${title}`
|
||||||
|
|
||||||
afterMonth() {
|
|
||||||
this.$refs.cal.getInstance().next();
|
|
||||||
this.setRenderRange()
|
|
||||||
},
|
|
||||||
|
|
||||||
setView(view) {
|
|
||||||
this.calendarView = view;
|
|
||||||
this.setRenderRange()
|
|
||||||
},
|
|
||||||
|
|
||||||
setRenderRange() {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
const cal = this.$refs.cal.getInstance();
|
|
||||||
let options = cal.getOptions();
|
|
||||||
let viewName = cal.getViewName();
|
|
||||||
let html = [];
|
|
||||||
if (viewName === 'day') {
|
|
||||||
html.push(this.currentCalendarDate('YYYY.MM.DD'));
|
|
||||||
} else if (viewName === 'month' &&
|
|
||||||
(!options.month.visibleWeeksCount || options.month.visibleWeeksCount > 4)) {
|
|
||||||
html.push(this.currentCalendarDate('YYYY.MM'));
|
|
||||||
} else {
|
|
||||||
html.push($A.dayjs(cal.getDateRangeStart().getTime()).format('YYYY.MM.DD'));
|
|
||||||
html.push(' ~ ');
|
|
||||||
html.push($A.dayjs(cal.getDateRangeEnd().getTime()).format(' MM.DD'));
|
|
||||||
}
|
|
||||||
this.rangeText = html.join('');
|
|
||||||
this.rangeTime = [$A.dayjs(cal.getDateRangeStart().getTime()).format('YYYY-MM-DD'), $A.dayjs(cal.getDateRangeEnd().getTime()).format('YYYY-MM-DD')];
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
currentCalendarDate(format) {
|
|
||||||
const cal = this.$refs.cal.getInstance();
|
|
||||||
const currentDate = $A.dayjs(cal.getDate().toDate());
|
|
||||||
return currentDate.format(format);
|
|
||||||
},
|
|
||||||
|
|
||||||
async onBeforeCreateSchedule({start, end, isAllDay, guide}) {
|
|
||||||
if (isAllDay || this.calendarView == 'month') {
|
|
||||||
start = $A.dayjs(start.toDate()).startOf('day')
|
|
||||||
end = $A.dayjs(end.toDate()).endOf('day')
|
|
||||||
} else {
|
|
||||||
start = $A.dayjs(start.toDate())
|
|
||||||
end = $A.dayjs(end.toDate())
|
|
||||||
}
|
}
|
||||||
const times = await this.$store.dispatch("taskDefaultTime", $A.newDateString([start, end], "YYYY-MM-DD HH:mm"))
|
if (data.sub_top === true) {
|
||||||
|
title = `[${this.$L('子任务')}] ${title}`
|
||||||
|
}
|
||||||
|
if (data.flow_item_name) {
|
||||||
|
title = `[${data.flow_item_name}] ${title}`
|
||||||
|
}
|
||||||
|
if (data.overdue) {
|
||||||
|
title = `[${this.$L('超期')}] ${title}`
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择时间
|
||||||
|
* @param start
|
||||||
|
* @param end
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onSelectDateTime({start, end}) {
|
||||||
|
const timer = [$A.dayjs(start), $A.dayjs(end)]
|
||||||
|
if (this.options.view == 'month') {
|
||||||
|
timer[0] = timer[0].startOf('day')
|
||||||
|
timer[1] = timer[1].startOf('day')
|
||||||
|
}
|
||||||
|
const times = await this.$store.dispatch("taskDefaultTime", $A.newDateString(timer, "YYYY-MM-DD HH:mm"))
|
||||||
emitter.emit('addTask', {
|
emitter.emit('addTask', {
|
||||||
times,
|
times,
|
||||||
owner: [this.userId],
|
owner: [this.userId],
|
||||||
beforeClose: () => guide.clearGuideElement()
|
beforeClose: () => this.calendar.clearGridSelections()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onBeforeClickSchedule(event) {
|
/**
|
||||||
const {type, schedule} = event;
|
* 更新任务
|
||||||
let data = this.cacheTasks.find(({id}) => id === schedule.id);
|
* @param changes
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
onBeforeUpdateEvent({changes, event}) {
|
||||||
|
if (!changes.start && !changes.end) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 查找任务
|
||||||
|
const data = this.cacheTasks.find(({id}) => id === event.id);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (type) {
|
// dayjs 处理
|
||||||
case "check":
|
const start = $A.dayjs(changes.start || data.start_at),
|
||||||
this.calendarMenuStyles = {
|
end = $A.dayjs(changes.end || data.end_at),
|
||||||
left: `${this.getElementLeft(event.target)}px`,
|
taskStart = $A.dayjs(data.start_at),
|
||||||
top: `${this.getElementTop(event.target) - 8}px`
|
taskEnd = $A.dayjs(data.end_at);
|
||||||
|
// 判断相差1分钟内不修改
|
||||||
|
if (start.isSame(taskStart, 'minute') && end.isSame(taskEnd, 'minute')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 更新日历
|
||||||
|
this.calendar.updateEvent(event.id, event.calendarId, { ...changes });
|
||||||
|
// 更新任务
|
||||||
|
this.$store.dispatch("taskUpdate", {
|
||||||
|
task_id: data.id,
|
||||||
|
times: $A.newDateString([start, end], "YYYY-MM-DD HH:mm"),
|
||||||
|
}).then(({msg}) => {
|
||||||
|
$A.messageSuccess(msg);
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError({
|
||||||
|
content: msg,
|
||||||
|
onOk: _ => {
|
||||||
|
this.calendar.updateEvent(event.id, event.calendarId, {
|
||||||
|
start: taskStart,
|
||||||
|
end: taskEnd
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.calendarTask = data;
|
})
|
||||||
this.$nextTick(this.$refs.calendarTaskMenu.show);
|
});
|
||||||
break;
|
|
||||||
|
|
||||||
case "edit":
|
|
||||||
this.$store.dispatch("openTask", data)
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "delete":
|
|
||||||
$A.modalConfirm({
|
|
||||||
title: '删除任务',
|
|
||||||
content: '你确定要删除任务【' + data.name + '】吗?',
|
|
||||||
loading: true,
|
|
||||||
onOk: () => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this.$store.dispatch("removeTask", {task_id: data.id}).then(({msg}) => {
|
|
||||||
resolve(msg);
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
reject(msg);
|
|
||||||
this.setRenderRange();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onBeforeUpdateSchedule(res) {
|
/**
|
||||||
const {changes, schedule} = res;
|
* 点击日期
|
||||||
let data = this.cacheTasks.find(({id}) => id === schedule.id);
|
* @param event
|
||||||
if (!data) {
|
*/
|
||||||
return;
|
onClickDayName(event) {
|
||||||
}
|
this.onSelectDateTime({
|
||||||
if(changes?.start?.getTime() == schedule?.start?.getTime() && changes?.end?.getTime() == schedule?.end?.getTime()){
|
start: $A.newDateString(event.date, "YYYY-MM-DD 00:00"),
|
||||||
return;
|
end: $A.newDateString(event.date, "YYYY-MM-DD 23:59"),
|
||||||
}
|
})
|
||||||
if (changes?.start || changes?.end) {
|
|
||||||
const cal = this.$refs.cal.getInstance();
|
|
||||||
cal.updateSchedule(schedule.id, schedule.calendarId, changes);
|
|
||||||
//
|
|
||||||
this.$store.dispatch("taskUpdate", {
|
|
||||||
task_id: data.id,
|
|
||||||
times: [
|
|
||||||
(changes.start || schedule.start).toDate(),
|
|
||||||
(changes.end || schedule.end).toDate(),
|
|
||||||
],
|
|
||||||
}).then(({msg}) => {
|
|
||||||
$A.messageSuccess(msg);
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg);
|
|
||||||
this.setRenderRange();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getElementLeft(element) {
|
/**
|
||||||
let actualLeft = element.offsetLeft;
|
* 点击事件
|
||||||
let current = element.offsetParent;
|
* @param event
|
||||||
while (current !== null) {
|
*/
|
||||||
if (current == this.$el) break;
|
onClickEvent({event}) {
|
||||||
actualLeft += (current.offsetLeft + current.clientLeft);
|
this.$store.dispatch("openTask", event.raw)
|
||||||
current = current.offsetParent;
|
|
||||||
}
|
|
||||||
return actualLeft;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getElementTop(element) {
|
/**
|
||||||
let actualTop = element.offsetTop;
|
* 上一天/周/月 下一天/周/月
|
||||||
let current = element.offsetParent;
|
* @param offset
|
||||||
while (current !== null) {
|
*/
|
||||||
if (current == this.$el) break;
|
onMove(offset) {
|
||||||
actualTop += (current.offsetTop + current.clientTop);
|
this.calendar.move(offset);
|
||||||
current = current.offsetParent;
|
this.setDateRangeText();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 今天
|
||||||
|
*/
|
||||||
|
onToDay() {
|
||||||
|
this.calendar.today();
|
||||||
|
this.setDateRangeText()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换天/周/月
|
||||||
|
* @param v
|
||||||
|
*/
|
||||||
|
setView(v) {
|
||||||
|
this.options.view = v;
|
||||||
|
this.calendar.changeView(v);
|
||||||
|
this.setDateRangeText();
|
||||||
|
$A.IDBSave("cacheCalendarView", this.$store.state.cacheCalendarView = v)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新日历标题
|
||||||
|
*/
|
||||||
|
setDateRangeText() {
|
||||||
|
const date = this.calendar.getDate();
|
||||||
|
const start = this.calendar.getDateRangeStart();
|
||||||
|
const end = this.calendar.getDateRangeEnd();
|
||||||
|
|
||||||
|
switch (this.calendar.getViewName()) {
|
||||||
|
case "month":
|
||||||
|
this.rangeText = $A.dayjs(date).format("YYYY.MM");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "day":
|
||||||
|
this.rangeText = $A.dayjs(date).format("YYYY.MM.DD");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
const startYear = start.getFullYear();
|
||||||
|
const endYear = end.getFullYear();
|
||||||
|
if (startYear !== endYear) {
|
||||||
|
this.rangeText = $A.dayjs(date).format("YYYY.MM.DD") + " ~ " + $A.dayjs(end).format("YYYY.MM.DD");
|
||||||
|
} else {
|
||||||
|
this.rangeText = $A.dayjs(date).format("YYYY.MM.DD") + " ~ " + $A.dayjs(end).format("MM.DD");
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return actualTop;
|
this.rangeTime = [$A.dayjs(start).format('YYYY-MM-DD'), $A.dayjs(end).format('YYYY-MM-DD')];
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,225 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div ref="tuiCalendar" class="calendar-wrapper"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import 'tui-date-picker/dist/tui-date-picker.css';
|
|
||||||
import 'tui-time-picker/dist/tui-time-picker.css';
|
|
||||||
import 'tui-calendar-hi/dist/tui-calendar-hi.css'
|
|
||||||
import Calendar from 'tui-calendar-hi';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Calendar',
|
|
||||||
props: {
|
|
||||||
calendars: {
|
|
||||||
type: Array,
|
|
||||||
default() {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
schedules: {
|
|
||||||
type: Array,
|
|
||||||
default() {
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
validator(value) {
|
|
||||||
let notHave = false;
|
|
||||||
|
|
||||||
value.forEach(schedule => {
|
|
||||||
notHave = [ 'start', 'category' ].some(prop => !schedule.hasOwnProperty(prop));
|
|
||||||
});
|
|
||||||
|
|
||||||
return !notHave;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
view: {
|
|
||||||
type: String,
|
|
||||||
default: 'week'
|
|
||||||
},
|
|
||||||
taskView: {
|
|
||||||
type: [Boolean, Array],
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
scheduleView: {
|
|
||||||
type: [Boolean, Array],
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
theme: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
template: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
week: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
month: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
useCreationPopup: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
useDetailPopup: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
timezones: {
|
|
||||||
type: Array,
|
|
||||||
default() {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
disableDblClick: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
disableClick: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
isReadOnly: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
usageStatistics: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
calendarInstance: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
calendars(newValue) {
|
|
||||||
this.calendarInstance.setCalendars(newValue);
|
|
||||||
this.$nextTick(this.resetRender)
|
|
||||||
},
|
|
||||||
schedules() {
|
|
||||||
this.resetRender();
|
|
||||||
},
|
|
||||||
view(newValue) {
|
|
||||||
this.calendarInstance.changeView(newValue, true);
|
|
||||||
},
|
|
||||||
taskView(newValue) {
|
|
||||||
this.calendarInstance.setOptions({taskView: newValue});
|
|
||||||
},
|
|
||||||
scheduleView(newValue) {
|
|
||||||
this.calendarInstance.setOptions({scheduleView: newValue});
|
|
||||||
},
|
|
||||||
theme: {
|
|
||||||
handler(newValue) {
|
|
||||||
this.calendarInstance.setTheme($A.cloneJSON(newValue));
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
},
|
|
||||||
week: {
|
|
||||||
handler(newValue) {
|
|
||||||
const silent = this.view !== 'week' && this.view !== 'day';
|
|
||||||
this.calendarInstance.setOptions({week: $A.cloneJSON(newValue)}, silent);
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
},
|
|
||||||
month: {
|
|
||||||
handler(newValue) {
|
|
||||||
const silent = this.view !== 'month';
|
|
||||||
this.calendarInstance.setOptions({month: $A.cloneJSON(newValue)}, silent);
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
},
|
|
||||||
timezones(newValue) {
|
|
||||||
this.calendarInstance.setOptions({timezones: newValue});
|
|
||||||
},
|
|
||||||
disableDblClick(newValue) {
|
|
||||||
this.calendarInstance.setOptions({disableDblClick: newValue});
|
|
||||||
},
|
|
||||||
disableClick(newValue) {
|
|
||||||
this.calendarInstance.setOptions({disableClick: newValue});
|
|
||||||
},
|
|
||||||
isReadOnly(newValue) {
|
|
||||||
this.calendarInstance.setOptions({isReadOnly: newValue});
|
|
||||||
},
|
|
||||||
windowPortrait: {
|
|
||||||
handler(v) {
|
|
||||||
this.resetRender()
|
|
||||||
},
|
|
||||||
immediate: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.calendarInstance = new Calendar(this.$refs.tuiCalendar, {
|
|
||||||
defaultView: this.view,
|
|
||||||
taskView: this.taskView,
|
|
||||||
scheduleView: this.scheduleView,
|
|
||||||
theme: this.theme,
|
|
||||||
template: this.template,
|
|
||||||
week: this.week,
|
|
||||||
month: this.month,
|
|
||||||
calendars: this.calendars,
|
|
||||||
useCreationPopup: this.useCreationPopup,
|
|
||||||
useDetailPopup: this.useDetailPopup,
|
|
||||||
timezones: this.timezones,
|
|
||||||
disableDblClick: this.disableDblClick,
|
|
||||||
disableClick: this.disableClick,
|
|
||||||
isReadOnly: this.isReadOnly,
|
|
||||||
usageStatistics: this.usageStatistics
|
|
||||||
});
|
|
||||||
this.addEventListeners();
|
|
||||||
this.reflectSchedules();
|
|
||||||
//
|
|
||||||
window.addEventListener('resize',this.resetRender);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
this.calendarInstance.off();
|
|
||||||
this.calendarInstance.destroy();
|
|
||||||
window.removeEventListener('resize',this.resetRender);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
addEventListeners() {
|
|
||||||
for (const eventName of Object.keys(this.$listeners)) {
|
|
||||||
this.calendarInstance.on(eventName, (...args) => this.$emit(eventName, ...args));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
reflectSchedules() {
|
|
||||||
if (this.schedules.length > 0) {
|
|
||||||
this.invoke('createSchedules', this.schedules);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getRootElement() {
|
|
||||||
return this.$refs.tuiCalendar;
|
|
||||||
},
|
|
||||||
getInstance() {
|
|
||||||
return this.calendarInstance;
|
|
||||||
},
|
|
||||||
resetRender() {
|
|
||||||
if(this.calendarInstance){
|
|
||||||
this.calendarInstance.clear();
|
|
||||||
this.reflectSchedules();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
invoke(methodName, ...args) {
|
|
||||||
let result;
|
|
||||||
|
|
||||||
if (this.calendarInstance[methodName]) {
|
|
||||||
result = this.calendarInstance[methodName](...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
125
resources/assets/js/pages/manage/components/Calendar/index.vue
Normal file
125
resources/assets/js/pages/manage/components/Calendar/index.vue
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="container" class="calendar-wrapper"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Calendar from "tui-calendar-hi";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Calendar',
|
||||||
|
props: {
|
||||||
|
view: String,
|
||||||
|
useFormPopup: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => undefined,
|
||||||
|
},
|
||||||
|
useDetailPopup: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => undefined,
|
||||||
|
},
|
||||||
|
isReadOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => undefined,
|
||||||
|
},
|
||||||
|
usageStatistics: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => undefined,
|
||||||
|
},
|
||||||
|
eventFilter: Function,
|
||||||
|
week: Object,
|
||||||
|
month: Object,
|
||||||
|
gridSelection: {
|
||||||
|
type: [Object, Boolean],
|
||||||
|
default: () => undefined,
|
||||||
|
},
|
||||||
|
timezone: Object,
|
||||||
|
theme: Object,
|
||||||
|
template: Object,
|
||||||
|
calendars: Array,
|
||||||
|
events: Array,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
calendarInstance: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
view(value) {
|
||||||
|
this.calendarInstance.changeView(value);
|
||||||
|
},
|
||||||
|
useFormPopup(value) {
|
||||||
|
this.calendarInstance.setOptions({useFormPopup: value});
|
||||||
|
},
|
||||||
|
useDetailPopup(value) {
|
||||||
|
this.calendarInstance.setOptions({useDetailPopup: value});
|
||||||
|
},
|
||||||
|
isReadOnly(value) {
|
||||||
|
this.calendarInstance.setOptions({isReadOnly: value});
|
||||||
|
},
|
||||||
|
eventFilter(value) {
|
||||||
|
this.calendarInstance.setOptions({eventFilter: value});
|
||||||
|
},
|
||||||
|
week(value) {
|
||||||
|
this.calendarInstance.setOptions({week: value});
|
||||||
|
},
|
||||||
|
month(value) {
|
||||||
|
this.calendarInstance.setOptions({month: value});
|
||||||
|
},
|
||||||
|
gridSelection(value) {
|
||||||
|
this.calendarInstance.setOptions({gridSelection: value});
|
||||||
|
},
|
||||||
|
timezone(value) {
|
||||||
|
this.calendarInstance.setOptions({timezone: value});
|
||||||
|
},
|
||||||
|
theme(value) {
|
||||||
|
this.calendarInstance.setTheme(value);
|
||||||
|
},
|
||||||
|
template(value) {
|
||||||
|
this.calendarInstance.setOptions({template: value});
|
||||||
|
},
|
||||||
|
calendars(value) {
|
||||||
|
this.calendarInstance.setCalendars(value);
|
||||||
|
},
|
||||||
|
events(value) {
|
||||||
|
this.calendarInstance.clear();
|
||||||
|
this.calendarInstance.createEvents(value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.calendarInstance = new Calendar(this.$refs.container, {
|
||||||
|
defaultView: this.view,
|
||||||
|
useFormPopup: this.useFormPopup,
|
||||||
|
useDetailPopup: this.useDetailPopup,
|
||||||
|
isReadOnly: this.isReadOnly,
|
||||||
|
usageStatistics: this.usageStatistics,
|
||||||
|
eventFilter: this.eventFilter,
|
||||||
|
week: this.week,
|
||||||
|
month: this.month,
|
||||||
|
gridSelection: this.gridSelection,
|
||||||
|
timezone: this.timezone,
|
||||||
|
theme: this.theme,
|
||||||
|
template: this.template,
|
||||||
|
calendars: this.calendars,
|
||||||
|
});
|
||||||
|
this.addEventListeners();
|
||||||
|
this.calendarInstance.createEvents(this.events);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.calendarInstance.off();
|
||||||
|
this.calendarInstance.destroy();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addEventListeners() {
|
||||||
|
Object.keys(this.$listeners).forEach((eventName) => {
|
||||||
|
this.calendarInstance.on(eventName, (...args) => this.$emit(eventName, ...args));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getRootElement() {
|
||||||
|
return this.$refs.container;
|
||||||
|
},
|
||||||
|
getInstance() {
|
||||||
|
return this.calendarInstance;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
63
resources/assets/js/pages/manage/components/Calendar/theme.js
vendored
Normal file
63
resources/assets/js/pages/manage/components/Calendar/theme.js
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
export const theme = {
|
||||||
|
common: {
|
||||||
|
border: '1px solid #ddd',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
holiday: {color: '#f54f3d'},
|
||||||
|
saturday: {color: '#135de6'},
|
||||||
|
dayName: {color: '#333'},
|
||||||
|
today: {color: '#009688'},
|
||||||
|
gridSelection: {
|
||||||
|
backgroundColor: 'rgba(19, 93, 230, 0.1)',
|
||||||
|
border: '1px solid #135de6',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
month: {
|
||||||
|
dayName: {
|
||||||
|
borderLeft: 'none',
|
||||||
|
backgroundColor: 'inherit',
|
||||||
|
},
|
||||||
|
holidayExceptThisMonth: {color: '#f3acac'},
|
||||||
|
dayExceptThisMonth: {color: '#bbb'},
|
||||||
|
weekend: {backgroundColor: '#fafafa'},
|
||||||
|
moreView: {boxShadow: 'none'},
|
||||||
|
moreViewTitle: {backgroundColor: '#f4f4f4'},
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
dayName: {
|
||||||
|
borderTop: 'none',
|
||||||
|
borderBottom: 'none',
|
||||||
|
borderLeft: '1px solid #ddd',
|
||||||
|
backgroundColor: 'inherit',
|
||||||
|
},
|
||||||
|
today: {
|
||||||
|
color: '#009688',
|
||||||
|
backgroundColor: 'inherit',
|
||||||
|
},
|
||||||
|
pastDay: {color: '#999'},
|
||||||
|
panelResizer: {border: '1px solid #ddd'},
|
||||||
|
dayGrid: {borderRight: '1px solid #ddd'},
|
||||||
|
dayGridLeft: {
|
||||||
|
width: '100px',
|
||||||
|
backgroundColor: '',
|
||||||
|
borderRight: '1px solid #ddd',
|
||||||
|
},
|
||||||
|
weekend: {backgroundColor: 'inherit'},
|
||||||
|
timeGridLeft: {
|
||||||
|
width: '100px',
|
||||||
|
backgroundColor: '#fafafa',
|
||||||
|
borderRight: '1px solid #ddd',
|
||||||
|
},
|
||||||
|
timeGridLeftAdditionalTimezone: {backgroundColor: '#fdfdfd'},
|
||||||
|
timeGridHourLine: {borderBottom: '1px solid #eee'},
|
||||||
|
timeGridHalfHourLine: {borderBottom: '1px dotted #f9f9f9'},
|
||||||
|
timeGrid: {borderRight: '1px solid #ddd'},
|
||||||
|
nowIndicatorLabel: {color: '#135de6'},
|
||||||
|
nowIndicatorPast: {border: '1px solid rgba(19, 93, 230, 0.3)'},
|
||||||
|
nowIndicatorBullet: {backgroundColor: '#135de6'},
|
||||||
|
nowIndicatorToday: {border: '1px solid #135de6'},
|
||||||
|
nowIndicatorFuture: {border: '1px solid #135de6'},
|
||||||
|
pastTime: {color: '#999'},
|
||||||
|
futureTime: {color: '#333'},
|
||||||
|
gridSelection: {color: '#135de6'},
|
||||||
|
},
|
||||||
|
};
|
||||||
2
resources/assets/js/store/actions.js
vendored
2
resources/assets/js/store/actions.js
vendored
@ -1020,6 +1020,7 @@ export default {
|
|||||||
const cacheItems = {
|
const cacheItems = {
|
||||||
clientId: await $A.IDBString("clientId"),
|
clientId: await $A.IDBString("clientId"),
|
||||||
cacheServerUrl: await $A.IDBString("cacheServerUrl"),
|
cacheServerUrl: await $A.IDBString("cacheServerUrl"),
|
||||||
|
cacheCalendarView: await $A.IDBString("cacheCalendarView"),
|
||||||
cacheProjectParameter: await $A.IDBArray("cacheProjectParameter"),
|
cacheProjectParameter: await $A.IDBArray("cacheProjectParameter"),
|
||||||
cacheLoginEmail: await $A.IDBString("cacheLoginEmail"),
|
cacheLoginEmail: await $A.IDBString("cacheLoginEmail"),
|
||||||
cacheFileSort: await $A.IDBJson("cacheFileSort"),
|
cacheFileSort: await $A.IDBJson("cacheFileSort"),
|
||||||
@ -1061,6 +1062,7 @@ export default {
|
|||||||
string: [
|
string: [
|
||||||
'clientId',
|
'clientId',
|
||||||
'cacheServerUrl',
|
'cacheServerUrl',
|
||||||
|
'cacheCalendarView',
|
||||||
'cacheTranslationLanguage',
|
'cacheTranslationLanguage',
|
||||||
'cacheTranscriptionLanguage'
|
'cacheTranscriptionLanguage'
|
||||||
],
|
],
|
||||||
|
|||||||
3
resources/assets/js/store/state.js
vendored
3
resources/assets/js/store/state.js
vendored
@ -75,6 +75,9 @@ export default {
|
|||||||
cacheUserWait: [],
|
cacheUserWait: [],
|
||||||
cacheUserBasic: [],
|
cacheUserBasic: [],
|
||||||
|
|
||||||
|
// 日历
|
||||||
|
cacheCalendarView: null,
|
||||||
|
|
||||||
// Dialog
|
// Dialog
|
||||||
cacheDialogs: [],
|
cacheDialogs: [],
|
||||||
|
|
||||||
|
|||||||
167
resources/assets/sass/pages/components/calendar.scss
vendored
167
resources/assets/sass/pages/components/calendar.scss
vendored
@ -1,164 +1,17 @@
|
|||||||
.calendar-wrapper {
|
.calendar-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
&:before {
|
.toastui-calendar-day-name-item.toastui-calendar-week,
|
||||||
content: "";
|
.toastui-calendar-day-names.toastui-calendar-week {
|
||||||
position: absolute;
|
overflow: hidden;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
height: 2px;
|
|
||||||
background-color: #ffffff;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
.tui-full-calendar-popup {
|
.toastui-calendar-month-more-list {
|
||||||
box-shadow: none;
|
.toastui-calendar-weekday-event-title {
|
||||||
font-weight: normal;
|
> div {
|
||||||
.tui-full-calendar-section-header {
|
padding: 0 2px;
|
||||||
.tui-full-calendar-ic-checkbox-checked {
|
overflow: hidden;
|
||||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAhFBMVEUAAACLz3CLz3CLz3CKzm6Gy2+Lz3CLz3CL0HCLz3CLz3CLz3CLz3CMz3GLz3CKz3CLz3CL0HCJ0G+KznCN0HCL0HCLz3CKz3CLz3CLz3CLz3CMz3CLz3CLz3GL0XCL0HCN0XKLz3CLz3CMz3CLz3CM0HCM0G+FzHCLz3CKz3CMz3CLz3Bod5CFAAAAK3RSTlMA18RAOQ3s8+Pc0rmyq3tpiUwTgBnovyDMjmNSRjUvJQX5yKB0WisKppuUFLaY7gAAAotJREFUeNrtm+FymkAUhc8KqIAgSkyUtkmsmqa97/9+HWeSudpCd8qZ7E0m+73A9/1gxmXx4IK0nbipvDFTN2lT9JDVToLh6gx/sHQSFLfEFZUEp8IFczFgrv5CTChe/TsxYvfy/IkZy7M/c2KGywDUYkgNIBdDciARUxI0YkqDiZgygRNTHKZiyhRiTAyIATEgBsSAGBADYsAnCJgdmtIywKUAOrsA94QzJyKA95/pbALcPV7piADGryzDB+Rnv3IkAhi/UhMBjF9pQwbk3/A3JRXA+7GjAng/DqEC5v3+dMYE8P6nQsIEzFOPnw7g/QpC+R8K4QJ4f5iAzaA/TMAm6fdvZQgY+wW2fn9A0a66Bee/2xLH8kp/Rr1MB/3jAxaP0ALCPzagzPBCM9r/XcYH3K4BLfD4vw75xwdMbqB4CmaD/vEB2ztc0RD+MQHFg+c85fffDPv9AbPUd6Lz+ydCBDyjh1//6WcCGngK1L8a8lMBJTwFfj8XIC16+SnX7Af9bIDUngLSrwFEwaD/VogA5YheDj7/Wv1MgL9g/8XjpwNk+c8Cyq8BYwqePX46QOkGCmi/BowrqFi/Bvg4wYv6y7e4Kz4Rfj5AnzY/WSlcwHAB5+cD9ivKzwfIbEX4qQA99RB+NkDfO4b5sRAigHjzpP0C6u6D9wuo2z/eL+DvXx8Zv4C4gVd/qABxCeFnApQT5+cDpOP8fICcLv2VxbfjlQZUNh+vU/XbBIj6jQLm9wDWlZgFyOaYHJ3Ix/gDQwyIATEgBsSAGODBfuBgPvEwH7m0YkqLVExJYfsQuPcwdjOf+5kPHoFKjKio0e3Hn90WUCyGt7v3Nf0GsjqXYOR1hh6SJsz8v0mg/AZRXmaRKXtJBwAAAABJRU5ErkJggg==);
|
white-space: nowrap;
|
||||||
}
|
text-overflow: ellipsis;
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-container {
|
|
||||||
word-break: break-all;
|
|
||||||
border: 0;
|
|
||||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
.tui-full-calendar-arrow-top .tui-full-calendar-popup-arrow-border {
|
|
||||||
top: -8px;
|
|
||||||
border-bottom-color: rgba(217, 217, 217, .5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-dropdown-menu {
|
|
||||||
border-color: #e8e8e8;
|
|
||||||
width: calc(100% - 14px);
|
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-creation {
|
|
||||||
.tui-full-calendar-icon {
|
|
||||||
&.tui-full-calendar-ic-title,
|
|
||||||
&.tui-full-calendar-calendar-dot {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
&.tui-full-calendar-ic-date {
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNjIzODU5NjcwNjA3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE2Mzg4IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTk2MCAxMjhIODMzYzAtNTMtNDMtOTYtOTYtOTZoLTE2Yy01MyAwLTk2IDQzLTk2IDk2SDQwMGMwLTI2LjUtMTAuNy01MC41LTI4LjEtNjcuOUMzNTQuNSA0Mi43IDMzMC41IDMyIDMwNCAzMmgtMTZjLTUzIDAtOTYgNDMtOTYgOTZINjRjLTM1LjMgMC02NCAyOC42LTY0IDY0djczNmMwIDM1LjMgMjguNyA2NCA2NCA2NGg4OTZjMzUuMyAwIDY0LTI4LjcgNjQtNjRWMTkyYzAtMzUuNC0yOC43LTY0LTY0LTY0eiBtLTI3MSA4YzAtMjIuMSAxNy45LTQwIDQwLTQwczQwIDE3LjkgNDAgNDB2ODBjMCAyMi4xLTE3LjkgNDAtNDAgNDAtMTEgMC0yMS00LjUtMjguMy0xMS43QzY5My41IDIzNyA2ODkgMjI3IDY4OSAyMTZ2LTgweiBtLTQzMyAwYzAtMjIuMSAxNy45LTQwIDQwLTQwczQwIDE3LjkgNDAgNDB2ODBjMCAyMi4xLTE3LjkgNDAtNDAgNDAtMTEgMC0yMS00LjUtMjguMy0xMS43QzI2MC41IDIzNyAyNTYgMjI3IDI1NiAyMTZ2LTgweiBtNzA0IDc2MGMwIDE3LjctMTQuMyAzMi0zMiAzMkg5NmMtMTcuNyAwLTMyLTE0LjMtMzItMzJWNDQ4aDg5NnY0NDh6IiBwLWlkPSIxNjM4OSIgZmlsbD0iIzUxNTE1MSI+PC9wYXRoPjwvc3ZnPg==");
|
|
||||||
background-size: contain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-content {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-section {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
.tui-full-calendar-popup-section-item {
|
|
||||||
height: 36px;
|
|
||||||
line-height: 34px;
|
|
||||||
border-color: #e8e8e8;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-section-item input {
|
|
||||||
height: 34px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-section-title {
|
|
||||||
width: 100%;
|
|
||||||
input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-section-start-date,
|
|
||||||
.tui-full-calendar-section-end-date {
|
|
||||||
width: 210px;
|
|
||||||
.tui-full-calendar-content {
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-location,
|
|
||||||
.tui-full-calendar-section-private,
|
|
||||||
.tui-full-calendar-section-allday,
|
|
||||||
.tui-full-calendar-section-state {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-task {
|
|
||||||
.priority {
|
|
||||||
color: #ffffff;
|
|
||||||
padding: 2px 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
.overdue {
|
|
||||||
color: #f5222d;
|
|
||||||
background: #fff1f0;
|
|
||||||
border: 1px solid #ffa39e;
|
|
||||||
padding: 1px 3px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
.tui-full-calendar-calendar-dot,
|
|
||||||
.tui-full-calendar-ic-priority {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
.tui-full-calendar-ic-edit {
|
|
||||||
top: -2px;
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNjIzODU5MzY4MTg5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjExMTkiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNODMzLjQyODU3MTY4IDYySDE5MC41NzE0MjgzMmExMjguNTcxNDI4MzIgMTI4LjU3MTQyODMyIDAgMCAwLTEyOC41NzE0MjgzMiAxMjguNTcxNDI4MzJ2NjQyLjg1NzE0MzM2YTEyOC41NzE0MjgzMiAxMjguNTcxNDI4MzIgMCAwIDAgMTI4LjU3MTQyODMyIDEyOC41NzE0MjgzMmg2NDIuODU3MTQzMzZhMTI4LjU3MTQyODMyIDEyOC41NzE0MjgzMiAwIDAgMCAxMjguNTcxNDI4MzItMTI4LjU3MTQyODMyVjE5MC41NzE0MjgzMmExMjguNTcxNDI4MzIgMTI4LjU3MTQyODMyIDAgMCAwLTEyOC41NzE0MjgzMi0xMjguNTcxNDI4MzJ6IG02NC4yODU3MTQxNiA3NzEuNDI4NTcxNjhhNjQuMjg1NzE0MTYgNjQuMjg1NzE0MTYgMCAwIDEtNjQuMjg1NzE0MTcgNjQuMjg1NzE0MTZIMTkwLjU3MTQyODMyYTY0LjI4NTcxNDE2IDY0LjI4NTcxNDE2IDAgMCAxLTY0LjI4NTcxNDE2LTY0LjI4NTcxNDE2VjE5MC41NzE0MjgzMmE2NC4yODU3MTQxNiA2NC4yODU3MTQxNiAwIDAgMSA2NC4yODU3MTQxNy02NC4yODU3MTQxNmg2NDIuODU3MTQzMzVhNjQuMjg1NzE0MTYgNjQuMjg1NzE0MTYgMCAwIDEgNjQuMjg1NzE0MTYgNjQuMjg1NzE0MTd6IiBwLWlkPSIxMTIwIiBmaWxsPSIjNTE1MTUxIj48L3BhdGg+PHBhdGggZD0iTTE5MC41NzE0MjgzMiAyNTQuODU3MTQyNDhoNjQuMjg1NzE0MTZ2NjQuMjg1NzE1MDRIMTkwLjU3MTQyODMyek0zMTkuMTQyODU3NTIgMjU0Ljg1NzE0MjQ4aDQ1MHY2NC4yODU3MTUwNEgzMTkuMTQyODU3NTJ6TTE5MC41NzE0MjgzMiA0NDcuNzE0Mjg1ODRoNjQuMjg1NzE0MTZ2NjQuMjg1NzE0MTZIMTkwLjU3MTQyODMyek0zMTkuMTQyODU3NTIgNDQ3LjcxNDI4NTg0aDQ1MHY2NC4yODU3MTQxNkgzMTkuMTQyODU3NTJ6TTE5MC41NzE0MjgzMiA2NDAuNTcxNDI4MzJoNjQuMjg1NzE0MTZ2NjQuMjg1NzE0MTZIMTkwLjU3MTQyODMyek0zMTkuMTQyODU3NTIgNjQwLjU3MTQyODMyaDMyMS40Mjg1NzA4djY0LjI4NTcxNDE2SDMxOS4xNDI4NTc1MnoiIHAtaWQ9IjExMjEiIGZpbGw9IiM1MTUxNTEiPjwvcGF0aD48L3N2Zz4=");
|
|
||||||
}
|
|
||||||
.tui-full-calendar-ic-delete {
|
|
||||||
top: -2px;
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNjIzODU5MzMwMTc2IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9Ijc5MiIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPjxwYXRoIGQ9Ik04OTIuMjg4IDI1NmgtMTkxLjE2OEEyMDIuMjQgMjAyLjI0IDAgMCAwIDUwOS42MzIgNjIuMDggMjAxLjIxNiAyMDEuMjE2IDAgMCAwIDMxOC44NDggMjU2SDEyOGMtMTguNjg4IDAtNjYuMDQ4LTQuMjI0LTY2LjA0OCAyNC43NjhDNjEuOTUyIDMyNy43NDQgMTA5LjM3NiAzMjAgMTI4IDMyMGg2NHY1MTJhMTQ2LjQ5NiAxNDYuNDk2IDAgMCAwIDEyNy40MjQgMTI4aDM4Mi4yNzJBMTUwLjAxNiAxNTAuMDE2IDAgMCAwIDgzMiA4MzJsLTMuMzkyLTUxMmg2NGMxOC4zNjggMCA2NS4wMjQgMS40NzIgNjUuMDI0LTM5Ljc0NEE3Mi4zODQgNzIuMzg0IDAgMCAwIDg5Mi4yODggMjU2ek01MDkuNjMyIDEyOC41MTJBMTM4LjE3NiAxMzguMTc2IDAgMCAxIDYzNy40NCAyNTZIMzgyLjU5MmExMzcuOTIgMTM3LjkyIDAgMCAxIDEyNy4wNC0xMjcuNDg4ek03NjggODMyYTk3Ljk4NCA5Ny45ODQgMCAwIDEtNjYuODggNjRIMzE4Ljg0OGE5My41NjggOTMuNTY4IDAgMCAxLTY0LTY0VjMyMEg3Njh2NTEyeiBtLTM4NS40MDgtNjRWNTEyYzAtMTguNDk2IDAuOTYtNjAuOTkyIDM2LjczNi02MC45OTIgMjcuMzI4IDAgMjYuNDk2IDQzLjAwOCAyNi45NDQgNjAuOTkydjI1NmMwIDE4LjQ5Ni02LjQgMjAuMDMyLTI0Ljk2IDIwLjAzMnMtMzguNzItMS41MzYtMzguNzItMjAuMDMyeiBtMTkxLjE2OCAwVjUxMmE2NCA2NCAwIDAgMSAyMy44MDgtNjAuOTkyYzQyLjQzMiAwIDM5LjM2IDQzLjAwOCAzOS44NzIgNjAuOTkydjI1NmMwIDE4LjQ5Ni0xOS41ODQgMjAuMDMyLTM3Ljk1MiAyMC4wMzJzLTI1Ljc5Mi0xLjUzNi0yNS43OTItMjAuMDMyeiIgcC1pZD0iNzkzIiBmaWxsPSIjNTE1MTUxIj48L3BhdGg+PC9zdmc+");
|
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-detail-item-separate {
|
|
||||||
padding-left: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-popup-detail {
|
|
||||||
.tui-full-calendar-content {
|
|
||||||
line-height: normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-datepicker {
|
|
||||||
border-color: #e8e8e8;
|
|
||||||
.tui-calendar {
|
|
||||||
th,
|
|
||||||
td {
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
.tui-calendar-prev-month.tui-calendar-date,
|
|
||||||
.tui-calendar-next-month.tui-calendar-date {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-datepicker-body .tui-timepicker,
|
|
||||||
.tui-datepicker-footer .tui-timepicker {
|
|
||||||
padding: 16px 46px 16px 47px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tui-full-calendar-week-container{
|
|
||||||
min-height: 100px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body.window-portrait {
|
|
||||||
.calendar-wrapper {
|
|
||||||
.tui-full-calendar-section-button {
|
|
||||||
> button {
|
|
||||||
.tui-full-calendar-icon {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
background-size: 14px;
|
|
||||||
}
|
|
||||||
.tui-full-calendar-content {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
.calendar-wrapper {
|
|
||||||
.tui-full-calendar-popup-arrow {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
resources/assets/sass/pages/page-calendar.scss
vendored
32
resources/assets/sass/pages/page-calendar.scss
vendored
@ -51,13 +51,6 @@
|
|||||||
padding: 0 48px 6px;
|
padding: 0 48px 6px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.calendar-menu {
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
right: 2px;
|
|
||||||
z-index: -1;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body.window-portrait {
|
body.window-portrait {
|
||||||
@ -79,31 +72,6 @@ body.window-portrait {
|
|||||||
}
|
}
|
||||||
.calendar-box {
|
.calendar-box {
|
||||||
padding: 0 24px 5px;
|
padding: 0 24px 5px;
|
||||||
.calendar-wrapper {
|
|
||||||
.tui-full-calendar-section-button {
|
|
||||||
> button {
|
|
||||||
.tui-full-calendar-icon {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
background-size: 14px;
|
|
||||||
}
|
|
||||||
.tui-full-calendar-content {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 640px) {
|
|
||||||
.page-calendar {
|
|
||||||
.calendar-box {
|
|
||||||
.calendar-wrapper {
|
|
||||||
.tui-full-calendar-popup-arrow {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user