update
This commit is contained in:
parent
336c31a345
commit
df196385e4
BIN
frontend/src/assets/images/loading.gif
Normal file
BIN
frontend/src/assets/images/loading.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
frontend/src/assets/images/no_content.jpg
Normal file
BIN
frontend/src/assets/images/no_content.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="empty-content-container" :class="{autoFit : 'auto-fit'}">
|
<div v-if="loading || empty" class="empty-content-container" :class="{autoFit : 'auto-fit'}">
|
||||||
|
<img v-if="loading" src="@/assets/images/loading.gif" class="loading-big" alt="">
|
||||||
|
<img v-if="empty && !loading" src="@/assets/images/no_content.jpg" class="empty-img" alt="">
|
||||||
|
<span v-if="empty && !loading" class="empty-text">No content yet</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -8,7 +10,9 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'EmptyContent',
|
name: 'EmptyContent',
|
||||||
props: {
|
props: {
|
||||||
autoFit: { type: Boolean, default: false }
|
autoFit: { type: Boolean, default: false },
|
||||||
|
loading: { type: Boolean, default: true },
|
||||||
|
empty: { type: Boolean, default: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -19,10 +23,15 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
&.auto-fit {
|
&.auto-fit {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-big {width: 188px; height: 188px;}
|
||||||
|
.empty-img {width: 188px; height: 188px; margin-bottom: 15px;}
|
||||||
|
.empty-text {font-size: 26px; color: #6E7387;}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -227,6 +227,9 @@ export default {
|
|||||||
|
|
||||||
img {
|
img {
|
||||||
width: 56px;
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +289,12 @@ export default {
|
|||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.header-switch-desc {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.header-switch-desc {
|
.header-switch-desc {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -295,6 +304,7 @@ export default {
|
|||||||
color: #3d455f;
|
color: #3d455f;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -204,15 +204,19 @@
|
|||||||
|
|
||||||
<div class="collapse collapse-content-container" id="collapse-personal-user-photo"
|
<div class="collapse collapse-content-container" id="collapse-personal-user-photo"
|
||||||
aria-labelledby="personal-summary" data-bs-parent="#personal-panel">
|
aria-labelledby="personal-summary" data-bs-parent="#personal-panel">
|
||||||
<div class="collapse-item-container">
|
<div class="collapse-item-container column-flex">
|
||||||
<label class="btn btn-link" for="personal-photo-operation-image">
|
<label class="btn btn-link" for="personal-photo-operation-image">
|
||||||
<img class="user-portrait-img" id="personal-photo-operation-image" alt="user portrait" :src="userProfile.account.basic.photo.base64
|
<img class="user-portrait-img" id="personal-photo-operation-image" alt="user portrait" :src="userProfile.account.basic.photo.base64
|
||||||
? userProfile.account.basic.photo.base64
|
? userProfile.account.basic.photo.base64
|
||||||
: profileUrl
|
: profileUrl
|
||||||
" v-tooltip title="Click to update" @click="selectUserPhoto()" />
|
" v-tooltip title="Click to update" @click="selectUserPhoto()" />
|
||||||
|
<div v-if="photoLoading" class="spinner-container">
|
||||||
|
<div class="spinner-border text-primary" role="status" />
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<input ref="uploadUserPhotoInput" type="file" :accept="identityOperation.photo.acceptableType" hidden
|
<input ref="uploadUserPhotoInput" type="file" :accept="identityOperation.photo.acceptableType" hidden
|
||||||
@change="onUserPhotoChange($event)" />
|
@change="onUserPhotoChange($event)" />
|
||||||
|
<p v-if="message">{{message}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse collapse-content-container" id="collapse-personal-user-intro"
|
<div class="collapse collapse-content-container" id="collapse-personal-user-intro"
|
||||||
@ -264,7 +268,7 @@
|
|||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse-item-container">
|
<div class="collapse-item-container column-flex">
|
||||||
<label v-if="Is_Wechat_QR_Code_Payment()" class="collapse-item-uploader" for="qr-uploader">
|
<label v-if="Is_Wechat_QR_Code_Payment()" class="collapse-item-uploader" for="qr-uploader">
|
||||||
<img v-if="paymentOperation.wechat_qr_code_img.data" class="uploader-img-show"
|
<img v-if="paymentOperation.wechat_qr_code_img.data" class="uploader-img-show"
|
||||||
:src="paymentOperation.wechat_qr_code_img.data" />
|
:src="paymentOperation.wechat_qr_code_img.data" />
|
||||||
@ -273,10 +277,14 @@
|
|||||||
<span v-if="!paymentOperation.wechat_qr_code_img.data" class="upload-text-btn">{{
|
<span v-if="!paymentOperation.wechat_qr_code_img.data" class="upload-text-btn">{{
|
||||||
$t('Upload QR code to receive payment')
|
$t('Upload QR code to receive payment')
|
||||||
}}</span>
|
}}</span>
|
||||||
|
<div v-if="photoLoading" class="spinner-container">
|
||||||
|
<div class="spinner-border text-primary" role="status" />
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<input v-if="Is_Wechat_QR_Code_Payment()" ref="uploadWechatQRCodePhotoInput" type="file" id="qr-uploader"
|
<input v-if="Is_Wechat_QR_Code_Payment()" ref="uploadWechatQRCodePhotoInput" type="file" id="qr-uploader"
|
||||||
:accept="paymentOperation.wechat_qr_code_img.acceptableType" hidden
|
:accept="paymentOperation.wechat_qr_code_img.acceptableType" hidden
|
||||||
@change="onUploadWechatQRCodePhoto($event)" />
|
@change="onUploadWechatQRCodePhoto($event)" />
|
||||||
|
<p v-if="message">{{message}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="Is_Stripe_Payment()" class="collapse-item-container">
|
<div v-if="Is_Stripe_Payment()" class="collapse-item-container">
|
||||||
<span>{{ $t('Have you linked your strip account?') }}</span><button class="btn btn-link"
|
<span>{{ $t('Have you linked your strip account?') }}</span><button class="btn btn-link"
|
||||||
@ -491,7 +499,7 @@ export default {
|
|||||||
name: 'UserProfile',
|
name: 'UserProfile',
|
||||||
props: {},
|
props: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchProfile()
|
// this.fetchProfile()
|
||||||
this.fetchTemplates()
|
this.fetchTemplates()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -518,12 +526,21 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
|
},
|
||||||
|
userProfile() {
|
||||||
|
this.fetchProfile()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
userProfile() {
|
||||||
|
return this.$store.getters['userProfile/profile']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
profileUrl,
|
profileUrl,
|
||||||
userProfile: null,
|
// userProfile: null,
|
||||||
|
photoLoading: false,
|
||||||
message: null,
|
message: null,
|
||||||
accountNeedAttention: false,
|
accountNeedAttention: false,
|
||||||
availableTemplates: null,
|
availableTemplates: null,
|
||||||
@ -593,7 +610,7 @@ export default {
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
fetchProfile() {
|
fetchProfile() {
|
||||||
this.userProfile = this.$store.getters['userProfile/profile']
|
// this.userProfile = this.$store.getters['userProfile/profile']
|
||||||
this.updateLocalIdentityData()
|
this.updateLocalIdentityData()
|
||||||
this.updateLocalEmailData()
|
this.updateLocalEmailData()
|
||||||
this.updateLocalMobileData()
|
this.updateLocalMobileData()
|
||||||
@ -645,9 +662,11 @@ export default {
|
|||||||
this.userProfile.account.basic.photo = response.data.photo
|
this.userProfile.account.basic.photo = response.data.photo
|
||||||
this.updateLocalIdentityData()
|
this.updateLocalIdentityData()
|
||||||
this.updateLocalProfileData()
|
this.updateLocalProfileData()
|
||||||
|
this.photoLoading = false
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.mnx_backendErrorHandler(error)
|
this.mnx_backendErrorHandler(error)
|
||||||
|
this.photoLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
selectUserPhoto() {
|
selectUserPhoto() {
|
||||||
@ -656,12 +675,15 @@ export default {
|
|||||||
onUserPhotoChange(event) {
|
onUserPhotoChange(event) {
|
||||||
let file = event.target.files[0]
|
let file = event.target.files[0]
|
||||||
let reader = new FileReader()
|
let reader = new FileReader()
|
||||||
|
this.message = null
|
||||||
|
this.photoLoading = true
|
||||||
reader.addEventListener(
|
reader.addEventListener(
|
||||||
'load',
|
'load',
|
||||||
function () {
|
function () {
|
||||||
this.identityOperation.photo.base64 = reader.result
|
this.identityOperation.photo.base64 = reader.result
|
||||||
this.identityOperation.photo.filename = file.name
|
this.identityOperation.photo.filename = file.name
|
||||||
if (file.size > this.identityOperation.photo.filesizeLimit) {
|
if (file.size > this.identityOperation.photo.filesizeLimit) {
|
||||||
|
this.photoLoading = false
|
||||||
this.message =
|
this.message =
|
||||||
'file need to be smaller than ' +
|
'file need to be smaller than ' +
|
||||||
this.identityOperation.photo.filesizeLimit +
|
this.identityOperation.photo.filesizeLimit +
|
||||||
@ -988,8 +1010,10 @@ export default {
|
|||||||
if (response.data.account_link != '') {
|
if (response.data.account_link != '') {
|
||||||
window.location = 'user-profile'
|
window.location = 'user-profile'
|
||||||
}
|
}
|
||||||
|
this.photoLoading = false
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
this.photoLoading = false
|
||||||
this.mnx_backendErrorHandler(error)
|
this.mnx_backendErrorHandler(error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -999,6 +1023,8 @@ export default {
|
|||||||
onUploadWechatQRCodePhoto(event) {
|
onUploadWechatQRCodePhoto(event) {
|
||||||
let file = event.target.files[0]
|
let file = event.target.files[0]
|
||||||
let reader = new FileReader()
|
let reader = new FileReader()
|
||||||
|
this.message = null
|
||||||
|
this.photoLoading = true
|
||||||
reader.addEventListener(
|
reader.addEventListener(
|
||||||
'load',
|
'load',
|
||||||
function () {
|
function () {
|
||||||
@ -1009,6 +1035,7 @@ export default {
|
|||||||
'file need to be smaller than ' +
|
'file need to be smaller than ' +
|
||||||
this.paymentOperation.wechat_qr_code_img.filesizeLimit +
|
this.paymentOperation.wechat_qr_code_img.filesizeLimit +
|
||||||
' byptes'
|
' byptes'
|
||||||
|
this.photoLoading = false
|
||||||
} else {
|
} else {
|
||||||
this.updateWechatQRCode(reader.result, file.name)
|
this.updateWechatQRCode(reader.result, file.name)
|
||||||
}
|
}
|
||||||
@ -1133,9 +1160,31 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
&.column-flex {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-link {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
background-color: rgba(0,0,0,.3);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.user-portrait-img {
|
.user-portrait-img {
|
||||||
width: 150px;
|
width: 150px;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapse-item-editor {
|
.collapse-item-editor {
|
||||||
@ -1210,6 +1259,7 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.78;
|
opacity: 0.78;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<empty-content :loading="loading" :empty="recommendedProviders?.length === 0" />
|
||||||
<div class="provider-hub-container" id="provider-accordion-container">
|
<div class="provider-hub-container" id="provider-accordion-container">
|
||||||
<template v-if="recommendedProviders">
|
<template v-if="recommendedProviders">
|
||||||
<div
|
<div
|
||||||
@ -280,15 +281,19 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ProviderHubApi } from '@/utils/index'
|
import { ProviderHubApi } from '@/utils/index'
|
||||||
|
import EmptyContent from '@/components/EmptyContent.vue'
|
||||||
export default {
|
export default {
|
||||||
|
components: { EmptyContent },
|
||||||
name: 'ProviderHub',
|
name: 'ProviderHub',
|
||||||
props: {},
|
props: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.loading = true
|
||||||
this.fetchProviders()
|
this.fetchProviders()
|
||||||
this.fetchRequests()
|
this.fetchRequests()
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
loading: false,
|
||||||
recommendedProviders: null,
|
recommendedProviders: null,
|
||||||
checkedRequests: [],
|
checkedRequests: [],
|
||||||
requests: null,
|
requests: null,
|
||||||
@ -300,9 +305,11 @@ export default {
|
|||||||
fetchProviders() {
|
fetchProviders() {
|
||||||
ProviderHubApi.fetchProvidersForHub()
|
ProviderHubApi.fetchProvidersForHub()
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
this.loading = false
|
||||||
this.recommendedProviders = response.data.recommended
|
this.recommendedProviders = response.data.recommended
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
this.loading = false
|
||||||
this.mnx_backendErrorHandler(error)
|
this.mnx_backendErrorHandler(error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<empty-content :loading="loading" :empty="requestGroups?.length === 0" />
|
||||||
<div class="request-hub">
|
<div class="request-hub">
|
||||||
<div
|
<div
|
||||||
v-for="(group, index) in requestGroups"
|
v-for="(group, index) in requestGroups"
|
||||||
@ -223,16 +224,19 @@
|
|||||||
<script>
|
<script>
|
||||||
import { RequestHubApi, WorksapceApi, DateUtils, requestHubUtils } from '@/utils/index'
|
import { RequestHubApi, WorksapceApi, DateUtils, requestHubUtils } from '@/utils/index'
|
||||||
import { proposingModelEnum } from '@/types/index'
|
import { proposingModelEnum } from '@/types/index'
|
||||||
|
import EmptyContent from '@/components/EmptyContent.vue'
|
||||||
import PDFReader from '@/components/PDFReader.vue'
|
import PDFReader from '@/components/PDFReader.vue'
|
||||||
export default {
|
export default {
|
||||||
components: { PDFReader },
|
components: { PDFReader, EmptyContent },
|
||||||
name: 'RequestHub',
|
name: 'RequestHub',
|
||||||
props: {},
|
props: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.loading = true
|
||||||
this.fetchRequests()
|
this.fetchRequests()
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
loading: false,
|
||||||
requestGroups: [],
|
requestGroups: [],
|
||||||
message: null,
|
message: null,
|
||||||
pdfDocument: {}
|
pdfDocument: {}
|
||||||
@ -245,8 +249,10 @@ export default {
|
|||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.requestGroups = response.data
|
this.requestGroups = response.data
|
||||||
this.$store.dispatch('basic/clearUnreadRequest')
|
this.$store.dispatch('basic/clearUnreadRequest')
|
||||||
|
this.loading = false
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
this.loading = false
|
||||||
this.mnx_backendErrorHandler(error)
|
this.mnx_backendErrorHandler(error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="workspace-container">
|
<empty-content :loading="loading" :empty="projects?.length === 0" />
|
||||||
<!-- <div class="workspace-header"></div> -->
|
<div v-if="projects && projects.length > 0" class="workspace-container">
|
||||||
<div class="workspace-body">
|
<div class="workspace-body">
|
||||||
<div class="accordion accordion-list" v-for="(project, project_index) in projects" :key="project_index"
|
<div class="accordion accordion-list" v-for="(project, project_index) in projects" :key="project_index"
|
||||||
:id="project.id">
|
:id="project.id">
|
||||||
@ -510,12 +510,14 @@ import { CanvasRenderer } from 'echarts/renderers'
|
|||||||
import { LineChart } from 'echarts/charts'
|
import { LineChart } from 'echarts/charts'
|
||||||
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
|
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
|
||||||
import VChart from 'vue-echarts'
|
import VChart from 'vue-echarts'
|
||||||
|
import EmptyContent from '@/components/EmptyContent.vue'
|
||||||
use([CanvasRenderer, LineChart, LegendComponent, GridComponent, TooltipComponent])
|
use([CanvasRenderer, LineChart, LegendComponent, GridComponent, TooltipComponent])
|
||||||
export default {
|
export default {
|
||||||
name: 'Workspace',
|
name: 'Workspace',
|
||||||
components: { VChart },
|
components: { VChart, EmptyContent },
|
||||||
props: {},
|
props: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.loading = true
|
||||||
this.fetchView()
|
this.fetchView()
|
||||||
// this.connectWebSocket()
|
// this.connectWebSocket()
|
||||||
},
|
},
|
||||||
@ -523,6 +525,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
projects: null,
|
projects: null,
|
||||||
message: null,
|
message: null,
|
||||||
|
loading: false,
|
||||||
newIssueDescriptions: null,
|
newIssueDescriptions: null,
|
||||||
newInviteCollaborator: null,
|
newInviteCollaborator: null,
|
||||||
qrCode: {
|
qrCode: {
|
||||||
@ -561,8 +564,10 @@ export default {
|
|||||||
this.newIssueDescriptions = new Array(this.projects.length)
|
this.newIssueDescriptions = new Array(this.projects.length)
|
||||||
this.newInviteCollaborator = new Array(this.projects.length)
|
this.newInviteCollaborator = new Array(this.projects.length)
|
||||||
this.$store.dispatch('basic/clearUnreadWorkspace')
|
this.$store.dispatch('basic/clearUnreadWorkspace')
|
||||||
|
this.loading = false
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
this.loading = false
|
||||||
this.mnx_backendErrorHandler(error)
|
this.mnx_backendErrorHandler(error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user