mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 11:19:56 +00:00
perf: 优化会员选择器
This commit is contained in:
parent
ae4be9e08e
commit
e507c148ca
@ -1,321 +0,0 @@
|
||||
<template>
|
||||
<div :class="['common-user', maxHiddenClass]">
|
||||
<Select
|
||||
ref="select"
|
||||
v-model="selects"
|
||||
:transfer="transfer"
|
||||
:placeholder="placeholder"
|
||||
:size="size"
|
||||
:loading="loadIng > 0"
|
||||
:loading-text="$L('加载中...')"
|
||||
:default-label="value"
|
||||
:default-event-object="true"
|
||||
:multiple-max="multipleMax"
|
||||
:multiple-uncancelable="uncancelable"
|
||||
:remote-method="remoteMethod"
|
||||
@on-query-change="searchUser"
|
||||
@on-open-change="openChange"
|
||||
multiple
|
||||
filterable
|
||||
:search-in-option="windowTouch"
|
||||
:search-placeholder="$L('输入关键词搜索')"
|
||||
transfer-class-name="common-user-transfer">
|
||||
<div v-if="multipleMax" slot="drop-prepend" class="user-drop-prepend">
|
||||
<div class="user-drop-text">{{selects.length}} / {{multipleMax}}</div>
|
||||
<Checkbox class="user-drop-check" v-model="multipleCheck" @on-change="onMultipleChange"></Checkbox>
|
||||
</div>
|
||||
<slot name="option-prepend"></slot>
|
||||
<Option
|
||||
v-for="(item, key) in list"
|
||||
:value="item.userid"
|
||||
:key="key"
|
||||
:key-value="`${item.email}|${item.pinyin}`"
|
||||
:label="item.nickname"
|
||||
:avatar="item.userimg"
|
||||
:disabled="isDisabled(item.userid)">
|
||||
<div class="user-input-option">
|
||||
<div class="user-input-avatar"><EAvatar class="avatar" :src="item.userimg"/></div>
|
||||
<div v-if="item.bot" class="taskfont user-input-bot"></div>
|
||||
<div v-if="item.disable_at" class="user-input-disable">[{{$L('离职')}}]</div>
|
||||
<div class="user-input-nickname">{{ item.nickname }}</div>
|
||||
<div class="user-input-userid">ID: {{ item.userid }}</div>
|
||||
</div>
|
||||
</Option>
|
||||
</Select>
|
||||
<div v-if="loadIng > 0" class="common-user-loading"><Loading/></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Store} from 'le5le-store';
|
||||
|
||||
export default {
|
||||
name: 'UserInput',
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number, Array],
|
||||
default: ''
|
||||
},
|
||||
uncancelable: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
disabledChoice: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
placeholder: {
|
||||
default: ''
|
||||
},
|
||||
size: {
|
||||
default: 'default'
|
||||
},
|
||||
transfer: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
multipleMax: {
|
||||
type: Number,
|
||||
},
|
||||
maxHiddenInput: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
maxHiddenSelect: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
projectId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
noProjectId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
dialogId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
showBot: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showDisable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
||||
|
||||
selects: [],
|
||||
list: [],
|
||||
|
||||
multipleCheck: false,
|
||||
|
||||
searchKey: null,
|
||||
searchHistory: [],
|
||||
|
||||
subscribe: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.subscribe = Store.subscribe('cacheUserActive', (data) => {
|
||||
let index = this.list.findIndex(({userid}) => userid == data.userid);
|
||||
if (index > -1) {
|
||||
this.$set(this.list, index, Object.assign({}, this.list[index], data));
|
||||
this.handleSelectData();
|
||||
}
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.subscribe) {
|
||||
this.subscribe.unsubscribe();
|
||||
this.subscribe = null;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
maxHiddenClass() {
|
||||
const {multipleMax, maxHiddenInput, selects} = this;
|
||||
if (multipleMax && maxHiddenInput) {
|
||||
if (selects.length >= multipleMax) {
|
||||
return 'hidden-input'
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler() {
|
||||
const tmpId = this._tmpId = $A.randomString(6)
|
||||
setTimeout(() => {
|
||||
if (tmpId === this._tmpId) this.valueChange()
|
||||
}, 10)
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
selects(val) {
|
||||
this.$emit('input', val)
|
||||
if (this.maxHiddenSelect && val.length >= this.maxHiddenSelect && this.$refs.select) {
|
||||
this.$refs.select.hideMenu()
|
||||
}
|
||||
this.calcMultipleSelect()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
searchUser(key) {
|
||||
if (typeof key !== "string") key = "";
|
||||
this.searchKey = key;
|
||||
//
|
||||
const history = this.searchHistory.find(item => item.key == key);
|
||||
if (history) {
|
||||
this.list = history.data
|
||||
this.calcMultipleSelect()
|
||||
}
|
||||
//
|
||||
if (!history) this.loadIng++;
|
||||
setTimeout(() => {
|
||||
if (this.searchKey != key) {
|
||||
if (!history) this.loadIng--;
|
||||
return;
|
||||
}
|
||||
this.$store.dispatch("call", {
|
||||
url: 'users/search',
|
||||
data: {
|
||||
keys: {
|
||||
key,
|
||||
project_id: this.projectId,
|
||||
no_project_id: this.noProjectId,
|
||||
dialog_id: this.dialogId,
|
||||
bot: this.showBot && key ? 2 : 0,
|
||||
disable: this.showDisable && key ? 2 : 0,
|
||||
},
|
||||
take: 50
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.list = data
|
||||
this.calcMultipleSelect()
|
||||
//
|
||||
const index = this.searchHistory.findIndex(item => item.key == key);
|
||||
const tmpData = {
|
||||
key,
|
||||
data,
|
||||
time: $A.Time()
|
||||
};
|
||||
if (index > -1) {
|
||||
this.searchHistory.splice(index, 1, tmpData)
|
||||
} else {
|
||||
this.searchHistory.push(tmpData)
|
||||
}
|
||||
}).catch(({msg}) => {
|
||||
this.list = []
|
||||
this.calcMultipleSelect()
|
||||
$A.messageWarning(msg)
|
||||
}).finally(_ => {
|
||||
if (!history) this.loadIng--;
|
||||
});
|
||||
}, this.searchHistory.length > 0 ? 300 : 0)
|
||||
},
|
||||
|
||||
isDisabled(userid) {
|
||||
if (this.disabledChoice.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return this.disabledChoice.includes(userid)
|
||||
},
|
||||
|
||||
openChange(show) {
|
||||
if (show) {
|
||||
this.$nextTick(this.searchUser);
|
||||
}
|
||||
this.calcMultipleSelect()
|
||||
},
|
||||
|
||||
remoteMethod() {
|
||||
//
|
||||
},
|
||||
|
||||
valueChange() {
|
||||
if (this.selects == this.value) {
|
||||
return
|
||||
}
|
||||
if ($A.isArray(this.value)) {
|
||||
this.selects = $A.cloneJSON(this.value);
|
||||
} else if (this.value) {
|
||||
this.selects = [this.value]
|
||||
} else {
|
||||
this.selects = [];
|
||||
}
|
||||
this.selects.some(userid => {
|
||||
if (!this.list.find(item => item.userid == userid)) {
|
||||
this.list.push({userid, nickname: userid})
|
||||
this.calcMultipleSelect()
|
||||
this.$store.dispatch("getUserBasic", {userid})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleSelectData() {
|
||||
this.__handleSelectTimeout && clearTimeout(this.__handleSelectTimeout);
|
||||
this.__handleSelectTimeout = setTimeout(() => {
|
||||
if (!this.$refs.select) {
|
||||
return;
|
||||
}
|
||||
const list = this.$refs.select.getValue();
|
||||
list && list.some(option => {
|
||||
const data = this.list.find(({userid}) => userid == option.value)
|
||||
if (data) {
|
||||
this.$set(option, 'label', data.nickname)
|
||||
this.$set(option, 'avatar', data.userimg)
|
||||
}
|
||||
})
|
||||
}, 100);
|
||||
},
|
||||
|
||||
calcMultipleSelect() {
|
||||
if (this.multipleMax && this.list.length > 0) {
|
||||
this.calcMultipleTime && clearTimeout(this.calcMultipleTime)
|
||||
this.calcMultipleTime = setTimeout(_ => {
|
||||
let allSelected = true
|
||||
this.$refs.select.selectOptions.some(({componentInstance}) => {
|
||||
if (!this.selects.includes(componentInstance.value)) {
|
||||
allSelected = false
|
||||
}
|
||||
})
|
||||
this.multipleCheck = allSelected
|
||||
}, 10)
|
||||
} else {
|
||||
this.multipleCheck = false
|
||||
}
|
||||
},
|
||||
|
||||
onMultipleChange(val) {
|
||||
if (val) {
|
||||
let optional = this.multipleMax - this.selects.length
|
||||
this.$refs.select.selectOptions.some(({componentInstance}) => {
|
||||
if (this.multipleMax && optional <= 0) {
|
||||
this.$nextTick(_ => {
|
||||
$A.messageWarning("已超过最大选择数量")
|
||||
this.multipleCheck = false
|
||||
})
|
||||
return true
|
||||
}
|
||||
if (!this.selects.includes(componentInstance.value)) {
|
||||
componentInstance.select()
|
||||
optional--
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.selects = []
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
381
resources/assets/js/components/UserSelect.vue
Executable file
381
resources/assets/js/components/UserSelect.vue
Executable file
@ -0,0 +1,381 @@
|
||||
<template>
|
||||
<div class="common-user-select" :class="{'select-border': border}">
|
||||
<ul @click="onSelect(true)" :style="warpStyle">
|
||||
<li v-for="userid in values">
|
||||
<UserAvatar :userid="userid" :size="avatarSize" :show-icon="avatarIcon" :show-name="avatarName" tooltip-disabled/>
|
||||
</li>
|
||||
<li v-if="addIcon || values.length === 0" class="add-icon" :style="addStyle" @click.stop="onSelect"></li>
|
||||
</ul>
|
||||
<Modal
|
||||
v-model="showModal"
|
||||
:mask-closable="false"
|
||||
class-name="common-user-select-modal"
|
||||
:title="localTitle"
|
||||
:fullscreen="windowWidth < 576">
|
||||
<div class="user-modal-search">
|
||||
<Input v-model="searchKey" :placeholder="localPlaceholder" clearable>
|
||||
<div class="search-pre" slot="prefix">
|
||||
<Loading v-if="loadIng > 0"/>
|
||||
<Icon v-else type="ios-search" />
|
||||
</div>
|
||||
</Input>
|
||||
</div>
|
||||
<Scrollbar class="user-modal-list">
|
||||
<ul>
|
||||
<li
|
||||
v-for="item in lists"
|
||||
:class="{
|
||||
selected: selects.includes(item.userid),
|
||||
disabled: inUncancelable(item.userid) || isDisabled(item.userid)
|
||||
}"
|
||||
@click="selectUser(item)">
|
||||
<Icon v-if="selects.includes(item.userid)" class="user-modal-icon" type="ios-checkmark-circle" />
|
||||
<Icon v-else class="user-modal-icon" type="ios-radio-button-off" />
|
||||
<UserAvatar class="user-modal-avatar" :userid="item.userid" show-name tooltip-disabled/>
|
||||
<div class="user-modal-userid">ID: {{item.userid}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</Scrollbar>
|
||||
<div v-if="multipleMax" class="user-modal-multiple">
|
||||
<Checkbox class="multiple-check" v-model="multipleCheck" @on-change="onMultipleChange" :disabled="lists.length === 0">{{$L(multipleCheck ? '取消全选' : '全选')}}</Checkbox>
|
||||
<div class="multiple-text">
|
||||
<span>{{$L('最多只能选择' + multipleMax + '个')}}</span>
|
||||
<em v-if="selects.length">({{$L(`已选${selects.length}个`)}})</em>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="adaption">
|
||||
<Button type="default" :loading="submittIng > 0" @click="showModal=false">{{$L('取消')}}</Button>
|
||||
<Button type="primary" :loading="submittIng > 0" @click="onSubmit">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UserSelect',
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number, Array],
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
// 不允许取消的列表
|
||||
uncancelable: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
// 禁止选择的列表
|
||||
disabledChoice: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
// 指定项目ID
|
||||
projectId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 指定非项目ID
|
||||
noProjectId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 指定会话ID
|
||||
dialogId: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 是否显示机器人
|
||||
showBot: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否显示禁用的
|
||||
showDisable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 最大选择数量
|
||||
multipleMax: {
|
||||
type: Number,
|
||||
},
|
||||
|
||||
// 头像大小
|
||||
avatarSize: {
|
||||
type: Number,
|
||||
default: 28
|
||||
},
|
||||
// 是否显示头像
|
||||
avatarIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示名称
|
||||
avatarName: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否显示添加按钮(已选择为空时一定是true)
|
||||
addIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否只有点击添加按钮才显示弹窗
|
||||
onlyAddIconClick: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 显示边框
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
// 弹窗标题
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
// 搜索提示
|
||||
placeholder: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
// 提交前的回调
|
||||
beforeSubmit: Function
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
||||
submittIng: 0,
|
||||
|
||||
values: [],
|
||||
lists: [],
|
||||
selects: [],
|
||||
|
||||
showModal: false,
|
||||
|
||||
multipleCheck: false,
|
||||
|
||||
searchTimer: null,
|
||||
searchKey: null,
|
||||
searchHistory: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(value) {
|
||||
if (typeof value === 'number') {
|
||||
this.$emit('input', value > 0 ? [value] : [])
|
||||
} else if (typeof value === 'string') {
|
||||
value = value.indexOf(',') > -1 ? value.split(',') : [value]
|
||||
this.$emit('input', value.map(item => $A.runNum(item)).filter(item => item > 0))
|
||||
}
|
||||
this.values = value
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
showModal(value) {
|
||||
if (value) {
|
||||
this.searchUser()
|
||||
} else {
|
||||
this.searchKey = ""
|
||||
}
|
||||
},
|
||||
searchKey() {
|
||||
this.searchUser()
|
||||
},
|
||||
'lists.length'() {
|
||||
this.calcMultiple()
|
||||
},
|
||||
'selects.length'() {
|
||||
this.calcMultiple()
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
warpStyle() {
|
||||
if (!this.onlyAddIconClick) {
|
||||
return {
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}
|
||||
},
|
||||
addStyle() {
|
||||
return {
|
||||
width: this.avatarSize + 'px',
|
||||
height: this.avatarSize + 'px',
|
||||
}
|
||||
},
|
||||
localTitle() {
|
||||
if (this.title === undefined) {
|
||||
return this.$L('选择会员')
|
||||
} else {
|
||||
return this.title;
|
||||
}
|
||||
},
|
||||
localPlaceholder() {
|
||||
if (this.placeholder === undefined) {
|
||||
return this.$L('搜索会员')
|
||||
} else {
|
||||
return this.placeholder;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
searchUser() {
|
||||
if (!this.showModal) {
|
||||
return
|
||||
}
|
||||
//
|
||||
let key = this.searchKey;
|
||||
const history = this.searchHistory.find(item => item.key == key);
|
||||
if (history) {
|
||||
this.lists = history.data
|
||||
}
|
||||
//
|
||||
if (this.searchTimer) {
|
||||
clearTimeout(this.searchTimer);
|
||||
}
|
||||
this.searchTimer = setTimeout(() => {
|
||||
if (this.searchKey != key) {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.loadIng++;
|
||||
}, 300)
|
||||
this.$store.dispatch("call", {
|
||||
url: 'users/search',
|
||||
data: {
|
||||
keys: {
|
||||
key,
|
||||
project_id: this.projectId,
|
||||
no_project_id: this.noProjectId,
|
||||
dialog_id: this.dialogId,
|
||||
bot: this.showBot && key ? 2 : 0,
|
||||
disable: this.showDisable && key ? 2 : 0,
|
||||
},
|
||||
take: 50
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.lists = data
|
||||
//
|
||||
const index = this.searchHistory.findIndex(item => item.key == key);
|
||||
const tmpData = {key, data, time: $A.Time()};
|
||||
if (index > -1) {
|
||||
this.searchHistory.splice(index, 1, tmpData)
|
||||
} else {
|
||||
this.searchHistory.push(tmpData)
|
||||
}
|
||||
}).catch(({msg}) => {
|
||||
this.lists = []
|
||||
$A.messageWarning(msg)
|
||||
}).finally(_ => {
|
||||
this.loadIng--;
|
||||
});
|
||||
}, this.searchHistory.length > 0 ? 300 : 0)
|
||||
},
|
||||
|
||||
onSelect(warp = false) {
|
||||
if (warp === true) {
|
||||
if (this.onlyAddIconClick) {
|
||||
return
|
||||
}
|
||||
}
|
||||
this.selects = $A.cloneJSON(this.values)
|
||||
this.showModal = true
|
||||
},
|
||||
|
||||
onSubmit() {
|
||||
const clone = $A.cloneJSON(this.values)
|
||||
this.values = $A.cloneJSON(this.selects)
|
||||
this.$emit('input', this.values)
|
||||
|
||||
if (!this.beforeSubmit) {
|
||||
this.showModal = false
|
||||
return
|
||||
}
|
||||
const before = this.beforeSubmit();
|
||||
if (before && before.then) {
|
||||
this.submittIng++
|
||||
before.then(() => {
|
||||
this.showModal = false
|
||||
}).catch(() => {
|
||||
this.values = clone
|
||||
this.$emit('input', this.values)
|
||||
}).finally(() => {
|
||||
this.submittIng--
|
||||
})
|
||||
} else {
|
||||
this.showModal = false
|
||||
}
|
||||
},
|
||||
|
||||
onMultipleChange(check) {
|
||||
if (check) {
|
||||
let optional = this.multipleMax - this.selects.length
|
||||
this.lists.some(item => {
|
||||
if (this.inUncancelable(item.userid)) {
|
||||
return false
|
||||
}
|
||||
if (this.isDisabled(item.userid)) {
|
||||
return false
|
||||
}
|
||||
if (optional <= 0) {
|
||||
$A.messageWarning("已超过最大选择数量")
|
||||
return true
|
||||
}
|
||||
if (!this.selects.includes(item.userid)) {
|
||||
this.selects.push(item.userid)
|
||||
optional--
|
||||
}
|
||||
})
|
||||
this.calcMultiple()
|
||||
} else {
|
||||
this.selects = $A.cloneJSON(this.uncancelable)
|
||||
}
|
||||
},
|
||||
|
||||
calcMultiple() {
|
||||
this.$nextTick(() => {
|
||||
this.multipleCheck = this.lists.length > 0 && this.lists.filter(item => this.selects.includes(item.userid)).length === this.lists.length;
|
||||
})
|
||||
},
|
||||
|
||||
selectUser(item) {
|
||||
if (this.selects.includes(item.userid)) {
|
||||
if (this.inUncancelable(item.userid)) {
|
||||
return
|
||||
}
|
||||
this.selects = this.selects.filter(userid => userid != item.userid)
|
||||
} else {
|
||||
if (this.isDisabled(item.userid)) {
|
||||
return
|
||||
}
|
||||
if (this.multipleMax && this.selects.length >= this.multipleMax) {
|
||||
$A.messageWarning("已超过最大选择数量")
|
||||
return
|
||||
}
|
||||
this.selects.push(item.userid)
|
||||
}
|
||||
},
|
||||
|
||||
inUncancelable(value) {
|
||||
if (this.uncancelable.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return this.uncancelable.includes(value);
|
||||
},
|
||||
|
||||
isDisabled(userid) {
|
||||
if (this.disabledChoice.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return this.disabledChoice.includes(userid)
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@ -71,8 +71,8 @@
|
||||
</DropdownItem>
|
||||
<DropdownItem name="exportTask">{{$L('导出任务统计')}}</DropdownItem>
|
||||
<DropdownItem name="exportOverdueTask">{{$L('导出超期任务')}}</DropdownItem>
|
||||
<DropdownItem name="exportCheckin">{{$L('导出签到数据')}}</DropdownItem>
|
||||
<DropdownItem name="exportApprove">{{$L('导出审批数据')}}</DropdownItem>
|
||||
<DropdownItem name="exportCheckin">{{$L('导出签到数据')}}</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
<!-- 其他菜单 -->
|
||||
|
||||
@ -53,10 +53,8 @@
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import UserInput from "../../../components/UserInput";
|
||||
export default {
|
||||
name: "ApproveExport",
|
||||
components: {UserInput},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
:mask-closable="false">
|
||||
<Form ref="export" :model="formData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem :label="$L('导出成员')">
|
||||
<UserInput v-model="formData.userid" :multiple-max="100" show-disable :placeholder="$L('请选择成员')"/>
|
||||
<UserSelect v-model="formData.userid" :multiple-max="100" avatar-name show-disable :title="$L('请选择成员')"/>
|
||||
<div class="form-tip">{{$L('每次最多选择导出100个成员')}}</div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('签到日期')">
|
||||
@ -60,10 +60,10 @@
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
export default {
|
||||
name: "CheckinExport",
|
||||
components: {UserInput},
|
||||
components: {UserSelect},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
:mask-closable="false">
|
||||
<Form :model="addData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="userids" :label="$L('新增成员')">
|
||||
<UserInput v-model="addData.userids" :disabledChoice="addData.disabledChoice" :multiple-max="100" show-bot :placeholder="$L('选择成员')"/>
|
||||
<UserSelect v-model="addData.userids" :disabledChoice="addData.disabledChoice" :multiple-max="100" show-bot :title="$L('选择成员')"/>
|
||||
<div v-if="dialogData.group_type === 'department'" class="form-tip">{{$L('此操作仅加入群成员并不会加入部门')}}</div>
|
||||
<div v-else-if="dialogData.group_type === 'project'" class="form-tip">{{$L('此操作仅加入群成员并不会加入项目')}}</div>
|
||||
<div v-else-if="dialogData.group_type === 'task'" class="form-tip">{{$L('此操作仅加入群成员并不会加入任务负责人')}}</div>
|
||||
@ -57,11 +57,11 @@
|
||||
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "DialogGroupInfo",
|
||||
components: {UserInput},
|
||||
components: {UserSelect},
|
||||
props: {
|
||||
dialogId: {
|
||||
type: Number,
|
||||
|
||||
@ -32,20 +32,20 @@
|
||||
</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem prop="userids" :label="$L('指定成员')">
|
||||
<UserInput v-model="value.userids" :multiple-max="20" :placeholder="`(${$L('或')}) ${$L('选择转发指定成员')}`"/>
|
||||
<FormItem prop="userids" :label="`(${$L('或')}) ${$L('指定成员')}`">
|
||||
<UserSelect v-model="value.userids" :multiple-max="20" :avatar-size="24" :title="$L('选择转发指定成员')" border/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import {mapState} from "vuex";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "DialogSelect",
|
||||
components: {UserInput},
|
||||
components: {UserSelect},
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
|
||||
@ -335,12 +335,12 @@
|
||||
<FormItem prop="avatar" :label="$L('群头像')">
|
||||
<ImgUpload v-model="createGroupData.avatar" :num="1" :width="512" :height="512" :whcut="1"/>
|
||||
</FormItem>
|
||||
<FormItem prop="userids" :label="$L('群成员')">
|
||||
<UserSelect v-model="createGroupData.userids" :uncancelable="createGroupData.uncancelable" :multiple-max="100" show-bot :title="$L('选择项目成员')"/>
|
||||
</FormItem>
|
||||
<FormItem prop="chat_name" :label="$L('群名称')">
|
||||
<Input v-model="createGroupData.chat_name" :placeholder="$L('输入群名称(选填)')"/>
|
||||
</FormItem>
|
||||
<FormItem prop="userids" :label="$L('群成员')">
|
||||
<UserInput v-model="createGroupData.userids" :uncancelable="createGroupData.uncancelable" :multiple-max="100" show-bot :placeholder="$L('选择项目成员')"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
<Button type="default" @click="createGroupShow=false">{{$L('取消')}}</Button>
|
||||
@ -397,6 +397,7 @@
|
||||
<RadioGroup v-model="todoSettingData.type">
|
||||
<Radio label="all">{{$L('所有成员')}}</Radio>
|
||||
<Radio label="user">{{$L('指定成员')}}</Radio>
|
||||
<br/>
|
||||
<Radio v-if="todoSettingData.my_id" label="my">
|
||||
<div class="dialog-wrapper-todo">
|
||||
<div>
|
||||
@ -414,8 +415,8 @@
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem v-if="todoSettingData.type === 'user'" prop="userids">
|
||||
<UserInput v-model="todoSettingData.userids" :dialog-id="dialogId" :placeholder="$L('选择指定成员')"/>
|
||||
<FormItem prop="userids" :label="$L('指定成员')" v-if="todoSettingData.type === 'user'">
|
||||
<UserSelect v-model="todoSettingData.userids" :dialog-id="dialogId" :title="$L('选择指定成员')"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
@ -439,7 +440,7 @@
|
||||
:mask-closable="false">
|
||||
<Form :model="groupTransferData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="userid" :label="$L('新的群主')">
|
||||
<UserInput v-model="groupTransferData.userid" :disabledChoice="groupTransferData.disabledChoice" :multiple-max="1" max-hidden-select :placeholder="$L('选择新的群主')"/>
|
||||
<UserSelect v-model="groupTransferData.userid" :disabledChoice="groupTransferData.disabledChoice" :multiple-max="1" :title="$L('选择新的群主')"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
@ -509,7 +510,6 @@
|
||||
import {mapGetters, mapState} from "vuex";
|
||||
import DialogItem from "./DialogItem";
|
||||
import DialogUpload from "./DialogUpload";
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import DrawerOverlay from "../../../components/DrawerOverlay";
|
||||
import DialogGroupInfo from "./DialogGroupInfo";
|
||||
import DialogRespond from "./DialogRespond";
|
||||
@ -522,10 +522,12 @@ import ImgUpload from "../../../components/ImgUpload.vue";
|
||||
import {choiceEmojiOne} from "./ChatInput/one";
|
||||
|
||||
import ApproveDetails from "../../../pages/manage/approve/details.vue";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "DialogWrapper",
|
||||
components: {
|
||||
UserSelect,
|
||||
ImgUpload,
|
||||
DialogSelect,
|
||||
DialogRespond,
|
||||
@ -534,7 +536,6 @@ export default {
|
||||
ChatInput,
|
||||
DialogGroupInfo,
|
||||
DrawerOverlay,
|
||||
UserInput,
|
||||
DialogUpload,
|
||||
ApproveDetails
|
||||
},
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<Input v-model="addData.name" :maxlength="50" :placeholder="$L('选填')"/>
|
||||
</FormItem>
|
||||
<FormItem prop="userids" :label="$L('邀请成员')">
|
||||
<UserInput v-model="addData.userids" :uncancelable="[userId]" :multiple-max="20" :placeholder="$L('选择邀请成员')"/>
|
||||
<UserSelect v-model="addData.userids" :uncancelable="[userId]" :multiple-max="20" :title="$L('选择邀请成员')"/>
|
||||
</FormItem>
|
||||
</template>
|
||||
<FormItem prop="tracks">
|
||||
@ -103,7 +103,7 @@
|
||||
:mask-closable="false">
|
||||
<Form ref="invitationForm" :model="invitationData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="userids" :label="$L('邀请成员')">
|
||||
<UserInput v-model="invitationData.userids" :multiple-max="20" :placeholder="$L('选择邀请成员')"/>
|
||||
<UserSelect v-model="invitationData.userids" :multiple-max="20" :title="$L('选择邀请成员')"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
@ -115,14 +115,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import {Store} from "le5le-store";
|
||||
import MeetingPlayer from "./MeetingPlayer";
|
||||
import DragBallComponent from "../../../components/DragBallComponent";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "MeetingManager",
|
||||
components: {DragBallComponent, MeetingPlayer, UserInput},
|
||||
components: {UserSelect, DragBallComponent, MeetingPlayer},
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
||||
|
||||
@ -349,7 +349,7 @@
|
||||
:mask-closable="false">
|
||||
<Form :model="userData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="userids" :label="$L('项目成员')">
|
||||
<UserInput v-model="userData.userids" :uncancelable="userData.uncancelable" :multiple-max="100" :placeholder="$L('选择项目成员')"/>
|
||||
<UserSelect v-model="userData.userids" :uncancelable="userData.uncancelable" :multiple-max="100" :title="$L('选择项目成员')"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
@ -414,8 +414,8 @@
|
||||
:title="$L('移交项目')"
|
||||
:mask-closable="false">
|
||||
<Form :model="transferData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="owner_userid" :label="$L('项目负责人')">
|
||||
<UserInput v-model="transferData.owner_userid" :multiple-max="1" max-hidden-select :placeholder="$L('选择项目负责人')"/>
|
||||
<FormItem prop="owner_userid" :label="$L('新项目负责人')">
|
||||
<UserSelect v-model="transferData.owner_userid" :multiple-max="1" :title="$L('选择项目负责人')"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
@ -464,7 +464,6 @@ import Draggable from 'vuedraggable'
|
||||
import TaskPriority from "./TaskPriority";
|
||||
import {mapGetters, mapState} from "vuex";
|
||||
import {Store} from 'le5le-store';
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import TaskAddSimple from "./TaskAddSimple";
|
||||
import TaskRow from "./TaskRow";
|
||||
import TaskArchived from "./TaskArchived";
|
||||
@ -475,15 +474,17 @@ import TaskMenu from "./TaskMenu";
|
||||
import TaskDeleted from "./TaskDeleted";
|
||||
import ProjectGantt from "./ProjectGantt";
|
||||
import MarkdownPreviewNostyle from "../../../components/MDEditor/components/preview/nostyle.vue";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "ProjectPanel",
|
||||
components: {
|
||||
UserSelect,
|
||||
MarkdownPreviewNostyle,
|
||||
TaskMenu,
|
||||
ProjectWorkflow,
|
||||
DrawerOverlay,
|
||||
ProjectLog, TaskArchived, TaskRow, Draggable, TaskAddSimple, UserInput, TaskPriority, TaskDeleted, ProjectGantt},
|
||||
ProjectLog, TaskArchived, TaskRow, Draggable, TaskAddSimple, TaskPriority, TaskDeleted, ProjectGantt},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@ -1265,7 +1266,7 @@ export default {
|
||||
break;
|
||||
|
||||
case "transfer":
|
||||
this.$set(this.transferData, 'owner_userid', [this.projectData.owner_userid]);
|
||||
this.$set(this.transferData, 'owner_userid', []);
|
||||
this.transferShow = true;
|
||||
break;
|
||||
|
||||
|
||||
@ -151,7 +151,7 @@
|
||||
:mask-closable="false">
|
||||
<Form :model="userData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="userids" :label="$L('状态负责人')">
|
||||
<UserInput v-model="userData.userids" :project-id="projectId" :multiple-max="5" :placeholder="$L('选择状态负责人')"/>
|
||||
<UserSelect v-model="userData.userids" :project-id="projectId" :multiple-max="5" :title="$L('选择状态负责人')"/>
|
||||
</FormItem>
|
||||
<FormItem prop="usertype" :label="$L('流转模式')">
|
||||
<RadioGroup v-model="userData.usertype">
|
||||
@ -179,12 +179,11 @@
|
||||
|
||||
<script>
|
||||
import Draggable from "vuedraggable";
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import {mapState} from "vuex";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "ProjectWorkflow",
|
||||
components: {UserInput, Draggable},
|
||||
components: {UserSelect, Draggable},
|
||||
props: {
|
||||
projectId: {
|
||||
type: Number,
|
||||
|
||||
@ -30,11 +30,7 @@
|
||||
</FormItem>
|
||||
<FormItem :label="$L('汇报对象')">
|
||||
<div class="report-users">
|
||||
<UserInput
|
||||
v-model="reportData.receive"
|
||||
:disabledChoice="[userId]"
|
||||
:placeholder="$L('选择接收人')"
|
||||
:transfer="false"/>
|
||||
<UserSelect v-model="reportData.receive" :disabledChoice="[userId]" :title="$L('选择接收人')"/>
|
||||
<a class="report-user-link" href="javascript:void(0);" @click="getLastSubmitter">
|
||||
<Icon v-if="receiveLoad > 0" type="ios-loading" class="icon-loading"/>
|
||||
<Icon v-else type="ios-share-outline" />
|
||||
@ -52,14 +48,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserInput from "../../../components/UserInput"
|
||||
import {mapState} from "vuex";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
const TEditor = () => import('../../../components/TEditor');
|
||||
export default {
|
||||
name: "ReportEdit",
|
||||
components: {
|
||||
TEditor, UserInput
|
||||
UserSelect,
|
||||
TEditor
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
|
||||
@ -79,12 +79,13 @@
|
||||
@on-change="taskTimeChange(addData.times)"/>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('任务负责人')">
|
||||
<UserInput
|
||||
<UserSelect
|
||||
v-model="addData.owner"
|
||||
:multiple-max="10"
|
||||
:placeholder="$L('选择任务负责人')"
|
||||
:title="$L('选择任务负责人')"
|
||||
:project-id="addData.project_id"
|
||||
:transfer="false"/>
|
||||
:avatar-size="24"
|
||||
border/>
|
||||
<div v-if="showAddAssist" class="task-add-assist">
|
||||
<Checkbox v-model="addData.add_assist" :true-value="1" :false-value="0">{{$L('加入任务协助人员列表')}}</Checkbox>
|
||||
<ETooltip :disabled="$isEEUiApp || windowTouch" :content="$L('你不是任务负责人时建议加入任务协助人员列表')">
|
||||
@ -96,8 +97,8 @@
|
||||
<div v-if="addData.subtasks.length > 0" class="sublist">
|
||||
<Row>
|
||||
<Col span="12">{{$L('任务描述')}}</Col>
|
||||
<Col span="6">{{$L('计划时间')}}</Col>
|
||||
<Col span="6">{{$L('负责人')}}</Col>
|
||||
<Col span="8">{{$L('计划时间')}}</Col>
|
||||
<Col span="4">{{$L('负责人')}}</Col>
|
||||
</Row>
|
||||
<Row v-for="(item, key) in addData.subtasks" :key="key">
|
||||
<Col span="12">
|
||||
@ -107,7 +108,7 @@
|
||||
clearable
|
||||
@on-clear="addData.subtasks.splice(key, 1)"/>
|
||||
</Col>
|
||||
<Col span="6">
|
||||
<Col span="8">
|
||||
<DatePicker
|
||||
v-model="item.times"
|
||||
:options="timeOptions"
|
||||
@ -117,14 +118,14 @@
|
||||
type="datetimerange"
|
||||
@on-change="taskTimeChange(item.times)"/>
|
||||
</Col>
|
||||
<Col span="6">
|
||||
<UserInput
|
||||
<Col span="4">
|
||||
<UserSelect
|
||||
v-model="item.owner"
|
||||
:multiple-max="1"
|
||||
:placeholder="$L('选择负责人')"
|
||||
:title="$L('选择负责人')"
|
||||
:project-id="addData.project_id"
|
||||
:transfer="false"
|
||||
max-hidden-select/>
|
||||
:avatar-size="24"
|
||||
border/>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
@ -158,12 +159,12 @@
|
||||
|
||||
<script>
|
||||
import TEditor from "../../../components/TEditor";
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import {mapState} from "vuex";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "TaskAdd",
|
||||
components: {UserInput, TEditor},
|
||||
components: {UserSelect, TEditor},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
|
||||
@ -41,33 +41,15 @@
|
||||
</div>
|
||||
<Icon v-else class="clock" type="ios-clock-outline" @click="openTime" />
|
||||
</DatePicker>
|
||||
<Poptip
|
||||
ref="owner"
|
||||
<UserSelect
|
||||
class="subtask-avatar"
|
||||
popper-class="task-detail-user-popper"
|
||||
:title="$L('修改负责人')"
|
||||
:width="240"
|
||||
placement="bottom"
|
||||
@on-popper-show="openOwner"
|
||||
@on-ok="onOwner"
|
||||
transfer>
|
||||
<div slot="content">
|
||||
<UserInput
|
||||
v-model="ownerData.owner_userid"
|
||||
:multiple-max="10"
|
||||
:avatar-size="20"
|
||||
:title="$L('修改负责人')"
|
||||
:add-icon="false"
|
||||
:project-id="taskDetail.project_id"
|
||||
:placeholder="$L('选择任务负责人')"
|
||||
:transfer="false"
|
||||
max-hidden-select/>
|
||||
<div class="task-detail-avatar-buttons">
|
||||
<Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="getOwner.length > 0">
|
||||
<UserAvatar v-for="item in getOwner" :key="item.userid" :userid="item.userid" :size="20" tooltipDisabled/>
|
||||
</template>
|
||||
<div v-else>--</div>
|
||||
</Poptip>
|
||||
:before-submit="onOwner"/>
|
||||
</li>
|
||||
<!--主任务-->
|
||||
<div
|
||||
@ -191,63 +173,29 @@
|
||||
<div class="item-label" slot="label">
|
||||
<i class="taskfont"></i>{{$L('负责人')}}
|
||||
</div>
|
||||
<Poptip
|
||||
ref="owner"
|
||||
:title="$L('修改负责人')"
|
||||
:width="240"
|
||||
<UserSelect
|
||||
class="item-content user"
|
||||
popper-class="task-detail-user-popper"
|
||||
placement="bottom"
|
||||
@on-popper-show="openOwner"
|
||||
@on-ok="onOwner"
|
||||
transfer>
|
||||
<div slot="content">
|
||||
<UserInput
|
||||
v-model="ownerData.owner_userid"
|
||||
:multiple-max="10"
|
||||
:avatar-size="28"
|
||||
:title="$L('修改负责人')"
|
||||
:project-id="taskDetail.project_id"
|
||||
:placeholder="$L('选择任务负责人')"
|
||||
:transfer="false"/>
|
||||
<div class="task-detail-avatar-buttons">
|
||||
<Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-list">
|
||||
<UserAvatar v-for="item in getOwner" :key="item.userid" :userid="item.userid" :size="28" :showName="getOwner.length === 1" tooltipDisabled/>
|
||||
</div>
|
||||
</Poptip>
|
||||
:before-submit="onOwner"/>
|
||||
</FormItem>
|
||||
<FormItem v-if="getAssist.length > 0 || assistForce">
|
||||
<div class="item-label" slot="label">
|
||||
<i class="taskfont"></i>{{$L('协助人员')}}
|
||||
</div>
|
||||
<Poptip
|
||||
<UserSelect
|
||||
ref="assist"
|
||||
:title="$L(getAssist.length > 0 ? '修改协助人员' : '添加协助人员')"
|
||||
:width="280"
|
||||
class="item-content user"
|
||||
popper-class="task-detail-user-popper"
|
||||
placement="bottom"
|
||||
@on-popper-show="openAssist"
|
||||
@on-ok="onAssist"
|
||||
transfer>
|
||||
<div slot="content">
|
||||
<UserInput
|
||||
v-model="assistData.assist_userid"
|
||||
:multiple-max="10"
|
||||
:avatar-size="28"
|
||||
:title="$L(getAssist.length > 0 ? '修改协助人员' : '添加协助人员')"
|
||||
:project-id="taskDetail.project_id"
|
||||
:disabled-choice="assistData.disabled"
|
||||
:placeholder="$L('选择任务协助人员')"
|
||||
:transfer="false"/>
|
||||
<div class="task-detail-avatar-buttons">
|
||||
<Button size="small" type="primary" @click="$refs.assist.ok()">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="getAssist.length > 0" class="user-list">
|
||||
<UserAvatar v-for="item in getAssist" :key="item.userid" :userid="item.userid" :size="28" :showName="getAssist.length === 1" tooltipDisabled/>
|
||||
</div>
|
||||
<div v-else>--</div>
|
||||
</Poptip>
|
||||
:before-submit="onAssist"/>
|
||||
</FormItem>
|
||||
<FormItem v-if="taskDetail.end_at || timeForce">
|
||||
<div class="item-label" slot="label">
|
||||
@ -460,17 +408,19 @@
|
||||
import {mapState} from "vuex";
|
||||
import TEditor from "../../../components/TEditor";
|
||||
import TaskPriority from "./TaskPriority";
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import TaskUpload from "./TaskUpload";
|
||||
import DialogWrapper from "./DialogWrapper";
|
||||
import ProjectLog from "./ProjectLog";
|
||||
import {Store} from "le5le-store";
|
||||
import TaskMenu from "./TaskMenu";
|
||||
import ChatInput from "./ChatInput";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "TaskDetail",
|
||||
components: {ChatInput, TaskMenu, ProjectLog, DialogWrapper, TaskUpload, UserInput, TaskPriority, TEditor},
|
||||
components: {
|
||||
UserSelect,
|
||||
ChatInput, TaskMenu, ProjectLog, DialogWrapper, TaskUpload, TaskPriority, TEditor},
|
||||
props: {
|
||||
taskId: {
|
||||
type: Number,
|
||||
@ -819,13 +769,28 @@ export default {
|
||||
this.assistForce = false;
|
||||
this.addsubForce = false;
|
||||
this.receiveShow = false;
|
||||
this.$refs.owner && this.$refs.owner.handleClose();
|
||||
this.$refs.assist && this.$refs.assist.handleClose();
|
||||
this.$refs.chatInput && this.$refs.chatInput.hidePopover();
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
getOwner: {
|
||||
handler(arr) {
|
||||
const list = arr.map(({userid}) => userid)
|
||||
this.$set(this.taskDetail, 'owner_userid', list)
|
||||
this.$set(this.ownerData, 'owner_userid', list)
|
||||
this.$set(this.assistData, 'disabled', arr.map(({userid}) => userid).filter(userid => userid != this.userId))
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
getAssist: {
|
||||
handler(arr) {
|
||||
const list = arr.map(({userid}) => userid)
|
||||
this.$set(this.taskDetail, 'assist_userid', list)
|
||||
this.$set(this.assistData, 'assist_userid', list);
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
receiveShow(val) {
|
||||
if (val) {
|
||||
this.timeValue = this.taskDetail.end_at ? [this.taskDetail.start_at, this.taskDetail.end_at] : [];
|
||||
@ -1026,12 +991,6 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
openOwner() {
|
||||
const list = this.getOwner.map(({userid}) => userid)
|
||||
this.$set(this.taskDetail, 'owner_userid', list)
|
||||
this.$set(this.ownerData, 'owner_userid', list)
|
||||
},
|
||||
|
||||
onOwner(pick) {
|
||||
let data = {
|
||||
task_id: this.taskDetail.id,
|
||||
@ -1059,47 +1018,52 @@ export default {
|
||||
if ($A.jsonStringify(this.taskDetail.owner_userid) === $A.jsonStringify(this.ownerData.owner_userid)) {
|
||||
return;
|
||||
}
|
||||
if ($A.count(data.owner) == 0) {
|
||||
data.owner = '';
|
||||
}
|
||||
//
|
||||
if ($A.count(data.owner) == 0) data.owner = '';
|
||||
this.ownerLoad++;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$store.dispatch("taskUpdate", data).then(({msg}) => {
|
||||
$A.messageSuccess(msg);
|
||||
this.ownerLoad--;
|
||||
this.receiveShow = false;
|
||||
this.$store.dispatch("getTaskOne", this.taskDetail.id).catch(() => {})
|
||||
resolve()
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg);
|
||||
this.ownerLoad--;
|
||||
this.receiveShow = false;
|
||||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
openAssist() {
|
||||
const list = this.getAssist.map(({userid}) => userid)
|
||||
this.$set(this.taskDetail, 'assist_userid', list)
|
||||
this.$set(this.assistData, 'assist_userid', list);
|
||||
this.$set(this.assistData, 'disabled', this.getOwner.map(({userid}) => userid).filter(userid => userid != this.userId))
|
||||
},
|
||||
|
||||
onAssist() {
|
||||
if ($A.jsonStringify(this.taskDetail.assist_userid) === $A.jsonStringify(this.assistData.assist_userid)) {
|
||||
return;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.getOwner.find(({userid}) => userid === this.userId) && this.assistData.assist_userid.find(userid => userid === this.userId)) {
|
||||
$A.modalConfirm({
|
||||
content: '你当前是负责人,确定要转为协助人员吗?',
|
||||
cancelText: '取消',
|
||||
okText: '确定',
|
||||
onOk: () => {
|
||||
this.onAssistConfirm()
|
||||
this.onAssistConfirm().then(resolve).catch(reject)
|
||||
},
|
||||
onCancel: () => {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
return
|
||||
} else {
|
||||
this.onAssistConfirm().then(resolve).catch(reject)
|
||||
}
|
||||
this.onAssistConfirm()
|
||||
})
|
||||
},
|
||||
|
||||
onAssistConfirm() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let assist = this.assistData.assist_userid;
|
||||
if (assist.length === 0) assist = false;
|
||||
this.assistLoad++;
|
||||
@ -1110,9 +1074,12 @@ export default {
|
||||
$A.messageSuccess(msg);
|
||||
this.assistLoad--;
|
||||
this.$store.dispatch("getTaskOne", this.taskDetail.id).catch(() => {})
|
||||
resolve()
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg);
|
||||
this.assistLoad--;
|
||||
reject()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
@ -1215,9 +1182,8 @@ export default {
|
||||
|
||||
case 'assist':
|
||||
this.assistForce = true;
|
||||
this.openAssist();
|
||||
this.$nextTick(() => {
|
||||
this.$refs.assist.handleClick();
|
||||
this.$refs.assist.onSelect();
|
||||
});
|
||||
break;
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
:mask-closable="false">
|
||||
<Form ref="exportTask" :model="formData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem :label="$L('导出成员')">
|
||||
<UserInput v-model="formData.userid" :multiple-max="100" show-disable :placeholder="$L('请选择成员')"/>
|
||||
<UserSelect v-model="formData.userid" :multiple-max="100" avatar-name show-disable :title="$L('请选择成员')"/>
|
||||
<div class="form-tip">{{$L('每次最多选择导出100个成员')}}</div>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('时间范围')">
|
||||
@ -52,10 +52,10 @@
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
export default {
|
||||
name: "TaskExport",
|
||||
components: {UserInput},
|
||||
components: {UserSelect},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
|
||||
@ -172,7 +172,7 @@
|
||||
<div v-if="departmentParentDisabled" class="form-tip" style="margin-bottom:-16px">{{$L('含有子部门无法修改上级部门')}}</div>
|
||||
</FormItem>
|
||||
<FormItem prop="owner_userid" :label="$L('部门负责人')">
|
||||
<UserInput v-model="departmentData.owner_userid" :multiple-max="1" max-hidden-select :placeholder="$L('请选择部门负责人')"/>
|
||||
<UserSelect v-model="departmentData.owner_userid" :multiple-max="1" :title="$L('请选择部门负责人')"/>
|
||||
</FormItem>
|
||||
<template v-if="departmentData.id == 0">
|
||||
<Divider orientation="left">{{$L('群组设置')}}</Divider>
|
||||
@ -273,7 +273,7 @@
|
||||
type="datetime"/>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('交接人')">
|
||||
<UserInput v-model="disableData.transfer_userid" :disabled-choice="[disableData.userid]" :multiple-max="1" max-hidden-select :placeholder="$L('选择交接人')"/>
|
||||
<UserSelect v-model="disableData.transfer_userid" :disabled-choice="[disableData.userid]" :multiple-max="1" :title="$L('选择交接人')"/>
|
||||
<div class="form-tip">{{ $L(`${disableData.nickname} 负责的部门、项目、任务和文件将移交给交接人;同时退出所有群(如果是群主则转让给交接人)`) }}</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
@ -298,11 +298,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import UserSelect from "../../../components/UserSelect.vue";
|
||||
|
||||
export default {
|
||||
name: "TeamManagement",
|
||||
components: {UserInput},
|
||||
components: {UserSelect},
|
||||
props: {
|
||||
checkinMac: {
|
||||
type: Boolean,
|
||||
|
||||
@ -278,19 +278,19 @@
|
||||
footer-hide>
|
||||
<Form class="page-file-share-form" :model="shareInfo" @submit.native.prevent inline>
|
||||
<FormItem prop="userids" class="share-userid">
|
||||
<UserInput
|
||||
<RadioGroup v-model="shareInfo.type">
|
||||
<Radio label="all">{{$L('所有人')}}</Radio>
|
||||
<Radio label="custom">{{$L('指定成员')}}</Radio>
|
||||
</RadioGroup>
|
||||
<UserSelect
|
||||
v-if="shareInfo.type === 'custom'"
|
||||
v-model="shareInfo.userids"
|
||||
:disabledChoice="shareAlready"
|
||||
:multiple-max="100"
|
||||
:placeholder="$L('选择共享成员')">
|
||||
<Option slot="option-prepend" :value="0" :label="$L('所有人')" :disabled="shareAlready.includes(0)">
|
||||
<div class="user-input-option">
|
||||
<div class="user-input-avatar"><EAvatar class="avatar" icon="el-icon-s-custom"/></div>
|
||||
<div class="user-input-nickname">{{ $L('所有人') }}</div>
|
||||
<div class="user-input-userid">All</div>
|
||||
</div>
|
||||
</Option>
|
||||
</UserInput>
|
||||
:placeholder="$L('选择共享成员')"
|
||||
:avatar-size="24"
|
||||
border>
|
||||
</UserSelect>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Select v-model="shareInfo.permission" :placeholder="$L('权限')">
|
||||
@ -302,7 +302,7 @@
|
||||
<Button type="primary" :loading="shareLoad > 0" @click="onShare">{{$L('共享')}}</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div v-if="shareList.length > 0">
|
||||
<div v-if="shareList.length > 0" class="page-file-share-items">
|
||||
<div class="page-file-share-title">{{ $L('已共享成员') }}:</div>
|
||||
<ul class="page-file-share-list">
|
||||
<li v-for="item in shareList">
|
||||
@ -398,18 +398,18 @@
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
import {sortBy} from "lodash";
|
||||
import UserInput from "../../components/UserInput";
|
||||
import DrawerOverlay from "../../components/DrawerOverlay";
|
||||
import PreviewImage from "../../components/PreviewImage";
|
||||
import longpress from "../../directives/longpress";
|
||||
import DialogSelect from "./components/DialogSelect";
|
||||
import UserSelect from "../../components/UserSelect.vue";
|
||||
|
||||
const FilePreview = () => import('./components/FilePreview');
|
||||
const FileContent = () => import('./components/FileContent');
|
||||
const FileObject = {sort: null, mode: null, shared: null};
|
||||
|
||||
export default {
|
||||
components: {DialogSelect, PreviewImage, FilePreview, DrawerOverlay, UserInput, FileContent},
|
||||
components: {UserSelect, DialogSelect, PreviewImage, FilePreview, DrawerOverlay, FileContent},
|
||||
directives: {longpress},
|
||||
data() {
|
||||
return {
|
||||
@ -473,7 +473,7 @@ export default {
|
||||
columns: [],
|
||||
|
||||
shareShow: false,
|
||||
shareInfo: {id: 0, userid: 0, permission: 1},
|
||||
shareInfo: {id: 0, type: 'all', userid: 0, permission: 1},
|
||||
shareList: [],
|
||||
shareLoad: 0,
|
||||
|
||||
@ -1208,6 +1208,7 @@ export default {
|
||||
case 'share':
|
||||
this.shareInfo = {
|
||||
id: item.id,
|
||||
type: 'all',
|
||||
userid: item.userid,
|
||||
permission: 1,
|
||||
};
|
||||
@ -1538,6 +1539,9 @@ export default {
|
||||
},
|
||||
|
||||
onShare(force = false) {
|
||||
if (this.shareInfo.type === 'all') {
|
||||
this.shareInfo.userids = [0];
|
||||
}
|
||||
if (this.shareInfo.userids.length == 0) {
|
||||
$A.messageWarning("请选择共享成员")
|
||||
return;
|
||||
|
||||
2
resources/assets/sass/components/_.scss
vendored
2
resources/assets/sass/components/_.scss
vendored
@ -11,7 +11,7 @@
|
||||
@import "quick-edit";
|
||||
@import "tag-input";
|
||||
@import "user-avatar";
|
||||
@import "user-input";
|
||||
@import "user-select";
|
||||
@import "report";
|
||||
@import "resize-line";
|
||||
@import "right-bottom";
|
||||
|
||||
3
resources/assets/sass/components/report.scss
vendored
3
resources/assets/sass/components/report.scss
vendored
@ -168,8 +168,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.common-user {
|
||||
flex: 1;
|
||||
.common-user-select {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
|
||||
99
resources/assets/sass/components/user-input.scss
vendored
99
resources/assets/sass/components/user-input.scss
vendored
@ -1,99 +0,0 @@
|
||||
.common-user {
|
||||
position: relative;
|
||||
white-space: normal;
|
||||
.common-user-loading {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
bottom: 0;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.common-loading {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
&.hidden-input {
|
||||
.ivu-select-selection {
|
||||
padding: 0 4px;
|
||||
.ivu-select-input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.common-user-transfer {
|
||||
.user-input-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.user-input-avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.avatar {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
}
|
||||
.user-input-bot {
|
||||
font-size: 16px;
|
||||
margin-left: 10px;
|
||||
margin-right: -6px;
|
||||
color: $primary-color;
|
||||
}
|
||||
.user-input-disable {
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
margin-right: -6px;
|
||||
color: #ff0000;
|
||||
}
|
||||
.user-input-nickname {
|
||||
margin-left: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
.user-input-userid {
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
color: #cccccc;
|
||||
transition: margin 0.1s;
|
||||
}
|
||||
}
|
||||
.ivu-select-item {
|
||||
&.ivu-select-item-selected {
|
||||
&:after {
|
||||
top: 8px;
|
||||
}
|
||||
.user-input-option {
|
||||
.user-input-userid {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-drop-prepend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
transform: translateY(-5px);
|
||||
background-color: #ffffff;
|
||||
padding: 5px 15px;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
.user-drop-text {
|
||||
flex: 1;
|
||||
color: #c5c8ce;
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.user-drop-check {
|
||||
margin-right: 0;
|
||||
transform: scale(0.9);
|
||||
transform-origin: right center;
|
||||
}
|
||||
}
|
||||
}
|
||||
153
resources/assets/sass/components/user-select.scss
vendored
Executable file
153
resources/assets/sass/components/user-select.scss
vendored
Executable file
@ -0,0 +1,153 @@
|
||||
.common-user-select {
|
||||
&.select-border {
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
> ul {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
> li {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 3px 6px 3px 0;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
&.add-icon {
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
background: #F2F3F5 url("data:image/svg+xml;base64,PHN2ZyB0PSIxNjg2NjIxNjA3NDE0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04NzQuNjY2NjY3IDQ3My42aC0zMjQuMjY2NjY3VjE0OS4zMzMzMzNjMC0yMS4zMzMzMzMtMTcuMDY2NjY3LTM4LjQtMzguNC0zOC40cy0zOC40IDE3LjA2NjY2Ny0zOC40IDM4LjR2MzI0LjI2NjY2N0gxNDkuMzMzMzMzYy0yMS4zMzMzMzMgMC0zOC40IDE3LjA2NjY2Ny0zOC40IDM4LjRzMTcuMDY2NjY3IDM4LjQgMzguNCAzOC40aDMyNC4yNjY2Njd2MzI0LjI2NjY2N2MwIDIxLjMzMzMzMyAxNy4wNjY2NjcgMzguNCAzOC40IDM4LjRzMzguNC0xNy4wNjY2NjcgMzguNC0zOC40di0zMjQuMjY2NjY3aDMyNC4yNjY2NjdjMjEuMzMzMzMzIDAgMzguNC0xNy4wNjY2NjcgMzguNC0zOC40cy0xNy4wNjY2NjctMzguNC0zOC40LTM4LjR6IiAgZmlsbD0iIzYwNjI2NiI+PC9wYXRoPjwvc3ZnPg==") no-repeat center;
|
||||
background-size: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.common-user-select-modal {
|
||||
.ivu-modal-body {
|
||||
padding: 0 16px !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.user-modal-search {
|
||||
flex-shrink: 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 9;
|
||||
padding: 8px 16px;
|
||||
background: #ffffff;
|
||||
.search-pre {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.common-loading {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-modal-list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 400px;
|
||||
ul {
|
||||
padding: 8px 0;
|
||||
> li {
|
||||
list-style: none;
|
||||
padding: 8px 16px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
&.selected {
|
||||
.user-modal-icon {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
&.disabled,
|
||||
&.disabled:hover {
|
||||
color: #c5c8ce;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.user-modal-icon {
|
||||
flex-shrink: 0;
|
||||
font-size: 24px;
|
||||
margin-right: 10px;
|
||||
color: rgba($primary-desc-color, 0.7);
|
||||
}
|
||||
.user-modal-avatar {
|
||||
flex: 1;
|
||||
.avatar-name {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.user-modal-userid {
|
||||
flex-shrink: 0;
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
color: #cccccc;
|
||||
transition: margin 0.1s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-modal-multiple {
|
||||
flex-shrink: 0;
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 9;
|
||||
padding: 6px 16px 0;
|
||||
background: #ffffff;
|
||||
color: $primary-desc-color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.multiple-check {
|
||||
margin-left: 4px;
|
||||
}
|
||||
.multiple-text {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
padding-left: 6px;
|
||||
> em {
|
||||
padding-left: 2px;
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.ivu-modal-fullscreen {
|
||||
.ivu-modal-content {
|
||||
margin-top: 46px;
|
||||
border-top-left-radius: 18px !important;
|
||||
border-top-right-radius: 18px !important;
|
||||
.ivu-modal-body {
|
||||
bottom: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 576px) {
|
||||
.common-user-select-modal {
|
||||
.ivu-modal-body {
|
||||
.user-modal-list {
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -245,13 +245,6 @@
|
||||
&.user {
|
||||
margin-top: 1px;
|
||||
cursor: pointer;
|
||||
.user-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> div {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.file {
|
||||
margin-bottom: -3px;
|
||||
@ -422,15 +415,6 @@
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.subtask-avatar {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.avatar-wrapper {
|
||||
margin-top: 3px;
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
}
|
||||
.ivu-icon-ios-loading {
|
||||
animation: animation-icon-loading 0.6s infinite linear;
|
||||
}
|
||||
@ -832,25 +816,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.task-detail-user-popper {
|
||||
.ivu-poptip-body-content {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.task-detail-avatar-buttons {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 4px;
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 14px;
|
||||
> button {
|
||||
font-size: 12px;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
}
|
||||
|
||||
.task-detail-loop {
|
||||
> li {
|
||||
text-align: center;
|
||||
|
||||
10
resources/assets/sass/pages/page-file.scss
vendored
10
resources/assets/sass/pages/page-file.scss
vendored
@ -634,9 +634,13 @@
|
||||
|
||||
.page-file-share-form {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 12px;
|
||||
.share-userid {
|
||||
flex: 1;
|
||||
.common-user-select {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
> div {
|
||||
flex-shrink: 0;
|
||||
@ -646,6 +650,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.page-file-share-items {
|
||||
border-top: 1px solid #eee;
|
||||
margin-top: -12px;
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.page-file-share-title {
|
||||
margin-top: -8px;
|
||||
margin-bottom: 14px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user