Merge branch 'master' of github.com:kuaifan/dootask into develop
# Conflicts: # electron/package.json # package.json # public/js/app.js # public/js/build/161.js # public/js/build/400.js # public/js/build/616.js # public/js/build/845.js
This commit is contained in:
commit
8bacc3b6ba
@ -876,6 +876,7 @@ class ProjectController extends AbstractController
|
|||||||
* - yes:已完成
|
* - yes:已完成
|
||||||
* - no:未完成
|
* - no:未完成
|
||||||
* @apiParam {String} [archived] 归档状态
|
* @apiParam {String} [archived] 归档状态
|
||||||
|
* - all:所有
|
||||||
* - yes:已归档
|
* - yes:已归档
|
||||||
* - no:未归档(默认)
|
* - no:未归档(默认)
|
||||||
* @apiParam {Object} sorts 排序方式
|
* @apiParam {Object} sorts 排序方式
|
||||||
@ -911,7 +912,7 @@ class ProjectController extends AbstractController
|
|||||||
//
|
//
|
||||||
$scopeAll = false;
|
$scopeAll = false;
|
||||||
if ($parent_id > 0) {
|
if ($parent_id > 0) {
|
||||||
ProjectTask::userTask($parent_id);
|
ProjectTask::userTask($parent_id, str_replace(['all', 'yes', 'no'], [null, false, true], $archived));
|
||||||
$scopeAll = true;
|
$scopeAll = true;
|
||||||
$builder->where('project_tasks.parent_id', $parent_id);
|
$builder->where('project_tasks.parent_id', $parent_id);
|
||||||
} elseif ($parent_id === -1) {
|
} elseif ($parent_id === -1) {
|
||||||
@ -974,6 +975,10 @@ class ProjectController extends AbstractController
|
|||||||
* @apiName task__one
|
* @apiName task__one
|
||||||
*
|
*
|
||||||
* @apiParam {Number} task_id 任务ID
|
* @apiParam {Number} task_id 任务ID
|
||||||
|
* @apiParam {String} [archived] 归档状态
|
||||||
|
* - all:所有
|
||||||
|
* - yes:已归档
|
||||||
|
* - no:未归档(默认)
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
@ -984,8 +989,9 @@ class ProjectController extends AbstractController
|
|||||||
User::auth();
|
User::auth();
|
||||||
//
|
//
|
||||||
$task_id = intval(Request::input('task_id'));
|
$task_id = intval(Request::input('task_id'));
|
||||||
|
$archived = Request::input('archived', 'no');
|
||||||
//
|
//
|
||||||
$task = ProjectTask::userTask($task_id, true, false, ['taskUser', 'taskTag']);
|
$task = ProjectTask::userTask($task_id, str_replace(['all', 'yes', 'no'], [null, false, true], $archived), false, ['taskUser', 'taskTag']);
|
||||||
//
|
//
|
||||||
$data = $task->toArray();
|
$data = $task->toArray();
|
||||||
$data['project_name'] = $task->project?->name;
|
$data['project_name'] = $task->project?->name;
|
||||||
@ -1013,7 +1019,7 @@ class ProjectController extends AbstractController
|
|||||||
//
|
//
|
||||||
$task_id = intval(Request::input('task_id'));
|
$task_id = intval(Request::input('task_id'));
|
||||||
//
|
//
|
||||||
$task = ProjectTask::userTask($task_id);
|
$task = ProjectTask::userTask($task_id, null);
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', $task->content ?: json_decode('{}'));
|
return Base::retSuccess('success', $task->content ?: json_decode('{}'));
|
||||||
}
|
}
|
||||||
@ -1038,7 +1044,7 @@ class ProjectController extends AbstractController
|
|||||||
//
|
//
|
||||||
$task_id = intval(Request::input('task_id'));
|
$task_id = intval(Request::input('task_id'));
|
||||||
//
|
//
|
||||||
$task = ProjectTask::userTask($task_id);
|
$task = ProjectTask::userTask($task_id, null);
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', $task->taskFile);
|
return Base::retSuccess('success', $task->taskFile);
|
||||||
}
|
}
|
||||||
@ -1381,7 +1387,11 @@ class ProjectController extends AbstractController
|
|||||||
} elseif ($type == 'add') {
|
} elseif ($type == 'add') {
|
||||||
$task->archivedTask(Carbon::now());
|
$task->archivedTask(Carbon::now());
|
||||||
}
|
}
|
||||||
return Base::retSuccess('操作成功', ['id' => $task->id]);
|
return Base::retSuccess('操作成功', [
|
||||||
|
'id' => $task->id,
|
||||||
|
'archived_at' => $task->archived_at,
|
||||||
|
'archived_userid' => $task->archived_userid,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1435,7 +1445,7 @@ class ProjectController extends AbstractController
|
|||||||
return Base::retError('记录不存在');
|
return Base::retError('记录不存在');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$task = ProjectTask::userTask($projectLog->task_id, null, true);
|
$task = ProjectTask::userTask($projectLog->task_id, true, true);
|
||||||
//
|
//
|
||||||
$record = $projectLog->record;
|
$record = $projectLog->record;
|
||||||
if ($record['flow'] && is_array($record['flow'])) {
|
if ($record['flow'] && is_array($record['flow'])) {
|
||||||
|
@ -18,6 +18,7 @@ use Illuminate\Support\Facades\DB;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
||||||
* @method static \Illuminate\Database\Eloquent\Model|object|static|null cancelAppend()
|
* @method static \Illuminate\Database\Eloquent\Model|object|static|null cancelAppend()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Model|object|static|null cancelHidden()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|static with($relations)
|
* @method static \Illuminate\Database\Eloquent\Builder|static with($relations)
|
||||||
* @method static \Illuminate\Database\Query\Builder|static select($columns = [])
|
* @method static \Illuminate\Database\Query\Builder|static select($columns = [])
|
||||||
* @method static \Illuminate\Database\Query\Builder|static whereNotIn($column, $values, $boolean = 'and')
|
* @method static \Illuminate\Database\Query\Builder|static whereNotIn($column, $values, $boolean = 'and')
|
||||||
@ -72,6 +73,15 @@ class AbstractModel extends Model
|
|||||||
return $this->setAppends([]);
|
return $this->setAppends([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消隐藏值
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
protected function scopeCancelHidden()
|
||||||
|
{
|
||||||
|
return $this->setHidden([]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为数组 / JSON 序列化准备日期。
|
* 为数组 / JSON 序列化准备日期。
|
||||||
* @param DateTimeInterface $date
|
* @param DateTimeInterface $date
|
||||||
|
@ -686,11 +686,11 @@ class ProjectTask extends AbstractModel
|
|||||||
$start_at = Carbon::parse($subTask->start_at);
|
$start_at = Carbon::parse($subTask->start_at);
|
||||||
$end_at = Carbon::parse($subTask->end_at);
|
$end_at = Carbon::parse($subTask->end_at);
|
||||||
$isUp = false;
|
$isUp = false;
|
||||||
if ($start_at->eq($oldAt[0]) || $start_at->lt(Carbon::parse($this->start_at))) {
|
if (empty($subTask->start_at) || $start_at->eq($oldAt[0]) || $start_at->lt(Carbon::parse($this->start_at))) {
|
||||||
$subTask->start_at = $this->start_at;
|
$subTask->start_at = $this->start_at;
|
||||||
$isUp = true;
|
$isUp = true;
|
||||||
}
|
}
|
||||||
if ($end_at->eq($oldAt[1]) || $end_at->gt(Carbon::parse($this->end_at))) {
|
if (empty($subTask->end_at) || $end_at->eq($oldAt[1]) || $end_at->gt(Carbon::parse($this->end_at))) {
|
||||||
$subTask->end_at = $this->end_at;
|
$subTask->end_at = $this->end_at;
|
||||||
$isUp = true;
|
$isUp = true;
|
||||||
}
|
}
|
||||||
@ -918,7 +918,6 @@ class ProjectTask extends AbstractModel
|
|||||||
$this->archived_userid = User::userid();
|
$this->archived_userid = User::userid();
|
||||||
$this->archived_follow = 0;
|
$this->archived_follow = 0;
|
||||||
$this->addLog("任务取消归档");
|
$this->addLog("任务取消归档");
|
||||||
$this->pushMsg('add', ProjectTask::oneTask($this->id));
|
|
||||||
} else {
|
} else {
|
||||||
// 归档任务
|
// 归档任务
|
||||||
if ($isAuto === true) {
|
if ($isAuto === true) {
|
||||||
@ -932,8 +931,12 @@ class ProjectTask extends AbstractModel
|
|||||||
$this->archived_userid = $userid;
|
$this->archived_userid = $userid;
|
||||||
$this->archived_follow = 0;
|
$this->archived_follow = 0;
|
||||||
$this->addLog($logText, [], $userid);
|
$this->addLog($logText, [], $userid);
|
||||||
$this->pushMsg('archived');
|
|
||||||
}
|
}
|
||||||
|
$this->pushMsg('update', [
|
||||||
|
'id' => $this->id,
|
||||||
|
'archived_at' => $this->archived_at,
|
||||||
|
'archived_userid' => $this->archived_userid,
|
||||||
|
]);
|
||||||
self::whereParentId($this->id)->update([
|
self::whereParentId($this->id)->update([
|
||||||
'archived_at' => $this->archived_at,
|
'archived_at' => $this->archived_at,
|
||||||
'archived_userid' => $this->archived_userid,
|
'archived_userid' => $this->archived_userid,
|
||||||
@ -1059,7 +1062,7 @@ class ProjectTask extends AbstractModel
|
|||||||
/**
|
/**
|
||||||
* 获取任务(会员有任务权限 或 会员存在项目内)
|
* 获取任务(会员有任务权限 或 会员存在项目内)
|
||||||
* @param int $task_id
|
* @param int $task_id
|
||||||
* @param bool $archived true:仅限未归档, false:不限制, null:不限制
|
* @param bool $archived true:仅限未归档, false:仅限已归档, null:不限制
|
||||||
* @param int|bool $mustOwner 0|false:不限制, 1|true:限制任务或项目负责人, 2:已有负责人才限制任务或项目负责人
|
* @param int|bool $mustOwner 0|false:不限制, 1|true:限制任务或项目负责人, 2:已有负责人才限制任务或项目负责人
|
||||||
* @param array $with
|
* @param array $with
|
||||||
* @return self
|
* @return self
|
||||||
@ -1072,7 +1075,7 @@ class ProjectTask extends AbstractModel
|
|||||||
throw new ApiException('任务不存在', [ 'task_id' => $task_id ], -4002);
|
throw new ApiException('任务不存在', [ 'task_id' => $task_id ], -4002);
|
||||||
}
|
}
|
||||||
if ($archived === true && $task->archived_at != null) {
|
if ($archived === true && $task->archived_at != null) {
|
||||||
throw new ApiException('任务已归档', [ 'task_id' => $task_id ], -4002);
|
throw new ApiException('任务已归档', [ 'task_id' => $task_id ]);
|
||||||
}
|
}
|
||||||
if ($archived === false && $task->archived_at == null) {
|
if ($archived === false && $task->archived_at == null) {
|
||||||
throw new ApiException('任务未归档', [ 'task_id' => $task_id ]);
|
throw new ApiException('任务未归档', [ 'task_id' => $task_id ]);
|
||||||
|
@ -120,10 +120,10 @@ class WebSocketDialog extends AbstractModel
|
|||||||
break;
|
break;
|
||||||
case "group":
|
case "group":
|
||||||
if ($dialog->group_type === 'project') {
|
if ($dialog->group_type === 'project') {
|
||||||
$dialog->group_info = Project::withTrashed()->select(['id', 'name'])->whereDialogId($dialog->id)->first();
|
$dialog->group_info = Project::withTrashed()->select(['id', 'name', 'archived_at', 'deleted_at'])->whereDialogId($dialog->id)->first()?->cancelAppend()->cancelHidden();
|
||||||
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
||||||
} elseif ($dialog->group_type === 'task') {
|
} elseif ($dialog->group_type === 'task') {
|
||||||
$dialog->group_info = ProjectTask::withTrashed()->select(['id', 'name'])->whereDialogId($dialog->id)->first();
|
$dialog->group_info = ProjectTask::withTrashed()->select(['id', 'name', 'complete_at', 'archived_at', 'deleted_at'])->whereDialogId($dialog->id)->first()?->cancelAppend()->cancelHidden();
|
||||||
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "DooTask",
|
"name": "DooTask",
|
||||||
"version": "0.6.83",
|
"version": "0.6.90",
|
||||||
"description": "DooTask is task management system.",
|
"description": "DooTask is task management system.",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "DooTask",
|
"name": "DooTask",
|
||||||
"version": "0.6.83",
|
"version": "0.6.90",
|
||||||
"description": "DooTask is task management system.",
|
"description": "DooTask is task management system.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "./cmd dev",
|
"start": "./cmd dev",
|
||||||
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
2
public/js/app.js
vendored
2
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/js/build/113.js
vendored
Normal file
1
public/js/build/113.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
public/js/build/120.js
vendored
2
public/js/build/120.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
* html2canvas 1.3.4 <https://html2canvas.hertzen.com>
|
* html2canvas 1.4.0 <https://html2canvas.hertzen.com>
|
||||||
* Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>
|
* Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>
|
||||||
* Released under MIT License
|
* Released under MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
1
public/js/build/307.js
vendored
1
public/js/build/307.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
public/js/build/328.js
vendored
2
public/js/build/328.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
public/js/build/357.js
vendored
2
public/js/build/357.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/388.js
vendored
2
public/js/build/388.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/400.js
vendored
Normal file
2
public/js/build/400.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
* TOAST UI Calendar
|
* TOAST UI Calendar
|
||||||
* @version 1.15.1 | Wed Dec 22 2021
|
* @version 1.15.1-5 | Sun Jan 09 2022
|
||||||
* @author NHN FE Development Lab <dl_javascript@nhn.com>
|
* @author NHN FE Development Lab <dl_javascript@nhn.com>
|
||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
@ -304,7 +304,7 @@
|
|||||||
|
|
||||||
/*! ./weekdayInMonth */
|
/*! ./weekdayInMonth */
|
||||||
|
|
||||||
/*! @license DOMPurify 2.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.1/LICENSE */
|
/*! @license DOMPurify 2.3.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.4/LICENSE */
|
||||||
|
|
||||||
/*! dompurify */
|
/*! dompurify */
|
||||||
|
|
1
public/js/build/43.js
vendored
Normal file
1
public/js/build/43.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
public/js/build/494.js
vendored
2
public/js/build/494.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/603.js
vendored
2
public/js/build/603.js
vendored
File diff suppressed because one or more lines are too long
1
public/js/build/639.js
vendored
1
public/js/build/639.js
vendored
File diff suppressed because one or more lines are too long
1
public/js/build/700.js
vendored
1
public/js/build/700.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/js/build/893.js
vendored
Normal file
1
public/js/build/893.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
public/js/build/954.js
vendored
2
public/js/build/954.js
vendored
File diff suppressed because one or more lines are too long
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"/js/app.js": "/js/app.js",
|
"/js/app.js": "/js/app.js",
|
||||||
"/css/app.css": "/css/app.css",
|
"/css/app.css": "/css/app.css",
|
||||||
|
"/.DS_Store": "/.DS_Store",
|
||||||
"/favicon.ico": "/favicon.ico"
|
"/favicon.ico": "/favicon.ico"
|
||||||
}
|
}
|
||||||
|
40
resources/assets/js/functions/web.js
vendored
40
resources/assets/js/functions/web.js
vendored
@ -315,6 +315,46 @@
|
|||||||
return [new Date(), lastSecond(e.getTime())];
|
return [new Date(), lastSecond(e.getTime())];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话标签
|
||||||
|
* @param dialog
|
||||||
|
* @returns {*[]}
|
||||||
|
*/
|
||||||
|
dialogTags(dialog) {
|
||||||
|
let tags = [];
|
||||||
|
if (dialog.type == 'group') {
|
||||||
|
if (['project', 'task'].includes(dialog.group_type) && $A.isJson(dialog.group_info)) {
|
||||||
|
if (dialog.group_type == 'task' && dialog.group_info.complete_at) {
|
||||||
|
tags.push({
|
||||||
|
color: 'success',
|
||||||
|
text: '已完成'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (dialog.group_info.deleted_at) {
|
||||||
|
tags.push({
|
||||||
|
color: 'red',
|
||||||
|
text: '已删除'
|
||||||
|
})
|
||||||
|
} else if (dialog.group_info.archived_at) {
|
||||||
|
tags.push({
|
||||||
|
color: 'default',
|
||||||
|
text: '已归档'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tags;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话完成
|
||||||
|
* @param dialog
|
||||||
|
* @returns {*[]}
|
||||||
|
*/
|
||||||
|
dialogCompleted(dialog) {
|
||||||
|
return this.dialogTags(dialog).find(({color}) => color == 'success');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ export default {
|
|||||||
|
|
||||||
msgAllUnread() {
|
msgAllUnread() {
|
||||||
let num = 0;
|
let num = 0;
|
||||||
this.cacheDialogs.map(({unread}) => {
|
this.cacheDialogs.some(({unread}) => {
|
||||||
if (unread) {
|
if (unread) {
|
||||||
num += unread;
|
num += unread;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,9 @@ export default {
|
|||||||
list() {
|
list() {
|
||||||
const {cacheTasks, taskCompleteTemps} = this;
|
const {cacheTasks, taskCompleteTemps} = this;
|
||||||
const filterTask = (task, chackCompleted = true) => {
|
const filterTask = (task, chackCompleted = true) => {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (task.complete_at && chackCompleted === true) {
|
if (task.complete_at && chackCompleted === true) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,11 @@
|
|||||||
@dragover.prevent="chatDragOver(true, $event)"
|
@dragover.prevent="chatDragOver(true, $event)"
|
||||||
@dragleave.prevent="chatDragOver(false, $event)">
|
@dragleave.prevent="chatDragOver(false, $event)">
|
||||||
<slot name="head">
|
<slot name="head">
|
||||||
<div class="dialog-title">
|
<div class="dialog-title" :class="{completed:$A.dialogCompleted(dialogData)}">
|
||||||
<div class="main-title">
|
<div class="main-title">
|
||||||
|
<template v-for="tag in $A.dialogTags(dialogData)" v-if="tag.color != 'success'">
|
||||||
|
<Tag :color="tag.color" :fade="false">{{$L(tag.text)}}</Tag>
|
||||||
|
</template>
|
||||||
<h2>{{dialogData.name}}</h2>
|
<h2>{{dialogData.name}}</h2>
|
||||||
<em v-if="peopleNum > 0">({{peopleNum}})</em>
|
<em v-if="peopleNum > 0">({{peopleNum}})</em>
|
||||||
</div>
|
</div>
|
||||||
@ -86,6 +89,20 @@
|
|||||||
<div v-if="dialogDrag" class="drag-over" @click="dialogDrag=false">
|
<div v-if="dialogDrag" class="drag-over" @click="dialogDrag=false">
|
||||||
<div class="drag-text">{{$L('拖动到这里发送')}}</div>
|
<div class="drag-text">{{$L('拖动到这里发送')}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
v-model="pasteShow"
|
||||||
|
:title="$L(pasteTitle)"
|
||||||
|
:cancel-text="$L('取消')"
|
||||||
|
:ok-text="$L('发送')"
|
||||||
|
@on-ok="pasteSend">
|
||||||
|
<div class="dialog-wrapper-paste">
|
||||||
|
<template v-for="item in pasteItem">
|
||||||
|
<img v-if="item.type == 'image'" :src="item.result"/>
|
||||||
|
<div v-else>{{$L('文件')}}: {{item.name}} ({{$A.bytesToSize(item.size)}})</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -122,6 +139,10 @@ export default {
|
|||||||
tempMsgs: [],
|
tempMsgs: [],
|
||||||
|
|
||||||
dialogMsgSubscribe: null,
|
dialogMsgSubscribe: null,
|
||||||
|
|
||||||
|
pasteShow: false,
|
||||||
|
pasteFile: [],
|
||||||
|
pasteItem: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -177,6 +198,18 @@ export default {
|
|||||||
|
|
||||||
peopleNum() {
|
peopleNum() {
|
||||||
return this.dialogData.type === 'group' ? $A.runNum(this.dialogData.people) : 0;
|
return this.dialogData.type === 'group' ? $A.runNum(this.dialogData.people) : 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
pasteTitle() {
|
||||||
|
const {pasteItem} = this;
|
||||||
|
let hasImage = pasteItem.find(({type}) => type == 'image')
|
||||||
|
let hasFile = pasteItem.find(({type}) => type != 'image')
|
||||||
|
if (hasImage && hasFile) {
|
||||||
|
return '发送文件/图片'
|
||||||
|
} else if (hasImage) {
|
||||||
|
return '发送图片'
|
||||||
|
}
|
||||||
|
return '发送文件'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -264,12 +297,31 @@ export default {
|
|||||||
const postFiles = Array.prototype.slice.call(files);
|
const postFiles = Array.prototype.slice.call(files);
|
||||||
if (postFiles.length > 0) {
|
if (postFiles.length > 0) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
postFiles.forEach((file) => {
|
this.pasteFile = [];
|
||||||
this.$refs.chatUpload.upload(file);
|
this.pasteItem = [];
|
||||||
|
postFiles.some(file => {
|
||||||
|
let reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = ({target}) => {
|
||||||
|
this.pasteFile.push(file)
|
||||||
|
this.pasteItem.push({
|
||||||
|
type: $A.getMiddle(file.type, null, '/'),
|
||||||
|
name: file.name,
|
||||||
|
size: file.size,
|
||||||
|
result: target.result
|
||||||
|
})
|
||||||
|
this.pasteShow = true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
pasteSend() {
|
||||||
|
this.pasteFile.some(file => {
|
||||||
|
this.$refs.chatUpload.upload(file)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
chatDragOver(show, e) {
|
chatDragOver(show, e) {
|
||||||
let random = (this.__dialogDrag = $A.randomString(8));
|
let random = (this.__dialogDrag = $A.randomString(8));
|
||||||
if (!show) {
|
if (!show) {
|
||||||
@ -329,7 +381,6 @@ export default {
|
|||||||
sendSuccess(data) {
|
sendSuccess(data) {
|
||||||
this.$store.dispatch("saveDialogMsg", data);
|
this.$store.dispatch("saveDialogMsg", data);
|
||||||
this.$store.dispatch("increaseTaskMsgNum", this.dialogId);
|
this.$store.dispatch("increaseTaskMsgNum", this.dialogId);
|
||||||
this.$store.dispatch("moveDialogTop", this.dialogId);
|
|
||||||
this.$store.dispatch("updateDialogLastMsg", data);
|
this.$store.dispatch("updateDialogLastMsg", data);
|
||||||
this.onActive();
|
this.onActive();
|
||||||
},
|
},
|
||||||
@ -414,7 +465,7 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -75,7 +75,7 @@ Vue.use(Minder)
|
|||||||
const MDEditor = () => import('../../../components/MDEditor/index');
|
const MDEditor = () => import('../../../components/MDEditor/index');
|
||||||
const TEditor = () => import('../../../components/TEditor');
|
const TEditor = () => import('../../../components/TEditor');
|
||||||
const LuckySheet = () => import('../../../components/LuckySheet');
|
const LuckySheet = () => import('../../../components/LuckySheet');
|
||||||
const Flow = () => import('../../../components/flow');
|
const Flow = () => import('../../../components/Flow');
|
||||||
const OnlyOffice = () => import('../../../components/OnlyOffice');
|
const OnlyOffice = () => import('../../../components/OnlyOffice');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -51,7 +51,7 @@ Vue.use(Minder)
|
|||||||
const MDPreview = () => import('../../../components/MDEditor/preview');
|
const MDPreview = () => import('../../../components/MDEditor/preview');
|
||||||
const TEditor = () => import('../../../components/TEditor');
|
const TEditor = () => import('../../../components/TEditor');
|
||||||
const LuckySheet = () => import('../../../components/LuckySheet');
|
const LuckySheet = () => import('../../../components/LuckySheet');
|
||||||
const Flow = () => import('../../../components/flow');
|
const Flow = () => import('../../../components/Flow');
|
||||||
const OnlyOffice = () => import('../../../components/OnlyOffice');
|
const OnlyOffice = () => import('../../../components/OnlyOffice');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -69,7 +69,8 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="projectData.desc" class="project-subtitle">{{projectData.desc}}</div>
|
<div class="project-subbox">
|
||||||
|
<div class="project-subtitle">{{projectData.desc}}</div>
|
||||||
<div class="project-switch">
|
<div class="project-switch">
|
||||||
<div v-if="completedCount > 0" class="project-checkbox">
|
<div v-if="completedCount > 0" class="project-checkbox">
|
||||||
<Checkbox :value="projectParameter('completedTask')" @on-change="toggleCompleted">{{$L('显示已完成')}}</Checkbox>
|
<Checkbox :value="projectParameter('completedTask')" @on-change="toggleCompleted">{{$L('显示已完成')}}</Checkbox>
|
||||||
@ -80,6 +81,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div v-if="projectParameter('card')" class="project-column">
|
<div v-if="projectParameter('card')" class="project-column">
|
||||||
<Draggable
|
<Draggable
|
||||||
:list="columnList"
|
:list="columnList"
|
||||||
@ -595,7 +597,10 @@ export default {
|
|||||||
return a.id - b.id;
|
return a.id - b.id;
|
||||||
});
|
});
|
||||||
list.forEach((column) => {
|
list.forEach((column) => {
|
||||||
column.tasks = this.transforTasks(cacheTasks.filter((task) => {
|
column.tasks = this.transforTasks(cacheTasks.filter(task => {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return task.column_id == column.id;
|
return task.column_id == column.id;
|
||||||
})).sort((a, b) => {
|
})).sort((a, b) => {
|
||||||
if (a.sort != b.sort) {
|
if (a.sort != b.sort) {
|
||||||
@ -655,7 +660,10 @@ export default {
|
|||||||
|
|
||||||
unList() {
|
unList() {
|
||||||
const {projectId, cacheTasks, searchText, sortField, sortType} = this;
|
const {projectId, cacheTasks, searchText, sortField, sortType} = this;
|
||||||
const array = cacheTasks.filter((task) => {
|
const array = cacheTasks.filter(task => {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (task.project_id != projectId || task.parent_id > 0) {
|
if (task.project_id != projectId || task.parent_id > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -683,7 +691,10 @@ export default {
|
|||||||
|
|
||||||
completedList() {
|
completedList() {
|
||||||
const {projectId, cacheTasks, searchText} = this;
|
const {projectId, cacheTasks, searchText} = this;
|
||||||
const array = cacheTasks.filter((task) => {
|
const array = cacheTasks.filter(task => {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (task.project_id != projectId || task.parent_id > 0) {
|
if (task.project_id != projectId || task.parent_id > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -703,7 +714,10 @@ export default {
|
|||||||
|
|
||||||
completedCount() {
|
completedCount() {
|
||||||
const {projectId, cacheTasks} = this;
|
const {projectId, cacheTasks} = this;
|
||||||
return cacheTasks.filter((task) => {
|
return cacheTasks.filter(task => {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (task.project_id != projectId || task.parent_id > 0) {
|
if (task.project_id != projectId || task.parent_id > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -766,7 +780,12 @@ export default {
|
|||||||
sort = -1;
|
sort = -1;
|
||||||
upTask.push(...item.task.map(id => {
|
upTask.push(...item.task.map(id => {
|
||||||
sort++;
|
sort++;
|
||||||
upTask.push(...this.cacheTasks.filter(({parent_id}) => parent_id == id).map(({id}) => {
|
upTask.push(...this.cacheTasks.filter(task => {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return task.parent_id == id
|
||||||
|
}).map(({id}) => {
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
sort,
|
sort,
|
||||||
@ -1161,6 +1180,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
myFilter(task, chackCompleted = true) {
|
myFilter(task, chackCompleted = true) {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (task.project_id != this.projectId) {
|
if (task.project_id != this.projectId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1178,6 +1200,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
helpFilter(task, chackCompleted = true) {
|
helpFilter(task, chackCompleted = true) {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (task.project_id != this.projectId || task.parent_id > 0) {
|
if (task.project_id != this.projectId || task.parent_id > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
</Timeline>
|
</Timeline>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="loadIng > 0" class="logs-loading"><Loading/></li>
|
<li v-if="loadIng > 0 && showLoad" class="logs-loading"><Loading/></li>
|
||||||
<li v-else-if="hasMorePages" class="logs-more" @click="getMore">{{$L('加载更多')}}</li>
|
<li v-else-if="hasMorePages" class="logs-more" @click="getMore">{{$L('加载更多')}}</li>
|
||||||
<li v-else-if="totalNum == 0" class="logs-none" @click="getLists(true)">{{$L('没有任何动态')}}</li>
|
<li v-else-if="totalNum == 0" class="logs-none" @click="getLists(true)">{{$L('没有任何动态')}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -52,6 +52,10 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
|
showLoad: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -74,7 +74,7 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['windowMax768'])
|
...mapState(['cacheTasks', 'windowMax768'])
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
projectId: {
|
projectId: {
|
||||||
@ -98,7 +98,13 @@ export default {
|
|||||||
key: 'name',
|
key: 'name',
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
render: (h, {row}) => {
|
render: (h, {row}) => {
|
||||||
return h('AutoTip', row.name);
|
return h('AutoTip', {
|
||||||
|
on: {
|
||||||
|
'on-click': () => {
|
||||||
|
this.$store.dispatch("openTask", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, row.name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -140,7 +146,27 @@ export default {
|
|||||||
align: 'center',
|
align: 'center',
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
const recoveryNode = h('Poptip', {
|
if (this.cacheTasks.find(task => task.id == params.row.id && !task.archived_at)) {
|
||||||
|
return h('div', {
|
||||||
|
style: {
|
||||||
|
color: '#888',
|
||||||
|
},
|
||||||
|
}, this.$L('已还原'));
|
||||||
|
}
|
||||||
|
const vNodes = [
|
||||||
|
h('span', {
|
||||||
|
style: {
|
||||||
|
fontSize: '13px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: '#8bcf70',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
'click': () => {
|
||||||
|
this.$store.dispatch("openTask", params.row);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, this.$L('查看')),
|
||||||
|
h('Poptip', {
|
||||||
props: {
|
props: {
|
||||||
title: this.$L('你确定要还原归档吗?'),
|
title: this.$L('你确定要还原归档吗?'),
|
||||||
confirm: true,
|
confirm: true,
|
||||||
@ -148,6 +174,7 @@ export default {
|
|||||||
placement: 'left',
|
placement: 'left',
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
|
marginLeft: '6px',
|
||||||
fontSize: '13px',
|
fontSize: '13px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
color: '#8bcf70',
|
color: '#8bcf70',
|
||||||
@ -157,8 +184,8 @@ export default {
|
|||||||
this.recovery(params.row);
|
this.recovery(params.row);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, this.$L('还原'));
|
}, this.$L('还原')),
|
||||||
const deleteNode = h('Poptip', {
|
h('Poptip', {
|
||||||
props: {
|
props: {
|
||||||
title: this.$L('你确定要删除任务吗?'),
|
title: this.$L('你确定要删除任务吗?'),
|
||||||
confirm: true,
|
confirm: true,
|
||||||
@ -176,15 +203,13 @@ export default {
|
|||||||
this.delete(params.row);
|
this.delete(params.row);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, this.$L('删除'));
|
}, this.$L('删除'))
|
||||||
|
];
|
||||||
return h('TableAction', {
|
return h('TableAction', {
|
||||||
props: {
|
props: {
|
||||||
column: params.column
|
column: params.column
|
||||||
}
|
}
|
||||||
}, [
|
}, vNodes);
|
||||||
recoveryNode,
|
|
||||||
deleteNode,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -239,12 +264,9 @@ export default {
|
|||||||
recovery(row) {
|
recovery(row) {
|
||||||
this.list = this.list.filter(({id}) => id != row.id);
|
this.list = this.list.filter(({id}) => id != row.id);
|
||||||
this.loadIng++;
|
this.loadIng++;
|
||||||
this.$store.dispatch("call", {
|
this.$store.dispatch("archivedTask", {
|
||||||
url: 'project/task/archived',
|
|
||||||
data: {
|
|
||||||
task_id: row.id,
|
task_id: row.id,
|
||||||
type: 'recovery'
|
type: 'recovery'
|
||||||
},
|
|
||||||
}).then(({msg}) => {
|
}).then(({msg}) => {
|
||||||
$A.messageSuccess(msg);
|
$A.messageSuccess(msg);
|
||||||
this.loadIng--;
|
this.loadIng--;
|
||||||
|
@ -79,6 +79,9 @@
|
|||||||
<div v-if="taskDetail.flow_item_name" class="flow">
|
<div v-if="taskDetail.flow_item_name" class="flow">
|
||||||
<span :class="taskDetail.flow_item_status" @click.stop="openMenu(taskDetail)">{{taskDetail.flow_item_name}}</span>
|
<span :class="taskDetail.flow_item_status" @click.stop="openMenu(taskDetail)">{{taskDetail.flow_item_name}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="taskDetail.archived_at" class="flow">
|
||||||
|
<span class="archived" @click.stop="openMenu(taskDetail)">{{$L('已归档')}}</span>
|
||||||
|
</div>
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<p v-if="projectName"><span>{{projectName}}</span></p>
|
<p v-if="projectName"><span>{{projectName}}</span></p>
|
||||||
<p v-if="columnName"><span>{{columnName}}</span></p>
|
<p v-if="columnName"><span>{{columnName}}</span></p>
|
||||||
@ -254,8 +257,10 @@
|
|||||||
transfer>
|
transfer>
|
||||||
<div class="picker-time">
|
<div class="picker-time">
|
||||||
<div @click="openTime" class="time">{{taskDetail.end_at ? cutTime : '--'}}</div>
|
<div @click="openTime" class="time">{{taskDetail.end_at ? cutTime : '--'}}</div>
|
||||||
<Tag v-if="!taskDetail.complete_at && taskDetail.today" color="blue"><i class="taskfont"></i>{{expiresFormat(taskDetail.end_at)}}</Tag>
|
<template v-if="!taskDetail.complete_at">
|
||||||
<Tag v-if="!taskDetail.complete_at && taskDetail.overdue" color="red">{{$L('超期未完成')}}</Tag>
|
<Tag v-if="within24Hours(taskDetail.end_at)" color="blue"><i class="taskfont"></i>{{expiresFormat(taskDetail.end_at)}}</Tag>
|
||||||
|
<Tag v-if="taskDetail.overdue" color="red">{{$L('超期未完成')}}</Tag>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</DatePicker>
|
</DatePicker>
|
||||||
</li>
|
</li>
|
||||||
@ -368,7 +373,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ProjectLog v-if="navActive=='log' && taskId > 0" ref="log" :task-id="taskDetail.id" @on-load-change="logLoadChange"/>
|
<ProjectLog v-if="navActive=='log' && taskId > 0" ref="log" :task-id="taskDetail.id" :show-load="false" @on-load-change="logLoadChange"/>
|
||||||
<div v-else class="no-dialog">
|
<div v-else class="no-dialog">
|
||||||
<div class="no-tip">{{$L('暂无消息')}}</div>
|
<div class="no-tip">{{$L('暂无消息')}}</div>
|
||||||
<div class="no-input">
|
<div class="no-input">
|
||||||
@ -565,8 +570,11 @@ export default {
|
|||||||
if (!this.taskId) {
|
if (!this.taskId) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return this.cacheTasks.filter(({parent_id}) => {
|
return this.cacheTasks.filter(task => {
|
||||||
return parent_id == this.taskId
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return task.parent_id == this.taskId
|
||||||
}).sort((a, b) => {
|
}).sort((a, b) => {
|
||||||
return a.id - b.id;
|
return a.id - b.id;
|
||||||
});
|
});
|
||||||
@ -708,6 +716,10 @@ export default {
|
|||||||
this.innerHeight = Math.min(1100, window.innerHeight);
|
this.innerHeight = Math.min(1100, window.innerHeight);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
within24Hours(date) {
|
||||||
|
return Math.round($A.Date(date).getTime() / 1000) - this.nowTime < 86400
|
||||||
|
},
|
||||||
|
|
||||||
expiresFormat(date) {
|
expiresFormat(date) {
|
||||||
return $A.countDownFormat(date, this.nowTime)
|
return $A.countDownFormat(date, this.nowTime)
|
||||||
},
|
},
|
||||||
@ -762,31 +774,6 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
archivedOrRemoveTask(type) {
|
|
||||||
let typeDispatch = type == 'remove' ? 'removeTask' : 'archivedTask';
|
|
||||||
let typeName = type == 'remove' ? '删除' : '归档';
|
|
||||||
let typeTask = this.taskDetail.parent_id > 0 ? '子任务' : '任务';
|
|
||||||
$A.modalConfirm({
|
|
||||||
title: typeName + typeTask,
|
|
||||||
content: '你确定要' + typeName + typeTask + '【' + this.taskDetail.name + '】吗?',
|
|
||||||
loading: true,
|
|
||||||
onOk: () => {
|
|
||||||
if (this.taskDetail.loading === true) {
|
|
||||||
this.$Modal.remove();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$set(this.taskDetail, 'loading', true);
|
|
||||||
this.$store.dispatch(typeDispatch, this.taskDetail.id).then(({msg}) => {
|
|
||||||
$A.messageSuccess(msg);
|
|
||||||
this.$Modal.remove();
|
|
||||||
}).catch(({msg}) => {
|
|
||||||
$A.modalError(msg, 301);
|
|
||||||
this.$Modal.remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
openOwner() {
|
openOwner() {
|
||||||
const list = this.getOwner.map(({userid}) => userid)
|
const list = this.getOwner.map(({userid}) => userid)
|
||||||
this.$set(this.taskDetail, 'owner_userid', list)
|
this.$set(this.taskDetail, 'owner_userid', list)
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
<template v-if="task.parent_id === 0">
|
<template v-if="task.parent_id === 0">
|
||||||
<EDropdownItem :divided="turns.length > 0" command="archived">
|
<EDropdownItem :divided="turns.length > 0" command="archived">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<Icon type="ios-filing" />{{$L('归档')}}
|
<Icon type="ios-filing" />{{$L(task.archived_at ? '还原归档' : '归档')}}
|
||||||
</div>
|
</div>
|
||||||
</EDropdownItem>
|
</EDropdownItem>
|
||||||
<EDropdownItem command="remove">
|
<EDropdownItem command="remove">
|
||||||
@ -246,9 +246,21 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
archivedOrRemoveTask(type) {
|
archivedOrRemoveTask(type) {
|
||||||
let typeDispatch = type == 'remove' ? 'removeTask' : 'archivedTask';
|
let typeDispatch = 'removeTask';
|
||||||
let typeName = type == 'remove' ? '删除' : '归档';
|
let typeName = '删除';
|
||||||
|
let typeData = this.task.id;
|
||||||
let typeTask = this.task.parent_id > 0 ? '子任务' : '任务';
|
let typeTask = this.task.parent_id > 0 ? '子任务' : '任务';
|
||||||
|
if (type == 'archived') {
|
||||||
|
typeDispatch = 'archivedTask'
|
||||||
|
typeName = '归档'
|
||||||
|
if (this.task.archived_at) {
|
||||||
|
typeName = '还原归档'
|
||||||
|
typeData = {
|
||||||
|
task_id: this.task.id,
|
||||||
|
type: 'recovery'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$A.modalConfirm({
|
$A.modalConfirm({
|
||||||
title: typeName + typeTask,
|
title: typeName + typeTask,
|
||||||
content: '你确定要' + typeName + typeTask + '【' + this.task.name + '】吗?',
|
content: '你确定要' + typeName + typeTask + '【' + this.task.name + '】吗?',
|
||||||
@ -258,7 +270,7 @@ export default {
|
|||||||
this.$Modal.remove();
|
this.$Modal.remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$store.dispatch(typeDispatch, this.task.id).then(({msg}) => {
|
this.$store.dispatch(typeDispatch, typeData).then(({msg}) => {
|
||||||
$A.messageSuccess(msg);
|
$A.messageSuccess(msg);
|
||||||
this.$Modal.remove();
|
this.$Modal.remove();
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
|
@ -163,8 +163,11 @@ export default {
|
|||||||
|
|
||||||
subTask() {
|
subTask() {
|
||||||
return function(task_id) {
|
return function(task_id) {
|
||||||
return this.cacheTasks.filter(({parent_id}) => {
|
return this.cacheTasks.filter(task => {
|
||||||
return parent_id == task_id
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return task.parent_id == task_id
|
||||||
}).sort((a, b) => {
|
}).sort((a, b) => {
|
||||||
return a.id - b.id;
|
return a.id - b.id;
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
v-for="(item, key) in dialogType"
|
v-for="(item, key) in dialogType"
|
||||||
:key="key"
|
:key="key"
|
||||||
:class="{active:dialogActive==item.type}"
|
:class="{active:dialogActive==item.type}"
|
||||||
@click="dialogActive=item.type">
|
@click="onActive(item.type)">
|
||||||
<Badge class="nav-num" :count="msgUnread(item.type)"/>
|
<Badge class="nav-num" :count="msgUnread(item.type)"/>
|
||||||
{{$L(item.name)}}
|
{{$L(item.name)}}
|
||||||
</p>
|
</p>
|
||||||
@ -27,18 +27,22 @@
|
|||||||
<ul v-if="tabActive==='dialog'" class="dialog">
|
<ul v-if="tabActive==='dialog'" class="dialog">
|
||||||
<li
|
<li
|
||||||
v-for="(dialog, key) in dialogList"
|
v-for="(dialog, key) in dialogList"
|
||||||
|
:ref="`dialog_${dialog.id}`"
|
||||||
:key="key"
|
:key="key"
|
||||||
:class="{active: dialog.id == dialogId}"
|
:class="{active: dialog.id == dialogId}"
|
||||||
@click="openDialog(dialog, true)">
|
@click="openDialog(dialog, true)">
|
||||||
<template v-if="dialog.type=='group'">
|
<template v-if="dialog.type=='group'">
|
||||||
<i v-if="dialog.group_type=='project'" class="taskfont icon-avatar project"></i>
|
<i v-if="dialog.group_type=='project'" class="taskfont icon-avatar project"></i>
|
||||||
<i v-else-if="dialog.group_type=='task'" class="taskfont icon-avatar task"></i>
|
<i v-else-if="dialog.group_type=='task'" class="taskfont icon-avatar task" :class="{completed:$A.dialogCompleted(dialog)}"></i>
|
||||||
<Icon v-else class="icon-avatar" type="ios-people" />
|
<Icon v-else class="icon-avatar" type="ios-people" />
|
||||||
</template>
|
</template>
|
||||||
<div v-else-if="dialog.dialog_user" class="user-avatar"><UserAvatar :userid="dialog.dialog_user.userid" :size="42"/></div>
|
<div v-else-if="dialog.dialog_user" class="user-avatar"><UserAvatar :userid="dialog.dialog_user.userid" :size="42"/></div>
|
||||||
<Icon v-else class="icon-avatar" type="md-person" />
|
<Icon v-else class="icon-avatar" type="md-person" />
|
||||||
<div class="dialog-box">
|
<div class="dialog-box">
|
||||||
<div class="dialog-title">
|
<div class="dialog-title">
|
||||||
|
<template v-for="tag in $A.dialogTags(dialog)" v-if="tag.color != 'success'">
|
||||||
|
<Tag :color="tag.color" :fade="false">{{$L(tag.text)}}</Tag>
|
||||||
|
</template>
|
||||||
<span>{{dialog.name}}</span>
|
<span>{{dialog.name}}</span>
|
||||||
<Icon v-if="dialog.type == 'user' && lastMsgReadDone(dialog.last_msg)" :type="lastMsgReadDone(dialog.last_msg)"/>
|
<Icon v-if="dialog.type == 'user' && lastMsgReadDone(dialog.last_msg)" :type="lastMsgReadDone(dialog.last_msg)"/>
|
||||||
<em v-if="dialog.last_at">{{$A.formatTime(dialog.last_at)}}</em>
|
<em v-if="dialog.last_at">{{$A.formatTime(dialog.last_at)}}</em>
|
||||||
@ -123,22 +127,24 @@ export default {
|
|||||||
dialogList() {
|
dialogList() {
|
||||||
const {dialogActive, dialogKey} = this;
|
const {dialogActive, dialogKey} = this;
|
||||||
if (dialogActive == '' && dialogKey == '') {
|
if (dialogActive == '' && dialogKey == '') {
|
||||||
return this.cacheDialogs.filter(({name}) => name !== undefined);
|
return this.cacheDialogs.filter(dialog => this.filterDialog(dialog)).sort((a, b) => {
|
||||||
|
return $A.Date(b.last_at) - $A.Date(a.last_at);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return this.cacheDialogs.filter(({name, type, group_type, last_msg}) => {
|
return this.cacheDialogs.filter(dialog => {
|
||||||
if (name === undefined) {
|
if (!this.filterDialog(dialog)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dialogActive) {
|
if (dialogActive) {
|
||||||
switch (dialogActive) {
|
switch (dialogActive) {
|
||||||
case 'project':
|
case 'project':
|
||||||
case 'task':
|
case 'task':
|
||||||
if (group_type != dialogActive) {
|
if (dialog.group_type != dialogActive) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'user':
|
case 'user':
|
||||||
if (type != 'user') {
|
if (dialog.type != 'user') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -147,20 +153,22 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dialogKey) {
|
if (dialogKey) {
|
||||||
let existName = $A.strExists(name, dialogKey);
|
let existName = $A.strExists(dialog.name, dialogKey);
|
||||||
let existMsg = last_msg && last_msg.type === 'text' && $A.strExists(last_msg.msg.text, dialogKey);
|
let existMsg = dialog.last_msg && dialog.last_msg.type === 'text' && $A.strExists(dialog.last_msg.msg.text, dialogKey);
|
||||||
if (!existName && !existMsg) {
|
if (!existName && !existMsg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
}).sort((a, b) => {
|
||||||
|
return $A.Date(b.last_at) - $A.Date(a.last_at);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
msgUnread() {
|
msgUnread() {
|
||||||
return function (type) {
|
return function (type) {
|
||||||
let num = 0;
|
let num = 0;
|
||||||
this.cacheDialogs.map((dialog) => {
|
this.cacheDialogs.some((dialog) => {
|
||||||
if (dialog.unread) {
|
if (dialog.unread) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'project':
|
case 'project':
|
||||||
@ -219,6 +227,24 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onActive(type) {
|
||||||
|
if (this.dialogActive == type) {
|
||||||
|
// 再次点击滚动到未读条目
|
||||||
|
const dialog = this.dialogList.find(({unread}) => unread > 0)
|
||||||
|
if (dialog) {
|
||||||
|
try {
|
||||||
|
this.$refs[`dialog_${dialog.id}`][0].scrollIntoView();
|
||||||
|
} catch (e) {
|
||||||
|
scrollIntoView(this.$refs[`dialog_${dialog.id}`][0], {
|
||||||
|
behavior: 'instant',
|
||||||
|
inline: 'end',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dialogActive = type
|
||||||
|
},
|
||||||
|
|
||||||
closeDialog() {
|
closeDialog() {
|
||||||
this.dialogId = 0;
|
this.dialogId = 0;
|
||||||
$A.setStorage("messenger::dialogId", 0)
|
$A.setStorage("messenger::dialogId", 0)
|
||||||
@ -245,6 +271,44 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
filterDialog(dialog) {
|
||||||
|
if (dialog.unread > 0 || dialog.id == this.dialogId) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (dialog.name === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!dialog.last_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dialog.type == 'group') {
|
||||||
|
if (['project', 'task'].includes(dialog.group_type) && $A.isJson(dialog.group_info)) {
|
||||||
|
if (dialog.group_type == 'task' && dialog.group_info.complete_at) {
|
||||||
|
// 已完成5天后隐藏对话
|
||||||
|
let time = Math.max($A.Date(dialog.last_at, true), $A.Date(dialog.group_info.complete_at, true))
|
||||||
|
if (5 * 86400 + time < $A.Time()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dialog.group_info.deleted_at) {
|
||||||
|
// 已删除2天后隐藏对话
|
||||||
|
let time = Math.max($A.Date(dialog.last_at, true), $A.Date(dialog.group_info.deleted_at, true))
|
||||||
|
if (2 * 86400 + time < $A.Time()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dialog.group_info.archived_at) {
|
||||||
|
// 已归档3天后隐藏对话
|
||||||
|
let time = Math.max($A.Date(dialog.last_at, true), $A.Date(dialog.group_info.archived_at, true))
|
||||||
|
if (3 * 86400 + time < $A.Time()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
getContactsList(page) {
|
getContactsList(page) {
|
||||||
if (this.contactsData === null) {
|
if (this.contactsData === null) {
|
||||||
this.contactsData = {};
|
this.contactsData = {};
|
||||||
|
@ -65,7 +65,10 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.loadIng++;
|
this.loadIng++;
|
||||||
this.$store.dispatch("getTaskOne", task_id).then(({data}) => {
|
this.$store.dispatch("getTaskOne", {
|
||||||
|
task_id,
|
||||||
|
archived: 'all'
|
||||||
|
}).then(({data}) => {
|
||||||
this.loadIng--;
|
this.loadIng--;
|
||||||
this.taskInfo = data;
|
this.taskInfo = data;
|
||||||
this.$store.dispatch("getTaskContent", task_id);
|
this.$store.dispatch("getTaskContent", task_id);
|
||||||
|
92
resources/assets/js/store/actions.js
vendored
92
resources/assets/js/store/actions.js
vendored
@ -538,6 +538,19 @@ export default {
|
|||||||
}
|
}
|
||||||
state.cacheProjects.push(data);
|
state.cacheProjects.push(data);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
state.cacheDialogs.some(dialog => {
|
||||||
|
if (dialog.type == 'group' && dialog.group_type == 'project' && dialog.group_info.id == data.id) {
|
||||||
|
if (data.name !== undefined) {
|
||||||
|
dialog.name = data.name
|
||||||
|
}
|
||||||
|
for (let key in dialog.group_info) {
|
||||||
|
if (!dialog.group_info.hasOwnProperty(key) || data[key] === undefined) continue;
|
||||||
|
dialog.group_info[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$A.setStorage("cacheProjects", state.cacheProjects);
|
$A.setStorage("cacheProjects", state.cacheProjects);
|
||||||
})
|
})
|
||||||
@ -896,6 +909,18 @@ export default {
|
|||||||
dispatch("getTaskForParent", data.id).catch(() => {})
|
dispatch("getTaskForParent", data.id).catch(() => {})
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
state.cacheDialogs.some(dialog => {
|
||||||
|
if (dialog.type == 'group' && dialog.group_type == 'task' && dialog.group_info.id == data.id) {
|
||||||
|
if (data.name !== undefined) {
|
||||||
|
dialog.name = data.name
|
||||||
|
}
|
||||||
|
for (let key in dialog.group_info) {
|
||||||
|
if (!dialog.group_info.hasOwnProperty(key) || data[key] === undefined) continue;
|
||||||
|
dialog.group_info[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$A.setStorage("cacheTasks", state.cacheTasks);
|
$A.setStorage("cacheTasks", state.cacheTasks);
|
||||||
})
|
})
|
||||||
@ -1010,20 +1035,21 @@ export default {
|
|||||||
* 获取单个任务
|
* 获取单个任务
|
||||||
* @param state
|
* @param state
|
||||||
* @param dispatch
|
* @param dispatch
|
||||||
* @param task_id
|
* @param data Number|JSONObject{task_id, ?archived_at}
|
||||||
* @returns {Promise<unknown>}
|
* @returns {Promise<unknown>}
|
||||||
*/
|
*/
|
||||||
getTaskOne({state, dispatch}, task_id) {
|
getTaskOne({state, dispatch}, data) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
if ($A.runNum(task_id) === 0) {
|
if (/^\d+$/.test(data)) {
|
||||||
|
data = {task_id: data}
|
||||||
|
}
|
||||||
|
if ($A.runNum(data.task_id) === 0) {
|
||||||
reject({msg: 'Parameter error'});
|
reject({msg: 'Parameter error'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch("call", {
|
dispatch("call", {
|
||||||
url: 'project/task/one',
|
url: 'project/task/one',
|
||||||
data: {
|
data,
|
||||||
task_id,
|
|
||||||
},
|
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
dispatch("saveTask", result.data);
|
dispatch("saveTask", result.data);
|
||||||
resolve(result)
|
resolve(result)
|
||||||
@ -1125,7 +1151,10 @@ export default {
|
|||||||
const newIds = state.cacheTasks.filter(task => task.parent_id == parent_id && task._time >= time).map(({id}) => id)
|
const newIds = state.cacheTasks.filter(task => task.parent_id == parent_id && task._time >= time).map(({id}) => id)
|
||||||
dispatch("forgetTask", currentIds.filter(v => newIds.indexOf(v) == -1))
|
dispatch("forgetTask", currentIds.filter(v => newIds.indexOf(v) == -1))
|
||||||
}
|
}
|
||||||
dispatch("getTasks", {parent_id}).then(() => {
|
dispatch("getTasks", {
|
||||||
|
parent_id,
|
||||||
|
archived: 'all'
|
||||||
|
}).then(() => {
|
||||||
call()
|
call()
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@ -1168,32 +1197,33 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 归档任务
|
* 归档(还原)任务
|
||||||
* @param state
|
* @param state
|
||||||
* @param dispatch
|
* @param dispatch
|
||||||
* @param task_id
|
* @param data Number|JSONObject{task_id, ?archived_at}
|
||||||
* @returns {Promise<unknown>}
|
* @returns {Promise<unknown>}
|
||||||
*/
|
*/
|
||||||
archivedTask({state, dispatch}, task_id) {
|
archivedTask({state, dispatch}, data) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
if ($A.runNum(task_id) === 0) {
|
if (/^\d+$/.test(data)) {
|
||||||
|
data = {task_id: data}
|
||||||
|
}
|
||||||
|
if ($A.runNum(data.task_id) === 0) {
|
||||||
reject({msg: 'Parameter error'});
|
reject({msg: 'Parameter error'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch("taskLoadStart", task_id)
|
dispatch("taskLoadStart", data.task_id)
|
||||||
dispatch("call", {
|
dispatch("call", {
|
||||||
url: 'project/task/archived',
|
url: 'project/task/archived',
|
||||||
data: {
|
data,
|
||||||
task_id: task_id,
|
|
||||||
},
|
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
dispatch("forgetTask", task_id)
|
dispatch("saveTask", result.data)
|
||||||
dispatch("taskLoadEnd", task_id)
|
dispatch("taskLoadEnd", data.task_id)
|
||||||
resolve(result)
|
resolve(result)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
dispatch("getTaskOne", task_id).catch(() => {})
|
dispatch("getTaskOne", data.task_id).catch(() => {})
|
||||||
dispatch("taskLoadEnd", task_id)
|
dispatch("taskLoadEnd", data.task_id)
|
||||||
reject(e)
|
reject(e)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1292,7 +1322,10 @@ export default {
|
|||||||
}
|
}
|
||||||
state.taskId = task_id;
|
state.taskId = task_id;
|
||||||
if (task_id > 0) {
|
if (task_id > 0) {
|
||||||
dispatch("getTaskOne", task_id).then(() => {
|
dispatch("getTaskOne", {
|
||||||
|
task_id,
|
||||||
|
archived: 'all'
|
||||||
|
}).then(() => {
|
||||||
dispatch("getTaskContent", task_id);
|
dispatch("getTaskContent", task_id);
|
||||||
dispatch("getTaskFiles", task_id);
|
dispatch("getTaskFiles", task_id);
|
||||||
dispatch("getTaskForParent", task_id).catch(() => {})
|
dispatch("getTaskForParent", task_id).catch(() => {})
|
||||||
@ -1749,22 +1782,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 将会话移动到首位
|
|
||||||
* @param state
|
|
||||||
* @param dialog_id
|
|
||||||
*/
|
|
||||||
moveDialogTop({state}, dialog_id) {
|
|
||||||
$A.execMainDispatch("moveDialogTop", dialog_id)
|
|
||||||
//
|
|
||||||
const index = state.cacheDialogs.findIndex(({id}) => id == dialog_id);
|
|
||||||
if (index > -1) {
|
|
||||||
const tmp = $A.cloneJSON(state.cacheDialogs[index]);
|
|
||||||
state.cacheDialogs.splice(index, 1);
|
|
||||||
state.cacheDialogs.unshift(tmp);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忘记对话数据
|
* 忘记对话数据
|
||||||
* @param state
|
* @param state
|
||||||
@ -2026,8 +2043,6 @@ export default {
|
|||||||
if (dialog) {
|
if (dialog) {
|
||||||
// 新增未读数
|
// 新增未读数
|
||||||
dialog.unread++;
|
dialog.unread++;
|
||||||
// 移动到首位
|
|
||||||
dispatch("moveDialogTop", dialog_id);
|
|
||||||
}
|
}
|
||||||
Store.set('dialogMsgPush', data);
|
Store.set('dialogMsgPush', data);
|
||||||
}
|
}
|
||||||
@ -2105,7 +2120,6 @@ export default {
|
|||||||
case 'filedelete':
|
case 'filedelete':
|
||||||
dispatch("forgetTaskFile", data.id)
|
dispatch("forgetTaskFile", data.id)
|
||||||
break;
|
break;
|
||||||
case 'archived':
|
|
||||||
case 'delete':
|
case 'delete':
|
||||||
dispatch("forgetTask", data.id)
|
dispatch("forgetTask", data.id)
|
||||||
break;
|
break;
|
||||||
|
3
resources/assets/js/store/getters.js
vendored
3
resources/assets/js/store/getters.js
vendored
@ -119,6 +119,9 @@ export default {
|
|||||||
todayEnd = $A.Date($A.formatDate("Y-m-d 23:59:59")),
|
todayEnd = $A.Date($A.formatDate("Y-m-d 23:59:59")),
|
||||||
todayNow = $A.Date($A.formatDate("Y-m-d H:i:s"));
|
todayNow = $A.Date($A.formatDate("Y-m-d H:i:s"));
|
||||||
const filterTask = (task, chackCompleted = true) => {
|
const filterTask = (task, chackCompleted = true) => {
|
||||||
|
if (task.archived_at) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (task.complete_at && chackCompleted === true) {
|
if (task.complete_at && chackCompleted === true) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
height: 68px;
|
height: 68px;
|
||||||
position: relative;
|
position: relative;
|
||||||
&:after {
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -24,11 +24,41 @@
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: #f4f5f5;
|
background-color: #f4f5f5;
|
||||||
}
|
}
|
||||||
|
&.completed {
|
||||||
|
&:after {
|
||||||
|
content: "\f373";
|
||||||
|
font-family: Ionicons, serif;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 24px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 52px;
|
||||||
|
color: #19be6b;
|
||||||
|
opacity: .2;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
.main-title {
|
.main-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
.ivu-tag {
|
||||||
|
margin: 0 6px 0 0;
|
||||||
|
padding: 0 5px;
|
||||||
|
&.ivu-tag-success {
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ivu-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-right: 6px;
|
||||||
|
|
||||||
|
&.completed {
|
||||||
|
color: $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
> h2 {
|
> h2 {
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@ -411,6 +441,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-wrapper-paste {
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 1000px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.dialog-wrapper {
|
.dialog-wrapper {
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
|
@ -112,23 +112,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.project-subtitle {
|
.project-subbox {
|
||||||
width: 100%;
|
|
||||||
color: #999999;
|
|
||||||
line-height: 24px;
|
|
||||||
margin-top: -6px;
|
|
||||||
margin-bottom: -18px;
|
|
||||||
padding-right: 260px;
|
|
||||||
}
|
|
||||||
.project-switch {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: space-between;
|
||||||
|
.project-subtitle {
|
||||||
|
flex: 1;
|
||||||
|
color: #999999;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
.project-switch {
|
||||||
|
margin-left: 80px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
.project-checkbox {
|
.project-checkbox {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-right: 14px;
|
margin-right: 14px;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
|
height: 30px;
|
||||||
.ivu-checkbox-focus {
|
.ivu-checkbox-focus {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
@ -138,6 +141,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
height: 30px;
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: box-shadow 0.2s;
|
transition: box-shadow 0.2s;
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -188,6 +192,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.project-column {
|
.project-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -934,10 +939,16 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.project-subbox {
|
||||||
|
display: block;
|
||||||
.project-subtitle {
|
.project-subtitle {
|
||||||
padding-right: 12px;
|
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
.project-switch {
|
||||||
|
margin-left: 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.project-column {
|
.project-column {
|
||||||
> ul {
|
> ul {
|
||||||
|
@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
.log-text {
|
.log-text {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: rgba(0, 0, 0, .8);
|
color: rgba(0, 0, 0, .72);
|
||||||
|
|
||||||
.detail-user {
|
.detail-user {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
background-color: #f4f5f5;
|
background-color: #f4f5f5;
|
||||||
}
|
}
|
||||||
.icon {
|
.icon {
|
||||||
|
margin-right: 18px;
|
||||||
.task-menu-icon {
|
.task-menu-icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -47,8 +48,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.flow {
|
.flow {
|
||||||
margin-left: 18px;
|
margin-right: 10px;
|
||||||
margin-right: -3px;
|
|
||||||
> span {
|
> span {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
@ -60,7 +60,8 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&.start {
|
&.start,
|
||||||
|
&.archived {
|
||||||
background-color: rgba(38, 38, 38, 0.05);
|
background-color: rgba(38, 38, 38, 0.05);
|
||||||
border-color: rgba(38, 38, 38, 0.05);
|
border-color: rgba(38, 38, 38, 0.05);
|
||||||
color: #595959;
|
color: #595959;
|
||||||
@ -81,7 +82,6 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-left: 18px;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
26
resources/assets/sass/pages/page-messenger.scss
vendored
26
resources/assets/sass/pages/page-messenger.scss
vendored
@ -111,6 +111,20 @@
|
|||||||
background-color: #9B96DF;
|
background-color: #9B96DF;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
&.completed {
|
||||||
|
&:after {
|
||||||
|
content: "\f373";
|
||||||
|
font-family: Ionicons, serif;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 12px;
|
||||||
|
font-size: 32px;
|
||||||
|
color: #19be6b;
|
||||||
|
opacity: .2;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.dialog-box {
|
.dialog-box {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -124,6 +138,13 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
|
.ivu-tag {
|
||||||
|
margin: 0 4px 0 0;
|
||||||
|
padding: 0 5px;
|
||||||
|
&.ivu-tag-success {
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
> span {
|
> span {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
@ -138,6 +159,11 @@
|
|||||||
transform: scale(0.9);
|
transform: scale(0.9);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
|
&.completed {
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 0 4px 0 0;
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
> em {
|
> em {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user