快速添加任务

This commit is contained in:
kuaifan 2021-06-07 15:00:01 +08:00
parent ab5a7544f2
commit b0a5a73153
12 changed files with 1323 additions and 909 deletions

View File

@ -374,7 +374,7 @@ class ProjectController extends AbstractController
}
/**
* 【消息】消息列表
* 消息列表
*
* @apiParam {Number} project_id 项目ID
* @apiParam {Number} [task_id] 任务ID
@ -413,7 +413,7 @@ class ProjectController extends AbstractController
}
/**
* 【消息】发送消息
* 发送消息
*
* @apiParam {Number} project_id 项目ID
* @apiParam {Number} [task_id] 任务ID
@ -455,7 +455,54 @@ class ProjectController extends AbstractController
}
/**
* {post}【任务】添加任务
* 添加、修改 任务列表
*
* @apiParam {Number} project_id 项目ID
* @apiParam {String} name 列表名称
*/
public function column__add()
{
$user = User::authE();
if (Base::isError($user)) {
return $user;
} else {
$user = User::IDE($user['data']);
}
//
$project_id = intval(Request::input('project_id'));
$column_id = intval(Request::input('column_id'));
$name = trim(Request::input('name'));
if (empty($name)) {
return Base::retError('列表名称不能为空');
}
// 项目
$project = Project::select($this->projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', $project_id)
->where('project_users.userid', $user->userid)
->first();
if (empty($project)) {
return Base::retError('项目不存在或不在成员列表内');
}
//
if ($column_id > 0) {
$column = ProjectColumn::find($column_id);
} else {
$column = ProjectColumn::createInstance([
'project_id' => $project->id,
]);
}
if ($column) {
$column->name = $name;
$column->save();
return Base::retSuccess('添加成功', $column);
} else {
return Base::retError('列表不存在');
}
}
/**
* {post}添加任务
*
* @apiParam {Number} project_id 项目ID
* @apiParam {Number} [column_id] 列表ID留空取第一个

View File

@ -178,6 +178,50 @@
return config;
},
modalInput(config, millisecond = 0) {
if (millisecond > 0) {
setTimeout(() => { $A.modalInput(config) }, millisecond);
return;
}
if (typeof config === "string") config = {title:config};
$A.Modal.confirm({
render: (h) => {
return h('div', [
h('div', {
style: {
fontSize: '16px',
fontWeight: '500',
marginBottom: '20px',
}
}, $A.L(config.title)),
h('Input', {
props: {
value: config.value,
placeholder: $A.L(config.placeholder)
},
on: {
input: (val) => {
config.value = val;
}
}
})
])
},
loading: true,
onOk: () => {
if (typeof config.onOk === "function") {
if (config.onOk(config.value, () => {
$A.Modal.remove();
}) === true) {
$A.Modal.remove();
}
} else {
$A.Modal.remove();
}
},
});
},
modalConfirm(config, millisecond = 0) {
if (millisecond > 0) {
setTimeout(() => { $A.modalConfirm(config) }, millisecond);

View File

@ -56,10 +56,25 @@
<ul>
<li v-for="column in projectDetail.project_column">
<div class="column-head">
<div class="column-head-title">{{column.name}}</div>
<div :class="['column-head-num', column.project_task.length > 0 ? 'have' : '']">{{column.project_task.length}}</div>
<div class="column-head-title">
<span><AutoTip>{{column.name}}</AutoTip></span>
<em>({{column.project_task.length}})</em>
</div>
<ul class="overlay-y">
<div class="column-head-icon">
<Icon type="ios-more" />
<Icon type="md-add" @click="addBefore(column)" />
</div>
</div>
<ul class="overlay-y" :ref="'column_' + column.id">
<li v-if="column.addBefore===true" class="task-add">
<TaskAddSimple
:column-id="column.id"
:project-id="projectDetail.id"
:add-before="true"
@on-close="column.addBefore=false"
@on-priority="addOpen"
auto-active/>
</li>
<li v-for="item in panelTask(column.project_task)">
<div :class="['task-head', item.desc ? 'has-desc' : '']">
<div class="task-title"><pre>{{item.name}}</pre></div>
@ -91,10 +106,16 @@
</div>
<em v-if="item.p_name" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
</li>
</ul>
<div class="column-add" @click="addOpen(column.id)"><Icon type="md-add" /></div>
<li class="task-add">
<TaskAddSimple
:column-id="column.id"
:project-id="projectDetail.id"
@on-priority="addOpen"/>
</li>
</ul>
</li>
<li class="add-column" @click="addColumn"><Icon type="md-add" />{{$L('添加列表')}}</li>
</ul>
</div>
<div v-else class="project-table">
<div class="project-table-head">
@ -333,508 +354,15 @@
</div>
</template>
<style lang="scss" scoped>
:global {
.project-list {
display: flex;
flex-direction: column;
.project-head {
display: flex;
align-items: flex-start;
margin: 32px 32px 16px;
.project-titbox {
flex: 1;
margin-bottom: 16px;
.project-title {
display: flex;
align-items: center;
> h1 {
color: #333333;
font-size: 28px;
font-weight: 600;
}
.project-load {
display: flex;
align-items: center;
margin-left: 18px;
.common-loading {
width: 22px;
height: 22px;
}
}
}
.project-subtitle {
color: #999999;
margin-top: 18px;
line-height: 24px;
}
}
.project-icobox {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
margin-top: 2px;
margin-left: 80px;
.project-icons {
display: flex;
align-items: center;
flex-shrink: 0;
> li {
list-style: none;
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: 50%;
position: relative;
margin-left: 16px;
cursor: pointer;
transition: all 0.3s;
&:hover {
box-shadow: 0 0 6px #cccccc;
}
&.project-icon {
border-radius: 50%;
background-color: #F2F3F5;
.ivu-icon {
font-size: 20px;
width: 36px;
height: 36px;
line-height: 36px;
}
.ivu-badge {
position: absolute;
top: -6px;
left: 20px;
transform: scale(0.8);
}
&.active {
color: #ffffff;
background-color: #2d8cf0;
}
}
}
}
.project-switch {
display: flex;
justify-content: flex-end;
margin-top: 24px;
.project-switch-button {
display: flex;
align-items: center;
background-color: #ffffff;
border-radius: 6px;
position: relative;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
z-index: 0;
color: #2d8cf0;
border-radius: 6px;
border: 1px solid #2d8cf0;
background-color: #e6f7ff;
transition: left 0.2s;
}
> div {
z-index: 1;
width: 32px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
cursor: pointer;
color: #515a6e;
> i {
font-size: 17px;
}
&:first-child {
color: #2d8cf0;
}
}
&.menu {
&:before {
left: 50%;
}
> div:first-child {
color: #515a6e;
}
> div:last-child {
color: #2d8cf0;
}
}
}
}
}
}
.project-column {
display: flex;
height: 100%;
overflow-x: auto;
> ul {
display: inline-flex;
justify-content: space-between;
align-items: center;
> li {
flex-shrink: 0;
list-style: none;
width: 260px;
height: 100%;
display: flex;
flex-direction: column;
&:first-child {
margin-left: 22px;
}
&:last-child {
margin-right: 22px;
}
.column-head {
display: flex;
align-items: center;
padding: 6px 10px;
margin: 0 10px;
background-color: #F2F3F5;
border-radius: 4px;
.column-head-title {
flex: 1;
font-size: 16px;
font-weight: 600;
}
.column-head-num {
font-size: 12px;
padding: 2px 7px;
line-height: 16px;
border-radius: 3px;
color: #ffffff;
background-color: #cccccc;
&.have {
background-color: #1C1D1E;
}
}
}
> ul {
flex: 1;
height: 0;
overflow-x: hidden;
overflow-y: auto;
> li {
list-style: none;
margin: 0 10px 16px;
background-color: #ffffff;
border-radius: 12px;
padding: 12px;
transition: box-shadow 0.3s;
position: relative;
&:hover {
box-shadow: 0 0 10px #e6ecfa;
}
&:first-child {
margin-top: 16px;
}
.priority-color {
position: absolute;
top: 12px;
left: 0;
width: 3px;
height: 42px;
border-radius: 2px;
}
.task-head {
display: flex;
align-items: flex-start;
.task-title {
flex: 1;
padding-top: 1px;
> pre {
margin: 0;
padding: 0;
line-height: 1.5;
white-space: pre-wrap;
word-wrap: break-word;
}
}
.ivu-icon {
font-size: 22px;
color: #666666;
margin-left: 8px;
}
&.has-desc {
.task-title {
font-weight: 600;
}
}
}
.task-desc {
color: #999999;
margin-top: 10px;
line-height: 20px;
}
.task-tags {
margin-top: 10px;
.ivu-tag {
}
}
.task-users {
margin-top: 10px;
display: flex;
align-items: center;
> ul {
flex: 1;
width: 0;
display: flex;
align-items: center;
overflow: auto;
margin-right: 24px;
> li {
list-style: none;
margin-left: -6px;
&:first-child {
margin-left: 0;
}
.common-avatar {
border: 2px solid #ffffff;
}
}
}
.task-icon {
margin-left: 6px;
font-size: 12px;
.ivu-icon {
margin-left: 1px;
font-size: 14px;
}
}
}
.task-progress {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: flex-end;
.task-time {
flex-shrink: 0;
color: #777777;
background-color: #EAEDF2;
padding: 1px 4px;
font-size: 12px;
font-weight: 500;
border-radius: 3px;
display: flex;
align-items: center;
&.overdue {
font-weight: 600;
color: #ffffff;
background-color: #ed4014;
}
&.today {
color: #ffffff;
background-color: #ff9900;
}
.ivu-icon {
margin-right: 3px;
font-size: 14px;
}
}
}
}
}
.column-add {
cursor: pointer;
border-radius: 6px;
border: 2px dashed #F1f1f1;
padding: 5px 12px;
text-align: center;
margin: 0 10px 18px;
transition: all 0.2s;
.ivu-icon {
color: #cccccc;
font-size: 22px;
transition: all 0.2s;
}
&:hover {
border-color: #e1e1e1;
.ivu-icon {
color: #aaaaaa;
transform: scale(1.1);
}
}
}
}
}
}
.project-table {
height: 100%;
overflow-y: auto;
.project-row {
background-color: #ffffff;
border-bottom: 1px solid #F4F4F5;
position: relative;
> div {
display: flex;
align-items: center;
padding: 8px 12px;
border-right: 1px solid #F4F4F5;
&:first-child {
padding-left: 32px;
}
&:last-child {
border-right: 0;
}
}
.priority-color {
position: absolute;
top: 0;
left: 0;
bottom: -1px;
width: 3px;
}
}
.project-table-head,
.project-table-body {
margin: 0 32px 12px;
border-radius: 5px;
border: 1px solid #F4F4F5;
border-bottom: 0;
overflow: hidden;
&.project-table-hide {
.project-rows {
display: none;
}
.row-title {
.iconfont {
transform: rotate(-90deg);
}
}
}
}
.project-table-head {
.project-row {
> div {
color: #888888;
font-size: 13px;
font-weight: 500;
}
}
}
.project-table-body {
transition: box-shadow 0.3s;
&:hover {
box-shadow: 0 0 10px #e6ecfa;
}
.project-row {
> div {
padding: 10px 12px;
.task-time {
&.overdue,
&.today {
color: #ffffff;
padding: 1px 5px;
font-size: 13px;
border-radius: 3px;
}
&.overdue {
font-weight: 600;
background-color: #ed4014;
}
&.today {
font-weight: 500;
background-color: #ff9900;
}
}
&.row-title {
font-size: 14px;
font-weight: 500;
color: #333333;
padding-left: 14px;
.iconfont {
cursor: pointer;
transition: transform 0.3s;
font-size: 12px;
}
.row-h1 {
padding-left: 18px;
}
.row-num {
color: #999999;
padding-left: 6px;
}
}
&.row-item {
padding-left: 24px;
.ivu-icon {
font-size: 16px;
color: #dddddd;
&.completed {
color: #87d068;
}
}
.item-title {
padding: 0 22px 0 10px;
}
.item-icon {
font-size: 12px;
margin-right: 8px;
color: #777777;
.ivu-icon,
.iconfont {
margin-left: 1px;
font-size: 14px;
color: #666666;
}
.iconfont {
color: #999999;
}
}
}
&.row-member {
> ul {
display: flex;
align-items: center;
overflow: auto;
margin-left: -4px;
> li {
list-style: none;
margin-left: -6px;
&:first-child {
margin-left: 0;
}
}
}
}
&.row-add {
display: flex;
align-items: center;
height: 48px;
cursor: pointer;
> i {
font-size: 24px;
color: #777777;
margin-left: 32px;
margin-right: 4px;
}
}
}
}
}
}
}
}
</style>
<script>
import TaskPriority from "./TaskPriority";
import TaskAdd from "./TaskAdd";
import {mapState} from "vuex";
import UserInput from "../../../components/UserInput";
import TaskAddSimple from "./TaskAddSimple";
export default {
name: "ProjectList",
components: {UserInput, TaskAdd, TaskPriority},
components: {TaskAddSimple, UserInput, TaskAdd, TaskPriority},
data() {
return {
nowTime: Math.round(new Date().getTime() / 1000),
@ -984,12 +512,52 @@ export default {
methods: {
addOpen(column_id) {
if ($A.isJson(column_id)) {
this.addData = Object.assign(this.addData, column_id);
} else {
this.$set(this.addData, 'owner', this.userId);
this.$set(this.addData, 'column_id', column_id);
this.$set(this.addData, 'project_id', this.projectDetail.id);
}
this.addShow = true;
},
addBefore(column) {
this.$set(column, 'addBefore', true);
this.$refs['column_' + column.id][0].scrollTop = 0;
},
addColumn() {
$A.modalInput({
title: "添加列表",
placeholder: "输入列表名称",
onOk: (value, callback) => {
if (!value) return true;
$A.apiAjax({
url: 'project/column/add',
data: {
project_id: this.projectDetail.id,
name: value,
},
complete: () => {
callback();
},
error: () => {
$A.modalAlert('网络繁忙,请稍后再试!');
},
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess(msg);
this.$store.commit('getProjectDetail', this.projectDetail.id);
} else {
$A.modalError(msg, 301);
}
}
});
}
})
},
onAddTask() {
this.taskLoad++;
$A.apiAjax({

View File

@ -0,0 +1,186 @@
<template>
<div :class="['task-add-simple', active ? 'active' : '']" @mouseenter="mouseEnter=true" @mouseleave="mouseEnter=false">
<Input
v-model="addData.name"
ref="input"
type="textarea"
:rows="2"
:autosize="{ minRows: 2, maxRows: 3 }"
:maxlength="255"
:placeholder="$L('任务描述,回车创建')"
@on-focus="onFocus=true"
@on-blur="onFocus=false"
@on-keydown="onKeydown"></Input>
<div class="add-placeholder" @click="openAdd">
<Icon type="md-add" />{{$L('添加任务')}}
</div>
<div class="priority">
<ul>
<li v-for="(item, key) in taskPriority" :key="key">
<Tooltip :content="item.name + ' (' + item.days + $L('天') + ')'" transfer>
<i
class="iconfont"
:style="{color:item.color}"
v-html="addData.p_name == item.name ? '&#xe61d;' : '&#xe61c;'"
@click="choosePriority(item)"></i>
</Tooltip>
</li>
</ul>
<Icon type="md-settings" @click="onPriority"/>
</div>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
name: "TaskAddSimple",
props: {
projectId: {
default: ''
},
columnId: {
default: ''
},
addBefore: {
type: Boolean,
default: false
},
autoActive: {
type: Boolean,
default: false
}
},
data() {
return {
addData: {
owner: 0,
column_id: 0,
times: [],
subtasks: [],
p_level: 0,
p_name: '',
p_color: '',
},
active: false,
onFocus: false,
mouseEnter: false,
}
},
mounted() {
if (this.autoActive) {
this.$nextTick(this.openAdd)
}
},
computed: {
...mapState(['userId', 'taskPriority']),
},
watch: {
active(val) {
if (!val) {
this.$emit("on-close")
}
},
mouseEnter() {
this.chackClose()
},
onFocus() {
this.chackClose()
}
},
methods: {
getData() {
this.addData.project_id = this.projectId;
this.addData.column_id = this.columnId;
this.addData.owner = [this.userId];
if (this.addBefore) {
this.addData.add_before = true;
}
return $A.cloneJSON(this.addData);
},
openAdd() {
this.active = true;
this.$nextTick(() => {
if (this.taskPriority.length === 0) {
this.$store.commit('getTaskPriority', () => {
if (!this.addData.p_name && this.taskPriority.length > 0) {
this.choosePriority(this.taskPriority[0])
}
});
} else {
if (!this.addData.p_name && this.taskPriority.length > 0) {
this.choosePriority(this.taskPriority[0])
}
}
this.$refs.input.focus();
});
},
chackClose() {
if (this.mouseEnter || this.onFocus) {
return;
}
if (!this.addData.name) {
this.active = false;
}
},
onPriority() {
this.$emit("on-priority", this.getData())
this.active = false;
},
onKeydown(e) {
if (e.keyCode === 13) {
if (e.shiftKey) {
return;
}
e.preventDefault();
this.onAdd();
}
},
onAdd() {
if (!this.addData.name) {
$A.messageWarning("请输入任务描述");
return;
}
this.loadIng++;
$A.apiAjax({
url: 'project/task/add',
data: this.getData(),
method: 'post',
complete: () => {
this.loadIng--;
},
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess(msg);
this.$store.commit('getProjectDetail', this.projectId);
this.active = false;
} else {
$A.modalError(msg);
}
}
});
},
choosePriority(item) {
let start = new Date();
let end = new Date(new Date().setDate(start.getDate() + $A.runNum(item.days)));
this.$set(this.addData, 'times', [start, end])
this.$set(this.addData, 'p_level', item.priority)
this.$set(this.addData, 'p_name', item.name)
this.$set(this.addData, 'p_color', item.color)
this.$refs.input.focus()
}
}
}
</script>

View File

@ -24,7 +24,6 @@ export default {
}
},
});
return state.userInfo;
},
/**
@ -114,9 +113,6 @@ export default {
if (state.method.runNum(project_id) === 0) {
return;
}
if (state.projectDetail.id === project_id) {
return;
}
if (state.method.isJson(state.cacheProject[project_id])) {
state.projectDetail = state.cacheProject[project_id];
}

View File

@ -2,3 +2,8 @@
@import "iconfont";
@import "loading";
@import "main";
@import "dialog-wrapper";
@import "messenger-wrapper";
@import "project-list";
@import "task-add";

View File

@ -0,0 +1,100 @@
.dialog-wrapper {
display: flex;
flex-direction: column;
background-color: #ffffff;
z-index: 1;
.dialog-title {
display: flex;
align-items: center;
padding: 0 32px;
margin-top: 20px;
> h2 {
font-size: 18px;
font-weight: 600;
}
> em {
font-style: normal;
font-size: 17px;
font-weight: 500;
padding-left: 6px;
}
}
.dialog-chat {
flex: 1;
padding: 0 32px;
margin-top: 18px;
}
.dialog-footer {
display: flex;
flex-direction: column;
align-items: flex-end;
padding: 0 28px;
margin-bottom: 20px;
.dialog-newmsg {
display: none;
height: 30px;
line-height: 30px;
color: #ffffff;
font-size: 12px;
background-color: rgba(0, 0, 0, 0.6);
padding: 0 12px;
margin-bottom: 20px;
margin-right: 10px;
border-radius: 16px;
cursor: pointer;
z-index: 2;;
}
.dialog-input {
background-color: #F4F5F7;
padding: 10px 12px;
border-radius: 10px;
.ivu-input {
border: 0;
resize: none;
background-color: transparent;
&:focus {
box-shadow: none;
}
}
}
.chat-upload {
display: none;
width: 0;
height: 0;
overflow: hidden;
}
&.newmsg {
margin-top: -50px;
.dialog-newmsg {
display: block;
}
}
}
.drag-over {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 3;
background-color: rgba(255, 255, 255, 0.78);
display: flex;
align-items: center;
justify-content: center;
&:before {
content: "";
position: absolute;
top: 16px;
left: 16px;
right: 16px;
bottom: 16px;
border: 2px dashed #7b7b7b;
border-radius: 12px;
}
.drag-text {
padding: 12px;
font-size: 18px;
color: #666666;
}
}
}

View File

@ -335,116 +335,6 @@ body {
}
}
.task-add {
.task-add-form,
.task-add-advanced {
margin: 0 0 -18px;
.ivu-form-item-label {
font-weight: 600;
}
.teditor-box {
.tox-tinymce {
border-color: #e8e8e8;
}
.tox .tox-statusbar,
.tox .tox-menubar+.tox-toolbar,
.tox .tox-menubar+.tox-toolbar-overlord .tox-toolbar__primary,
.tox:not([dir=rtl]) .tox-toolbar__group:not(:last-of-type) {
border-color: #e8e8e8;
}
.tox .tox-toolbar,
.tox .tox-toolbar__overflow,
.tox .tox-toolbar__primary {
background-image: none;
border-bottom: 1px solid #e8e8e8;
}
}
.advanced-option {
margin-top: -6px;
z-index: 1;
display: flex;
align-items: center;
> button {
transition: margin 0.2s;
&.advanced {
margin-left: 22px;
}
&:focus {
box-shadow: none;
}
}
.advanced-priority {
display: flex;
align-items: center;
margin-left: 24px;
> li {
list-style: none;
margin-left: 3px;
.ivu-tooltip {
display: flex;
align-items: center;
.ivu-tooltip-rel {
height: 34px;
line-height: 1;
.iconfont {
font-size: 34px;
cursor: pointer;
}
}
}
}
}
}
}
.task-add-advanced {
margin: 1px 0 0;
padding: 34px 32px 6px;
border-radius: 8px;
border: 1px solid #e8e8e8;
.subtasks {
margin-bottom: 24px;
padding: 12px 16px;
border-radius: 6px;
background-color: #f8f8f8;
.enter-input {
.ivu-input {
background: transparent;
border-color: transparent;
&:hover,
&:focus {
box-shadow: none;
}
}
}
.sublist {
.ivu-row {
margin-bottom: 12px;
> div {
padding-right: 7px;
&:last-child {
padding-right: 0;
}
}
}
}
}
.ivu-date-picker {
width: 100%;
}
}
}
.task-add-advanced-transfer {
.task-drop-prepend {
text-align: center;
color: #c5c8ce;
line-height: 20px;
padding-bottom: 5px;
font-size: 12px;
border-bottom: 1px solid #f1f1f1;
margin-bottom: 5px;
}
}
.common-user {
position: relative;
.common-user-loading {
@ -925,291 +815,3 @@ body {
}
}
.dialog-wrapper {
display: flex;
flex-direction: column;
background-color: #ffffff;
z-index: 1;
.dialog-title {
display: flex;
align-items: center;
padding: 0 32px;
margin-top: 20px;
> h2 {
font-size: 18px;
font-weight: 600;
}
> em {
font-style: normal;
font-size: 17px;
font-weight: 500;
padding-left: 6px;
}
}
.dialog-chat {
flex: 1;
padding: 0 32px;
margin-top: 18px;
}
.dialog-footer {
display: flex;
flex-direction: column;
align-items: flex-end;
padding: 0 28px;
margin-bottom: 20px;
.dialog-newmsg {
display: none;
height: 30px;
line-height: 30px;
color: #ffffff;
font-size: 12px;
background-color: rgba(0, 0, 0, 0.6);
padding: 0 12px;
margin-bottom: 20px;
margin-right: 10px;
border-radius: 16px;
cursor: pointer;
z-index: 2;;
}
.dialog-input {
background-color: #F4F5F7;
padding: 10px 12px;
border-radius: 10px;
.ivu-input {
border: 0;
resize: none;
background-color: transparent;
&:focus {
box-shadow: none;
}
}
}
.chat-upload {
display: none;
width: 0;
height: 0;
overflow: hidden;
}
&.newmsg {
margin-top: -50px;
.dialog-newmsg {
display: block;
}
}
}
.drag-over {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 3;
background-color: rgba(255, 255, 255, 0.78);
display: flex;
align-items: center;
justify-content: center;
&:before {
content: "";
position: absolute;
top: 16px;
left: 16px;
right: 16px;
bottom: 16px;
border: 2px dashed #7b7b7b;
border-radius: 12px;
}
.drag-text {
padding: 12px;
font-size: 18px;
color: #666666;
}
}
}
.messenger-wrapper {
flex: 1;
display: flex;
align-items: flex-start;
.messenger-select {
position: relative;
height: 100%;
width: 30%;
min-width: 240px;
max-width: 320px;
flex-shrink: 0;
display: flex;
flex-direction: column;
&:after {
content: "";
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 1px;
background-color: #f2f2f2;
}
.messenger-search {
display: flex;
align-items: center;
justify-content: center;
height: 54px;
padding: 0 12px;
flex-shrink: 0;
.search-wrapper {
flex: 1;
background-color: #F7F7F7;
padding: 0 8px;
margin: 0 4px;
border-radius: 12px;
overflow: hidden;
.ivu-input {
border-color: transparent;
background-color: transparent;
&:hover,
&:focus {
box-shadow: none;
}
}
}
}
.messenger-list {
flex: 1;
height: 0;
width: 100%;
overflow-x: hidden;
overflow-y: auto;
> ul {
> li {
display: flex;
flex-direction: row;
align-items: center;
height: 80px;
padding: 0 12px;
position: relative;
cursor: pointer;
&.active {
background-color: #F4F5F7;
}
.user-avatar,
.icon-avatar {
width: 46px;
height: 46px;
flex-grow: 0;
flex-shrink: 0;
}
.icon-avatar {
line-height: 46px;
border-radius: 50%;
font-size: 26px;
background-color: #61B2F9;
color: #ffffff;
}
.dialog-box {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 12px;
.dialog-title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
line-height: 24px;
> span {
flex: 1;
max-width: 130px;
color: #333333;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
> i {
margin-left: 8px;
transform: scale(0.9);
font-size: 12px;
color: #87d068;
}
> em {
margin-left: 8px;
font-style: normal;
color: #999999;
font-size: 12px;
}
}
.dialog-text {
max-width: 170px;
color: #999999;
font-size: 12px;
line-height: 24px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.dialog-num {
position: absolute;
top: 10px;
left: 42px;
font-size: 12px;
transform: scale(0.8);
}
}
}
}
.messenger-menu {
display: flex;
align-items: center;
justify-content: center;
height: 54px;
flex-shrink: 0;
border-top: 1px solid #f2f2f2;
> i {
cursor: pointer;
font-size: 28px;
margin: 0 24px;
color: #aaaaaa;
opacity: 0.9;
&.active {
opacity: 1;
color: #2d8cf0;
}
&:hover {
opacity: 1;
}
}
}
}
.messenger-msg {
flex: 1;
width: 0;
height: 100%;
display: flex;
.dialog-wrapper,
.dialog-no {
flex: 1;
}
.dialog-no {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.dialog-no-icon {
background-color: #f4f5f7;
padding: 20px;
border-radius: 50%;
.ivu-icon {
color: #d1d8dd;
font-size: 46px;
}
}
.dialog-no-text {
margin-top: 16px;
color: #bec6cc;
background-color: #f4f5f7;
padding: 4px 15px;
border-radius: 14px;
}
}
}
}

View File

@ -0,0 +1,187 @@
.messenger-wrapper {
flex: 1;
display: flex;
align-items: flex-start;
.messenger-select {
position: relative;
height: 100%;
width: 30%;
min-width: 240px;
max-width: 320px;
flex-shrink: 0;
display: flex;
flex-direction: column;
&:after {
content: "";
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 1px;
background-color: #f2f2f2;
}
.messenger-search {
display: flex;
align-items: center;
justify-content: center;
height: 54px;
padding: 0 12px;
flex-shrink: 0;
.search-wrapper {
flex: 1;
background-color: #F7F7F7;
padding: 0 8px;
margin: 0 4px;
border-radius: 12px;
overflow: hidden;
.ivu-input {
border-color: transparent;
background-color: transparent;
&:hover,
&:focus {
box-shadow: none;
}
}
}
}
.messenger-list {
flex: 1;
height: 0;
width: 100%;
overflow-x: hidden;
overflow-y: auto;
> ul {
> li {
display: flex;
flex-direction: row;
align-items: center;
height: 80px;
padding: 0 12px;
position: relative;
cursor: pointer;
&.active {
background-color: #F4F5F7;
}
.user-avatar,
.icon-avatar {
width: 46px;
height: 46px;
flex-grow: 0;
flex-shrink: 0;
}
.icon-avatar {
line-height: 46px;
border-radius: 50%;
font-size: 26px;
background-color: #61B2F9;
color: #ffffff;
}
.dialog-box {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 12px;
.dialog-title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
line-height: 24px;
> span {
flex: 1;
max-width: 130px;
color: #333333;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
> i {
margin-left: 8px;
transform: scale(0.9);
font-size: 12px;
color: #87d068;
}
> em {
margin-left: 8px;
font-style: normal;
color: #999999;
font-size: 12px;
}
}
.dialog-text {
max-width: 170px;
color: #999999;
font-size: 12px;
line-height: 24px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.dialog-num {
position: absolute;
top: 10px;
left: 42px;
font-size: 12px;
transform: scale(0.8);
}
}
}
}
.messenger-menu {
display: flex;
align-items: center;
justify-content: center;
height: 54px;
flex-shrink: 0;
border-top: 1px solid #f2f2f2;
> i {
cursor: pointer;
font-size: 28px;
margin: 0 24px;
color: #aaaaaa;
opacity: 0.9;
&.active {
opacity: 1;
color: #2d8cf0;
}
&:hover {
opacity: 1;
}
}
}
}
.messenger-msg {
flex: 1;
width: 0;
height: 100%;
display: flex;
.dialog-wrapper,
.dialog-no {
flex: 1;
}
.dialog-no {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.dialog-no-icon {
background-color: #f4f5f7;
padding: 20px;
border-radius: 50%;
.ivu-icon {
color: #d1d8dd;
font-size: 46px;
}
}
.dialog-no-text {
margin-top: 16px;
color: #bec6cc;
background-color: #f4f5f7;
padding: 4px 15px;
border-radius: 14px;
}
}
}
}

504
resources/assets/sass/project-list.scss vendored Normal file
View File

@ -0,0 +1,504 @@
.project-list {
display: flex;
flex-direction: column;
.project-head {
display: flex;
align-items: flex-start;
margin: 32px 32px 16px;
.project-titbox {
flex: 1;
margin-bottom: 16px;
.project-title {
display: flex;
align-items: center;
> h1 {
color: #333333;
font-size: 28px;
font-weight: 600;
}
.project-load {
display: flex;
align-items: center;
margin-left: 18px;
.common-loading {
width: 22px;
height: 22px;
}
}
}
.project-subtitle {
color: #999999;
margin-top: 18px;
line-height: 24px;
}
}
.project-icobox {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
margin-top: 2px;
margin-left: 80px;
.project-icons {
display: flex;
align-items: center;
flex-shrink: 0;
> li {
list-style: none;
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: 50%;
position: relative;
margin-left: 16px;
cursor: pointer;
transition: all 0.3s;
&:hover {
box-shadow: 0 0 6px #cccccc;
}
&.project-icon {
border-radius: 50%;
background-color: #F2F3F5;
.ivu-icon {
font-size: 20px;
width: 36px;
height: 36px;
line-height: 36px;
}
.ivu-badge {
position: absolute;
top: -6px;
left: 20px;
transform: scale(0.8);
}
&.active {
color: #ffffff;
background-color: #2d8cf0;
}
}
}
}
.project-switch {
display: flex;
justify-content: flex-end;
margin-top: 24px;
.project-switch-button {
display: flex;
align-items: center;
background-color: #ffffff;
border-radius: 6px;
position: relative;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
z-index: 0;
color: #2d8cf0;
border-radius: 6px;
border: 1px solid #2d8cf0;
background-color: #e6f7ff;
transition: left 0.2s;
}
> div {
z-index: 1;
width: 32px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
cursor: pointer;
color: #515a6e;
> i {
font-size: 17px;
}
&:first-child {
color: #2d8cf0;
}
}
&.menu {
&:before {
left: 50%;
}
> div:first-child {
color: #515a6e;
}
> div:last-child {
color: #2d8cf0;
}
}
}
}
}
}
.project-column {
display: flex;
height: 100%;
overflow-x: auto;
> ul {
display: inline-flex;
justify-content: space-between;
align-items: flex-start;
> li {
flex-shrink: 0;
list-style: none;
width: 260px;
height: 100%;
display: flex;
flex-direction: column;
&:first-child {
margin-left: 22px;
}
&:last-child {
margin-right: 22px;
}
&.add-column {
display: flex;
flex-direction: row;
align-items: center;
height: 36px;
padding: 0 12px;
color: #888888;
cursor: pointer;
background-color: #F2F3F5;
&:hover {
color: #777777;
}
> i {
font-size: 16px;
padding-right: 8px;
}
}
.column-head {
display: flex;
align-items: center;
padding: 7px 10px;
margin: 0 10px;
background-color: #F2F3F5;
border-radius: 4px;
.column-head-title {
flex: 1;
width: 0;
display: flex;
align-items: center;
font-weight: 500;
> span {
font-size: 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
> em {
color: #888888;
font-style: normal;
font-size: 14px;
padding-left: 6px;
}
}
.column-head-icon {
display: flex;
align-items: center;
margin-left: 12px;
.ivu-icon {
padding-left: 8px;
font-size: 16px;
color: #aaaaaa;
cursor: pointer;
font-weight: 600;
transition: color 0.3s;
&:hover {
color: #888888;
}
}
}
}
> ul {
flex: 1;
height: 0;
overflow-x: hidden;
overflow-y: auto;
> li {
list-style: none;
margin: 0 10px 16px;
background-color: #ffffff;
border-radius: 12px;
padding: 12px;
transition: all 0.3s;
position: relative;
&:hover {
box-shadow: 0 0 10px #e6ecfa;
}
&:first-child {
margin-top: 16px;
}
.priority-color {
position: absolute;
top: 12px;
left: 0;
width: 3px;
height: 42px;
border-radius: 2px;
}
.task-head {
display: flex;
align-items: flex-start;
.task-title {
flex: 1;
padding-top: 1px;
> pre {
margin: 0;
padding: 0;
line-height: 1.5;
white-space: pre-wrap;
word-wrap: break-word;
}
}
.ivu-icon {
font-size: 22px;
color: #666666;
margin-left: 8px;
}
&.has-desc {
.task-title {
font-weight: 600;
}
}
}
.task-desc {
color: #999999;
margin-top: 10px;
line-height: 20px;
}
.task-tags {
margin-top: 10px;
.ivu-tag {
}
}
.task-users {
margin-top: 10px;
display: flex;
align-items: center;
> ul {
flex: 1;
width: 0;
display: flex;
align-items: center;
overflow: auto;
margin-right: 24px;
> li {
list-style: none;
margin-left: -6px;
&:first-child {
margin-left: 0;
}
.common-avatar {
border: 2px solid #ffffff;
}
}
}
.task-icon {
margin-left: 6px;
font-size: 12px;
.ivu-icon {
margin-left: 1px;
font-size: 14px;
}
}
}
.task-progress {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: flex-end;
.task-time {
flex-shrink: 0;
color: #777777;
background-color: #EAEDF2;
padding: 1px 4px;
font-size: 12px;
font-weight: 500;
border-radius: 3px;
display: flex;
align-items: center;
&.overdue {
font-weight: 600;
color: #ffffff;
background-color: #ed4014;
}
&.today {
color: #ffffff;
background-color: #ff9900;
}
.ivu-icon {
margin-right: 3px;
font-size: 14px;
}
}
}
}
}
}
}
}
.project-table {
height: 100%;
overflow-y: auto;
.project-row {
background-color: #ffffff;
border-bottom: 1px solid #F4F4F5;
position: relative;
> div {
display: flex;
align-items: center;
padding: 8px 12px;
border-right: 1px solid #F4F4F5;
&:first-child {
padding-left: 32px;
}
&:last-child {
border-right: 0;
}
}
.priority-color {
position: absolute;
top: 0;
left: 0;
bottom: -1px;
width: 3px;
}
}
.project-table-head,
.project-table-body {
margin: 0 32px 12px;
border-radius: 5px;
border: 1px solid #F4F4F5;
border-bottom: 0;
overflow: hidden;
&.project-table-hide {
.project-rows {
display: none;
}
.row-title {
.iconfont {
transform: rotate(-90deg);
}
}
}
}
.project-table-head {
.project-row {
> div {
color: #888888;
font-size: 13px;
font-weight: 500;
}
}
}
.project-table-body {
transition: box-shadow 0.3s;
&:hover {
box-shadow: 0 0 10px #e6ecfa;
}
.project-row {
> div {
padding: 10px 12px;
.task-time {
&.overdue,
&.today {
color: #ffffff;
padding: 1px 5px;
font-size: 13px;
border-radius: 3px;
}
&.overdue {
font-weight: 600;
background-color: #ed4014;
}
&.today {
font-weight: 500;
background-color: #ff9900;
}
}
&.row-title {
font-size: 14px;
font-weight: 500;
color: #333333;
padding-left: 14px;
.iconfont {
cursor: pointer;
transition: transform 0.3s;
font-size: 12px;
}
.row-h1 {
padding-left: 18px;
}
.row-num {
color: #999999;
padding-left: 6px;
}
}
&.row-item {
padding-left: 24px;
.ivu-icon {
font-size: 16px;
color: #dddddd;
&.completed {
color: #87d068;
}
}
.item-title {
padding: 0 22px 0 10px;
}
.item-icon {
font-size: 12px;
margin-right: 8px;
color: #777777;
.ivu-icon,
.iconfont {
margin-left: 1px;
font-size: 14px;
color: #666666;
}
.iconfont {
color: #999999;
}
}
}
&.row-member {
> ul {
display: flex;
align-items: center;
overflow: auto;
margin-left: -4px;
> li {
list-style: none;
margin-left: -6px;
&:first-child {
margin-left: 0;
}
}
}
}
&.row-add {
display: flex;
align-items: center;
height: 48px;
cursor: pointer;
> i {
font-size: 24px;
color: #777777;
margin-left: 32px;
margin-right: 4px;
}
}
}
}
}
}
}

View File

@ -1,7 +1,7 @@
/* 滚动条美化 */
::-webkit-scrollbar {
width: 6px;
height: 0;
width: 10px;
height: 10px;
}
/*滚动条滑块隐藏*/
@ -18,7 +18,15 @@
/*鼠标浮到容器上,让该容器的滚动条滑块显示*/
:hover::-webkit-scrollbar-thumb {
border: 2px solid transparent;
background: rgba(0, 0, 0, .2);
background-clip: content-box;
}
/*鼠标浮到容器上,让该容器的滚动条滑块显示*/
:hover::-webkit-scrollbar-thumb:hover {
border-top-width: 0;
border-bottom-width: 0;
}
/*滚动条轨道*/

167
resources/assets/sass/task-add.scss vendored Normal file
View File

@ -0,0 +1,167 @@
.task-add {
.task-add-form,
.task-add-advanced {
margin: 0 0 -18px;
.ivu-form-item-label {
font-weight: 600;
}
.teditor-box {
.tox-tinymce {
border-color: #e8e8e8;
}
.tox .tox-statusbar,
.tox .tox-menubar+.tox-toolbar,
.tox .tox-menubar+.tox-toolbar-overlord .tox-toolbar__primary,
.tox:not([dir=rtl]) .tox-toolbar__group:not(:last-of-type) {
border-color: #e8e8e8;
}
.tox .tox-toolbar,
.tox .tox-toolbar__overflow,
.tox .tox-toolbar__primary {
background-image: none;
border-bottom: 1px solid #e8e8e8;
}
}
.advanced-option {
margin-top: -6px;
z-index: 1;
display: flex;
align-items: center;
> button {
transition: margin 0.2s;
&.advanced {
margin-left: 22px;
}
&:focus {
box-shadow: none;
}
}
.advanced-priority {
display: flex;
align-items: center;
margin-left: 24px;
> li {
list-style: none;
margin-left: 3px;
.ivu-tooltip {
display: flex;
align-items: center;
.ivu-tooltip-rel {
height: 34px;
line-height: 1;
.iconfont {
font-size: 34px;
cursor: pointer;
}
}
}
}
}
}
}
.task-add-advanced {
margin: 1px 0 0;
padding: 34px 32px 6px;
border-radius: 8px;
border: 1px solid #e8e8e8;
.subtasks {
margin-bottom: 24px;
padding: 12px 16px;
border-radius: 6px;
background-color: #f8f8f8;
.enter-input {
.ivu-input {
background: transparent;
border-color: transparent;
&:hover,
&:focus {
box-shadow: none;
}
}
}
.sublist {
.ivu-row {
margin-bottom: 12px;
> div {
padding-right: 7px;
&:last-child {
padding-right: 0;
}
}
}
}
}
.ivu-date-picker {
width: 100%;
}
}
}
.task-add-advanced-transfer {
.task-drop-prepend {
text-align: center;
color: #c5c8ce;
line-height: 20px;
padding-bottom: 5px;
font-size: 12px;
border-bottom: 1px solid #f1f1f1;
margin-bottom: 5px;
}
}
.task-add-simple {
.ivu-input-wrapper {
display: none;
}
.add-placeholder {
cursor: pointer;
color: #888888;
.ivu-icon {
margin-right: 4px;
}
&:hover {
color: #666666;
}
}
.priority {
display: none;
align-items: center;
min-height: 22px;
margin-top: 10px;
margin-bottom: -3px;
> ul {
flex: 1;
display: flex;
align-items: center;
> li {
list-style: none;
margin-right: 3px;
.ivu-tooltip {
display: flex;
align-items: center;
.ivu-tooltip-rel {
height: 22px;
line-height: 1;
.iconfont {
font-size: 22px;
cursor: pointer;
}
}
}
}
}
.ivu-icon {
cursor: pointer;
font-size: 16px;
}
}
&.active {
.ivu-input-wrapper {
display: block;
}
.add-placeholder {
display: none;
}
.priority {
display: flex;
}
}
}