no message
This commit is contained in:
parent
489804ca80
commit
d95220763a
@ -26,7 +26,9 @@
|
|||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
"vue-loader": "^15.9.7",
|
"vue-loader": "^15.9.7",
|
||||||
"vue-router": "^3.4.2",
|
"vue-router": "^3.4.2",
|
||||||
"vue-template-compiler": "^2.6.11"
|
"vue-template-compiler": "^2.6.11",
|
||||||
|
"webpack": "^5.38.1",
|
||||||
|
"webpack-cli": "^4.7.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"echarts": "^5.1.1",
|
"echarts": "^5.1.1",
|
||||||
|
396
resources/assets/js/components/DragInput.vue
Normal file
396
resources/assets/js/components/DragInput.vue
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="wrapClasses">
|
||||||
|
<template v-if="type !== 'textarea'">
|
||||||
|
<div :class="[prefixCls + '-group-prepend']" v-if="prepend" v-show="slotReady"><slot name="prepend"></slot></div>
|
||||||
|
<i class="ivu-icon" :class="['ivu-icon-ios-close-circle', prefixCls + '-icon', prefixCls + '-icon-clear' , prefixCls + '-icon-normal']" v-if="clearable && currentValue && !itemDisabled" @click="handleClear"></i>
|
||||||
|
<i class="ivu-icon" :class="['ivu-icon-' + icon, prefixCls + '-icon', prefixCls + '-icon-normal']" v-else-if="icon" @click="handleIconClick"></i>
|
||||||
|
<i class="ivu-icon ivu-icon-ios-search" :class="[prefixCls + '-icon', prefixCls + '-icon-normal', prefixCls + '-search-icon']" v-else-if="search && enterButton === false" @click="handleSearch"></i>
|
||||||
|
<span class="ivu-input-suffix" v-else-if="showSuffix"><slot name="suffix"><i class="ivu-icon" :class="['ivu-icon-' + suffix]" v-if="suffix"></i></slot></span>
|
||||||
|
<span class="ivu-input-word-count" v-else-if="showWordLimit">{{ textLength }}/{{ upperLimit }}</span>
|
||||||
|
<span class="ivu-input-suffix" v-else-if="password" @click="handleToggleShowPassword">
|
||||||
|
<i class="ivu-icon ivu-icon-ios-eye-off-outline" v-if="showPassword"></i>
|
||||||
|
<i class="ivu-icon ivu-icon-ios-eye-outline" v-else></i>
|
||||||
|
</span>
|
||||||
|
<transition name="fade">
|
||||||
|
<i class="ivu-icon ivu-icon-ios-loading ivu-load-loop" :class="[prefixCls + '-icon', prefixCls + '-icon-validate']" v-if="!icon"></i>
|
||||||
|
</transition>
|
||||||
|
<input
|
||||||
|
:id="elementId"
|
||||||
|
:autocomplete="autocomplete"
|
||||||
|
:spellcheck="spellcheck"
|
||||||
|
ref="input"
|
||||||
|
:type="currentType"
|
||||||
|
:class="inputClasses"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:disabled="itemDisabled"
|
||||||
|
:maxlength="maxlength"
|
||||||
|
:readonly="readonly"
|
||||||
|
:name="name"
|
||||||
|
:value="currentValue"
|
||||||
|
:number="number"
|
||||||
|
:autofocus="autofocus"
|
||||||
|
@keyup.enter="handleEnter"
|
||||||
|
@keyup="handleKeyup"
|
||||||
|
@keypress="handleKeypress"
|
||||||
|
@keydown="handleKeydown"
|
||||||
|
@focus="handleFocus"
|
||||||
|
@blur="handleBlur"
|
||||||
|
@compositionstart="handleComposition"
|
||||||
|
@compositionupdate="handleComposition"
|
||||||
|
@compositionend="handleComposition"
|
||||||
|
@input="handleInput"
|
||||||
|
@change="handleChange"
|
||||||
|
@paste="handlePaste">
|
||||||
|
<div :class="[prefixCls + '-group-append']" v-if="append" v-show="slotReady"><slot name="append"></slot></div>
|
||||||
|
<div :class="[prefixCls + '-group-append', prefixCls + '-search']" v-else-if="search && enterButton" @click="handleSearch">
|
||||||
|
<i class="ivu-icon ivu-icon-ios-search" v-if="enterButton === true"></i>
|
||||||
|
<template v-else>{{ enterButton }}</template>
|
||||||
|
</div>
|
||||||
|
<span class="ivu-input-prefix" v-else-if="showPrefix"><slot name="prefix"><i class="ivu-icon" :class="['ivu-icon-' + prefix]" v-if="prefix"></i></slot></span>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<textarea
|
||||||
|
:id="elementId"
|
||||||
|
:wrap="wrap"
|
||||||
|
:autocomplete="autocomplete"
|
||||||
|
:spellcheck="spellcheck"
|
||||||
|
ref="textarea"
|
||||||
|
:class="textareaClasses"
|
||||||
|
:style="textareaStyles"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:disabled="itemDisabled"
|
||||||
|
:rows="rows"
|
||||||
|
:maxlength="maxlength"
|
||||||
|
:readonly="readonly"
|
||||||
|
:name="name"
|
||||||
|
:value="currentValue"
|
||||||
|
:autofocus="autofocus"
|
||||||
|
@keyup.enter="handleEnter"
|
||||||
|
@keyup="handleKeyup"
|
||||||
|
@keypress="handleKeypress"
|
||||||
|
@keydown="handleKeydown"
|
||||||
|
@focus="handleFocus"
|
||||||
|
@blur="handleBlur"
|
||||||
|
@compositionstart="handleComposition"
|
||||||
|
@compositionupdate="handleComposition"
|
||||||
|
@compositionend="handleComposition"
|
||||||
|
@input="handleInput"
|
||||||
|
@paste="handlePaste">
|
||||||
|
</textarea>
|
||||||
|
<span class="ivu-input-word-count" v-if="showWordLimit">{{ textLength }}/{{ upperLimit }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { oneOf, findComponentUpward } from 'view-design-hi/src/utils/assist';
|
||||||
|
import calcTextareaHeight from 'view-design-hi/src/utils/calcTextareaHeight';
|
||||||
|
import Emitter from 'view-design-hi/src/mixins/emitter';
|
||||||
|
import mixinsForm from 'view-design-hi/src/mixins/form';
|
||||||
|
|
||||||
|
const prefixCls = 'ivu-input';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DragInput',
|
||||||
|
mixins: [ Emitter, mixinsForm ],
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
validator (value) {
|
||||||
|
return oneOf(value, ['text', 'textarea', 'password', 'url', 'email', 'date', 'number', 'tel']);
|
||||||
|
},
|
||||||
|
default: 'text'
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
validator (value) {
|
||||||
|
return oneOf(value, ['small', 'large', 'default']);
|
||||||
|
},
|
||||||
|
default () {
|
||||||
|
return !this.$IVIEW || this.$IVIEW.size === '' ? 'default' : this.$IVIEW.size;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
maxlength: {
|
||||||
|
type: [String, Number]
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
icon: String,
|
||||||
|
autosize: {
|
||||||
|
type: [Boolean, Object],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
rows: {
|
||||||
|
type: Number,
|
||||||
|
default: 2
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
autofocus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
spellcheck: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
autocomplete: {
|
||||||
|
type: String,
|
||||||
|
default: 'off'
|
||||||
|
},
|
||||||
|
clearable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
elementId: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
wrap: {
|
||||||
|
validator (value) {
|
||||||
|
return oneOf(value, ['hard', 'soft']);
|
||||||
|
},
|
||||||
|
default: 'soft'
|
||||||
|
},
|
||||||
|
prefix: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
suffix: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
enterButton: {
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 4.0.0
|
||||||
|
showWordLimit: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 4.0.0
|
||||||
|
password: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
currentValue: this.value,
|
||||||
|
prefixCls: prefixCls,
|
||||||
|
slotReady: false,
|
||||||
|
textareaStyles: {},
|
||||||
|
isOnComposition: false,
|
||||||
|
showPassword: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentType () {
|
||||||
|
let type = this.type;
|
||||||
|
if (type === 'password' && this.password && this.showPassword) type = 'text';
|
||||||
|
return type;
|
||||||
|
},
|
||||||
|
prepend () {
|
||||||
|
let state = false;
|
||||||
|
if (this.type !== 'textarea') state = this.$slots.prepend !== undefined;
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
append () {
|
||||||
|
let state = false;
|
||||||
|
if (this.type !== 'textarea') state = this.$slots.append !== undefined;
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
showPrefix () {
|
||||||
|
let state = false;
|
||||||
|
if (this.type !== 'textarea') state = this.prefix !== '' || this.$slots.prefix !== undefined;
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
showSuffix () {
|
||||||
|
let state = false;
|
||||||
|
if (this.type !== 'textarea') state = this.suffix !== '' || this.$slots.suffix !== undefined;
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
wrapClasses () {
|
||||||
|
return [
|
||||||
|
`${prefixCls}-wrapper`,
|
||||||
|
{
|
||||||
|
[`${prefixCls}-wrapper-${this.size}`]: !!this.size,
|
||||||
|
[`${prefixCls}-type-${this.type}`]: this.type,
|
||||||
|
[`${prefixCls}-group`]: this.prepend || this.append || (this.search && this.enterButton),
|
||||||
|
[`${prefixCls}-group-${this.size}`]: (this.prepend || this.append || (this.search && this.enterButton)) && !!this.size,
|
||||||
|
[`${prefixCls}-group-with-prepend`]: this.prepend,
|
||||||
|
[`${prefixCls}-group-with-append`]: this.append || (this.search && this.enterButton),
|
||||||
|
[`${prefixCls}-hide-icon`]: this.append, // #554
|
||||||
|
[`${prefixCls}-with-search`]: (this.search && this.enterButton)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
},
|
||||||
|
inputClasses () {
|
||||||
|
return [
|
||||||
|
`${prefixCls}`,
|
||||||
|
{
|
||||||
|
[`${prefixCls}-${this.size}`]: !!this.size,
|
||||||
|
[`${prefixCls}-disabled`]: this.itemDisabled,
|
||||||
|
[`${prefixCls}-with-prefix`]: this.showPrefix,
|
||||||
|
[`${prefixCls}-with-suffix`]: this.showSuffix || (this.search && this.enterButton === false)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
},
|
||||||
|
textareaClasses () {
|
||||||
|
return [
|
||||||
|
`${prefixCls}`,
|
||||||
|
{
|
||||||
|
[`${prefixCls}-disabled`]: this.itemDisabled
|
||||||
|
}
|
||||||
|
];
|
||||||
|
},
|
||||||
|
upperLimit () {
|
||||||
|
return this.maxlength;
|
||||||
|
},
|
||||||
|
textLength () {
|
||||||
|
if (typeof this.value === 'number') {
|
||||||
|
return String(this.value).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (this.value || '').length;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleEnter (event) {
|
||||||
|
this.$emit('on-enter', event);
|
||||||
|
if (this.search) this.$emit('on-search', this.currentValue);
|
||||||
|
},
|
||||||
|
handleKeydown (event) {
|
||||||
|
this.$emit('on-keydown', event);
|
||||||
|
},
|
||||||
|
handleKeypress(event) {
|
||||||
|
this.$emit('on-keypress', event);
|
||||||
|
},
|
||||||
|
handleKeyup (event) {
|
||||||
|
this.$emit('on-keyup', event);
|
||||||
|
},
|
||||||
|
handleIconClick (event) {
|
||||||
|
this.$emit('on-click', event);
|
||||||
|
},
|
||||||
|
handleFocus (event) {
|
||||||
|
this.$emit('on-focus', event);
|
||||||
|
},
|
||||||
|
handleBlur (event) {
|
||||||
|
this.$emit('on-blur', event);
|
||||||
|
if (!findComponentUpward(this, ['DatePicker', 'TimePicker', 'Cascader', 'Search'])) {
|
||||||
|
this.dispatch('FormItem', 'on-form-blur', this.currentValue);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleComposition(event) {
|
||||||
|
if (event.type === 'compositionstart') {
|
||||||
|
this.isOnComposition = true;
|
||||||
|
}
|
||||||
|
if (event.type === 'compositionend') {
|
||||||
|
this.isOnComposition = false;
|
||||||
|
this.handleInput(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleInput (event) {
|
||||||
|
if (this.isOnComposition) return;
|
||||||
|
|
||||||
|
let value = event.target.value;
|
||||||
|
if (this.number && value !== '') value = Number.isNaN(Number(value)) ? value : Number(value);
|
||||||
|
this.$emit('input', value);
|
||||||
|
this.setCurrentValue(value);
|
||||||
|
this.$emit('on-change', event);
|
||||||
|
},
|
||||||
|
handleChange (event) {
|
||||||
|
this.$emit('on-input-change', event);
|
||||||
|
},
|
||||||
|
handlePaste (event) {
|
||||||
|
this.$emit('on-input-paste', event);
|
||||||
|
},
|
||||||
|
setCurrentValue (value) {
|
||||||
|
if (value === this.currentValue) return;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.resizeTextarea();
|
||||||
|
});
|
||||||
|
this.currentValue = value;
|
||||||
|
if (!findComponentUpward(this, ['DatePicker', 'TimePicker', 'Cascader', 'Search'])) {
|
||||||
|
this.dispatch('FormItem', 'on-form-change', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resizeTextarea () {
|
||||||
|
const autosize = this.autosize;
|
||||||
|
if (!autosize || this.type !== 'textarea') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const minRows = autosize.minRows;
|
||||||
|
const maxRows = autosize.maxRows;
|
||||||
|
|
||||||
|
this.textareaStyles = calcTextareaHeight(this.$refs.textarea, minRows, maxRows);
|
||||||
|
},
|
||||||
|
focus () {
|
||||||
|
if (this.type === 'textarea') {
|
||||||
|
this.$refs.textarea.focus();
|
||||||
|
} else {
|
||||||
|
this.$refs.input.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
blur () {
|
||||||
|
if (this.type === 'textarea') {
|
||||||
|
this.$refs.textarea.blur();
|
||||||
|
} else {
|
||||||
|
this.$refs.input.blur();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleClear () {
|
||||||
|
const e = { target: { value: '' } };
|
||||||
|
this.$emit('input', '');
|
||||||
|
this.setCurrentValue('');
|
||||||
|
this.$emit('on-change', e);
|
||||||
|
this.$emit('on-clear');
|
||||||
|
},
|
||||||
|
handleSearch () {
|
||||||
|
if (this.itemDisabled) return false;
|
||||||
|
this.$refs.input.focus();
|
||||||
|
this.$emit('on-search', this.currentValue);
|
||||||
|
},
|
||||||
|
handleToggleShowPassword () {
|
||||||
|
if (this.itemDisabled) return false;
|
||||||
|
this.showPassword = !this.showPassword;
|
||||||
|
this.focus();
|
||||||
|
const len = this.currentValue.length;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$refs.input.setSelectionRange(len, len);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value (val) {
|
||||||
|
this.setCurrentValue(val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.slotReady = true;
|
||||||
|
this.resizeTextarea();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
97
resources/assets/js/components/ScrollerY.vue
Normal file
97
resources/assets/js/components/ScrollerY.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="scrollerView" class="app-scroller" :class="[static ? 'app-scroller-static' : '']">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.app-scroller {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-scroller-static {
|
||||||
|
position: static;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ScrollerY',
|
||||||
|
props: {
|
||||||
|
static: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
scrollY: 0,
|
||||||
|
scrollDiff: 0,
|
||||||
|
scrollInfo: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
let scrollListener = typeof this.$listeners['on-scroll'] === "function";
|
||||||
|
let scrollerView = $A(this.$refs.scrollerView);
|
||||||
|
scrollerView.scroll(() => {
|
||||||
|
let wInnerH = Math.round(scrollerView.innerHeight());
|
||||||
|
let wScrollY = scrollerView.scrollTop();
|
||||||
|
let bScrollH = this.$refs.scrollerView.scrollHeight;
|
||||||
|
this.scrollY = wScrollY;
|
||||||
|
if (scrollListener) {
|
||||||
|
let direction = 'static';
|
||||||
|
let directionreal = 'static';
|
||||||
|
if (this.scrollDiff - wScrollY > 50) {
|
||||||
|
this.scrollDiff = wScrollY;
|
||||||
|
direction = 'down';
|
||||||
|
} else if (this.scrollDiff - wScrollY < -100) {
|
||||||
|
this.scrollDiff = wScrollY;
|
||||||
|
direction = 'up';
|
||||||
|
}
|
||||||
|
if (this.scrollDiff - wScrollY > 1) {
|
||||||
|
this.scrollDiff = wScrollY;
|
||||||
|
directionreal = 'down';
|
||||||
|
} else if (this.scrollDiff - wScrollY < -1) {
|
||||||
|
this.scrollDiff = wScrollY;
|
||||||
|
directionreal = 'up';
|
||||||
|
}
|
||||||
|
this.$emit('on-scroll', {
|
||||||
|
scale: wScrollY / (bScrollH - wInnerH), //已滚动比例
|
||||||
|
scrollY: wScrollY, //滚动的距离
|
||||||
|
scrollE: bScrollH - wInnerH - wScrollY, //与底部距离
|
||||||
|
direction: direction, //滚动方向
|
||||||
|
directionreal: directionreal, //滚动方向(即时)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
activated() {
|
||||||
|
if (this.scrollY > 0) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollTo(this.scrollY);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
scrollTo(top, animate) {
|
||||||
|
if (animate === false) {
|
||||||
|
$A(this.$refs.scrollerView).stop().scrollTop(top);
|
||||||
|
} else {
|
||||||
|
$A(this.$refs.scrollerView).stop().animate({"scrollTop": top});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scrollToBottom(animate) {
|
||||||
|
this.scrollTo(this.$refs.scrollerView.scrollHeight, animate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -152,6 +152,7 @@
|
|||||||
}
|
}
|
||||||
.manage-box-new {
|
.manage-box-new {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
|
height: 38px;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,475 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="project-list">
|
<div class="project-list">
|
||||||
list
|
<div class="project-head">
|
||||||
|
<div class="project-titbox">
|
||||||
|
<div class="project-title">✔️ Daily Task</div>
|
||||||
|
<div class="project-subtitle">Click + New To create new list and wait for project manager card Don't Create a card by yourself to manage a good colaboration.</div>
|
||||||
|
</div>
|
||||||
|
<ul class="project-icons">
|
||||||
|
<li class="project-icon">
|
||||||
|
<Icon type="ios-search-outline" />
|
||||||
|
</li>
|
||||||
|
<li class="project-icon">
|
||||||
|
<Icon type="ios-chatbubbles-outline" />
|
||||||
|
<Badge :count="999"></Badge>
|
||||||
|
</li>
|
||||||
|
<li class="project-avatar online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="project-column">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="column-head">
|
||||||
|
<div class="column-head-title">Next Up</div>
|
||||||
|
<div class="column-head-num">3</div>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="task-head">
|
||||||
|
<div class="task-title">Maxxis Tyres</div>
|
||||||
|
<Icon type="ios-more" />
|
||||||
|
</div>
|
||||||
|
<div class="task-desc">These project will need a new brand Identity where they will get recognise.</div>
|
||||||
|
<div class="task-tags">
|
||||||
|
<Tag color="red">red</Tag>
|
||||||
|
<Tag color="volcano">volcano</Tag>
|
||||||
|
</div>
|
||||||
|
<div class="task-member">
|
||||||
|
<ul>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="task-icon">5<Icon type="ios-link-outline" /></div>
|
||||||
|
<div class="task-icon">5<Icon type="ios-chatbubbles-outline" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="task-progress">
|
||||||
|
<Progress :percent="25" :stroke-width="6" />
|
||||||
|
<div class="task-time today"><Icon type="ios-time-outline" />Mar 30</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="task-head">
|
||||||
|
<div class="task-title">Maxxis Tyres</div>
|
||||||
|
<Icon type="ios-more" />
|
||||||
|
</div>
|
||||||
|
<div class="task-desc">These project will need a new brand Identity where they will get recognise.</div>
|
||||||
|
<div class="task-member">
|
||||||
|
<ul>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="task-icon">5<Icon type="ios-link-outline" /></div>
|
||||||
|
<div class="task-icon">5<Icon type="ios-chatbubbles-outline" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="task-progress">
|
||||||
|
<Progress :percent="25" :stroke-width="6" />
|
||||||
|
<div class="task-time"><Icon type="ios-time-outline" />Mar 30</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="column-add">
|
||||||
|
<Icon type="md-add" />
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="column-head">
|
||||||
|
<div class="column-head-title">Hi Progress</div>
|
||||||
|
<div class="column-head-num">3</div>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="task-head">
|
||||||
|
<div class="task-title">Maxxis Tyres</div>
|
||||||
|
<Icon type="ios-more" />
|
||||||
|
</div>
|
||||||
|
<div class="task-desc">These project will need a new brand Identity where they will get recognise.</div>
|
||||||
|
<div class="task-tags">
|
||||||
|
<Tag color="magenta">magenta</Tag>
|
||||||
|
<Tag color="red">red</Tag>
|
||||||
|
<Tag color="volcano">volcano</Tag>
|
||||||
|
</div>
|
||||||
|
<div class="task-member">
|
||||||
|
<ul>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="task-icon">5<Icon type="ios-link-outline" /></div>
|
||||||
|
<div class="task-icon">5<Icon type="ios-chatbubbles-outline" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="task-progress">
|
||||||
|
<Progress :percent="25" :stroke-width="6" />
|
||||||
|
<div class="task-time"><Icon type="ios-time-outline" />Mar 30</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="task-head">
|
||||||
|
<div class="task-title">Maxxis Tyres</div>
|
||||||
|
<Icon type="ios-more" />
|
||||||
|
</div>
|
||||||
|
<div class="task-desc">These project will need a new brand Identity where they will get recognise.</div>
|
||||||
|
<div class="task-tags">
|
||||||
|
<Tag color="magenta">magenta</Tag>
|
||||||
|
<Tag color="red">red</Tag>
|
||||||
|
<Tag color="volcano">volcano</Tag>
|
||||||
|
</div>
|
||||||
|
<div class="task-member">
|
||||||
|
<ul>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="task-icon">5<Icon type="ios-link-outline" /></div>
|
||||||
|
<div class="task-icon">5<Icon type="ios-chatbubbles-outline" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="task-progress">
|
||||||
|
<Progress :percent="25" :stroke-width="6" />
|
||||||
|
<div class="task-time tomorrow"><Icon type="ios-time-outline" />Mar 30</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="column-add">
|
||||||
|
<Icon type="md-add" />
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="column-head">
|
||||||
|
<div class="column-head-title">Complete</div>
|
||||||
|
<div class="column-head-num">3</div>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="task-head">
|
||||||
|
<div class="task-title">Maxxis Tyres</div>
|
||||||
|
<Icon type="ios-more" />
|
||||||
|
</div>
|
||||||
|
<div class="task-desc">These project will need a new brand Identity where they will get recognise.</div>
|
||||||
|
<div class="task-member">
|
||||||
|
<ul>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="task-icon">5<Icon type="ios-link-outline" /></div>
|
||||||
|
<div class="task-icon">5<Icon type="ios-chatbubbles-outline" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="task-progress">
|
||||||
|
<Progress :percent="25" :stroke-width="6" />
|
||||||
|
<div class="task-time"><Icon type="ios-time-outline" />Mar 30</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="task-head">
|
||||||
|
<div class="task-title">Maxxis Tyres</div>
|
||||||
|
<Icon type="ios-more" />
|
||||||
|
</div>
|
||||||
|
<div class="task-desc">These project will need a new brand Identity where they will get recognise.</div>
|
||||||
|
<div class="task-tags">
|
||||||
|
<Tag color="primary">primary</Tag>
|
||||||
|
<Tag color="success">success</Tag>
|
||||||
|
<Tag color="error">error</Tag>
|
||||||
|
<Tag color="warning">warning</Tag>
|
||||||
|
<Tag color="magenta">magenta</Tag>
|
||||||
|
<Tag color="red">red</Tag>
|
||||||
|
<Tag color="volcano">volcano</Tag>
|
||||||
|
</div>
|
||||||
|
<div class="task-member">
|
||||||
|
<ul>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li class="online">
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="task-icon">5<Icon type="ios-link-outline" /></div>
|
||||||
|
<div class="task-icon">5<Icon type="ios-chatbubbles-outline" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="task-progress">
|
||||||
|
<Progress :percent="25" :stroke-width="6" />
|
||||||
|
<div class="task-time"><Icon type="ios-time-outline" />Mar 30</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="column-add">
|
||||||
|
<Icon type="md-add" />
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:global {
|
:global {
|
||||||
.project-list {
|
.project-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.project-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
margin: 32px;
|
||||||
|
.project-titbox {
|
||||||
|
.project-title {
|
||||||
|
flex: 1;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.project-subtitle {
|
||||||
|
color: #999999;
|
||||||
|
margin-top: 18px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.project-icons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-left: 80px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
> li {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 16px;
|
||||||
|
&.project-icon {
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #F2F3F5;
|
||||||
|
.ivu-icon {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.ivu-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: -6px;
|
||||||
|
left: 20px;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.project-avatar {
|
||||||
|
.ivu-avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #ff0000;
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
&.online {
|
||||||
|
&:before {
|
||||||
|
background-color: #509E76;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.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: #1C1D1E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> ul {
|
||||||
|
flex: 1;
|
||||||
|
height: 0;
|
||||||
|
overflow: auto;
|
||||||
|
> li {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 10px 16px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
transition: box-shadow 0.3s;
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 0 10px #e6ecfa;
|
||||||
|
}
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
.task-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.task-title {
|
||||||
|
flex: 1;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.ivu-icon {
|
||||||
|
font-size: 22px;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.task-desc {
|
||||||
|
color: #999999;
|
||||||
|
margin-top: 10px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
.task-tags {
|
||||||
|
margin-top: 10px;
|
||||||
|
.ivu-tag {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.task-member {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
> ul {
|
||||||
|
flex: 1;
|
||||||
|
width: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 12px;
|
||||||
|
> li {
|
||||||
|
list-style: none;
|
||||||
|
margin-left: -5px;
|
||||||
|
&:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.ivu-avatar {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
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;
|
||||||
|
.task-time {
|
||||||
|
flex-shrink: 0;
|
||||||
|
background-color: #EAEDF2;
|
||||||
|
padding: 1px 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 3px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
&.today {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #ed4014;
|
||||||
|
}
|
||||||
|
&.tomorrow {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #ff9900;
|
||||||
|
}
|
||||||
|
.ivu-icon {
|
||||||
|
margin-right: 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.column-add {
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 2px dashed #F1f1f1;
|
||||||
|
padding: 5px 12px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 10px 18px;
|
||||||
|
.ivu-icon {
|
||||||
|
color: #cccccc;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -16,23 +16,104 @@
|
|||||||
<li><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></li>
|
<li><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="group-chat">
|
|
||||||
<div class="group-title">Group Chat</div>
|
<div class="group-title">Group Chat</div>
|
||||||
|
<ScrollerY ref="groupChat" class="group-chat" @on-scroll="groupChatScroll">
|
||||||
|
<div ref="manageList" class="message-list">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="message-avatar online"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Selamat pagi, Mas!</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="group-input">
|
</li>
|
||||||
|
<li class="self">
|
||||||
|
<div class="message-avatar"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Selamat pagi, Mas!</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="message-avatar offline"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Pagi Mas Piko, Langsung saja Ada apa Gerangan mas?</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="self">
|
||||||
|
<div class="message-avatar"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Pagi Mas Piko, Langsung saja Ada apa Gerangan mas?</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="message-avatar online"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Selamat pagi, Mas!</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="self">
|
||||||
|
<div class="message-avatar"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Selamat pagi, Mas!</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="message-avatar offline"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Pagi Mas Piko, Langsung saja Ada apa Gerangan mas?</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="self">
|
||||||
|
<div class="message-avatar"><Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" /></div>
|
||||||
|
<div class="message-item">
|
||||||
|
<div class="message-text">Pagi Mas Piko, Langsung saja Ada apa Gerangan mas?</div>
|
||||||
|
<div class="message-time">08:00 AM</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</ScrollerY>
|
||||||
|
<div class="group-footer">
|
||||||
|
<DragInput class="group-input" v-model="groupText" type="textarea" :rows="1" :autosize="{ minRows: 1, maxRows: 3 }" :maxlength="255" @on-keydown="groupKeydown" @on-input-paste="groupPasteDrag" :placeholder="$L('输入消息...')" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
:global {
|
||||||
|
.project-message {
|
||||||
|
.group-footer {
|
||||||
|
.group-input {
|
||||||
|
background-color: #F4F5F7;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 10px;
|
||||||
|
.ivu-input {
|
||||||
|
border: 0;
|
||||||
|
resize: none;
|
||||||
|
background-color: transparent;
|
||||||
|
&:focus {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:global {
|
:global {
|
||||||
.project-message {
|
.project-message {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 36px 24px;
|
|
||||||
.group-member {
|
.group-member {
|
||||||
padding: 0 8px;
|
margin-top: 36px;
|
||||||
|
padding: 0 32px;
|
||||||
.member-head {
|
.member-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -42,7 +123,7 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
> span {
|
> span {
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
color: #4E60CC;
|
color: #2d8cf0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.member-view-all {
|
.member-view-all {
|
||||||
@ -57,10 +138,10 @@
|
|||||||
> li {
|
> li {
|
||||||
position: relative;
|
position: relative;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin-right: 13px;
|
margin-right: 14px;
|
||||||
.ivu-avatar {
|
.ivu-avatar {
|
||||||
width: 38px;
|
width: 36px;
|
||||||
height: 38px;
|
height: 36px;
|
||||||
}
|
}
|
||||||
&:before {
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
@ -82,32 +163,146 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.group-chat {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 8px;
|
|
||||||
margin-top: 24px;
|
|
||||||
.group-title {
|
.group-title {
|
||||||
|
padding: 0 32px;
|
||||||
|
margin-top: 28px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
.group-chat {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 32px;
|
||||||
|
margin-top: 18px;
|
||||||
|
overflow: auto;
|
||||||
|
.message-list {
|
||||||
|
> ul {
|
||||||
|
> li {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-end;
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
.message-avatar {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
.ivu-avatar {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.group-input {
|
&.online,
|
||||||
|
&.offline {
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
transform: scale(0.8);
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #ff0000;
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.online {
|
||||||
|
&:before {
|
||||||
|
background-color: #509E76;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.message-item {
|
||||||
|
max-width: 70%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin: 0 0 0 8px;
|
||||||
|
.message-text {
|
||||||
|
color: #333333;
|
||||||
|
background-color: #F4F5F7;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 6px 6px 6px 0;
|
||||||
|
}
|
||||||
|
.message-time {
|
||||||
|
color: #bbbbbb;
|
||||||
|
font-size: 12px;
|
||||||
|
padding-top: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.self {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
.message-item {
|
||||||
|
align-items: flex-end;
|
||||||
|
margin: 0 8px 0 0;
|
||||||
|
.message-text {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #2d8cf0;
|
||||||
|
border-radius: 6px 6px 0 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.group-footer {
|
||||||
|
padding: 0 28px;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import DragInput from "../../../components/DragInput";
|
||||||
|
import ScrollerY from "../../../components/ScrollerY";
|
||||||
export default {
|
export default {
|
||||||
name: "ProjectMessage",
|
name: "ProjectMessage",
|
||||||
|
components: {ScrollerY, DragInput},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
groupText: '',
|
||||||
|
autoBottom: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.groupChatGoAuto();
|
||||||
|
this.groupChatGoBottom();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
groupKeydown() {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
groupPasteDrag() {
|
||||||
|
|
||||||
|
},
|
||||||
|
groupChatScroll(res) {
|
||||||
|
if (res.directionreal === 'up') {
|
||||||
|
if (res.scrollE < 10) {
|
||||||
|
this.autoBottom = true;
|
||||||
|
}
|
||||||
|
} else if (res.directionreal === 'down') {
|
||||||
|
this.autoBottom = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groupChatGoAuto() {
|
||||||
|
clearTimeout(this.groupChatGoTimeout);
|
||||||
|
this.groupChatGoTimeout = setTimeout(() => {
|
||||||
|
if (this.autoBottom) {
|
||||||
|
this.groupChatGoBottom();
|
||||||
|
}
|
||||||
|
this.groupChatGoAuto();
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
groupChatGoBottom(animation = false) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (typeof this.$refs.groupChat !== "undefined") {
|
||||||
|
this.$refs.groupChat.scrollTo(this.$refs.manageList.clientHeight, animation);
|
||||||
|
this.autoBottom = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -13,13 +13,16 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
.project-list {
|
.project-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
width: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background-color: #fafafa;
|
||||||
}
|
}
|
||||||
.project-message {
|
.project-message {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 40%;
|
width: 40%;
|
||||||
max-width: 410px;
|
max-width: 410px;
|
||||||
|
flex-shrink: 0;
|
||||||
&:before {
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user