Merge branch 'main' of https://freeleaps.com:3443/products/freeleaps into main
* 'main' of https://freeleaps.com:3443/products/freeleaps: adjust the size of images on blogs and about pages implement link content viewer catch up on enabling blog APIs in client trying to rendering pdf(not succeeded yet) add blog retrieving display workspace according to correct role in project added support for self intro template added 'update' and 'cancel' function for self-intra
This commit is contained in:
commit
75298bc3e1
@ -26,6 +26,7 @@
|
|||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"bootstrap": "^5.3.1",
|
"bootstrap": "^5.3.1",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
"pdfjs-dist": "^4.2.67",
|
"pdfjs-dist": "^4.2.67",
|
||||||
"pinia": "^2.1.6",
|
"pinia": "^2.1.6",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
|
|||||||
@ -14,6 +14,12 @@ export default {
|
|||||||
mnx_navToContact() {
|
mnx_navToContact() {
|
||||||
this.$router.push('/contact')
|
this.$router.push('/contact')
|
||||||
},
|
},
|
||||||
|
mnx_navToPdfContentViewer(content_id) {
|
||||||
|
this.$router.push('/pdf-content-viewer/' + content_id)
|
||||||
|
},
|
||||||
|
mnx_navToLinkContentViewer(content_link_based64) {
|
||||||
|
this.$router.push('/link-content-viewer/' + content_link_based64)
|
||||||
|
},
|
||||||
|
|
||||||
//common
|
//common
|
||||||
mnx_navToFrontDoor() {
|
mnx_navToFrontDoor() {
|
||||||
|
|||||||
@ -1,11 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="">About</div>
|
<div class="directories_containter">
|
||||||
|
<div
|
||||||
|
class="directory_container"
|
||||||
|
v-for="(directory, index) in directories"
|
||||||
|
:key="index"
|
||||||
|
@click="view_link(directory)"
|
||||||
|
>
|
||||||
|
<p>{{ directory.title_text }}</p>
|
||||||
|
<img class="directory_cover_image" :src="directory.cover_picture" />
|
||||||
|
<p>{{ directory.summary_text }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { ContentApi } from '../../utils/index'
|
||||||
export default {
|
export default {
|
||||||
name: 'About',
|
name: 'About',
|
||||||
components: {},
|
components: {},
|
||||||
computed: {},
|
computed: {},
|
||||||
methods: {}
|
mounted() {
|
||||||
|
this.retrieve_directories()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
retrieve_directories() {
|
||||||
|
ContentApi.retrieve_about_directories()
|
||||||
|
.then((response) => {
|
||||||
|
this.directories = response.data
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.mnx_backendErrorHandler(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
view_link(directory) {
|
||||||
|
this.mnx_navToLinkContentViewer(btoa(directory.content_link))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
directories: null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.directories_containter {
|
||||||
|
@extend .container;
|
||||||
|
}
|
||||||
|
|
||||||
|
.directory_container {
|
||||||
|
@extend .container;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.directory_cover_image{
|
||||||
|
height: 20vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,11 +1,56 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="">Blogs</div>
|
<div v-if="blogs" class="blogs_containter">
|
||||||
|
<div class="blog_containter" v-for="(blog, index) in blogs" :key="index" @click="view_blog(blog)">
|
||||||
|
<h2>{{ blog.blog_name }}</h2>
|
||||||
|
<img class="blog_cover_image" :src="blog.cover_picture" />
|
||||||
|
<p v-text="retrieve_summary(blog)"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import { ContentApi } from '../../utils/index'
|
||||||
export default {
|
export default {
|
||||||
name: 'Blogs',
|
name: 'Blogs',
|
||||||
components: {},
|
components: {},
|
||||||
computed: {},
|
computed: {},
|
||||||
methods: {}
|
mounted() {
|
||||||
|
this.retrieve_blogs()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
retrieve_blogs() {
|
||||||
|
ContentApi.retrieve_blogs()
|
||||||
|
.then((response) => {
|
||||||
|
this.blogs = response.data
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.mnx_backendErrorHandler(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
view_blog(blog) {
|
||||||
|
this.mnx_navToPdfContentViewer(blog.content_id)
|
||||||
|
},
|
||||||
|
retrieve_summary(blog) {
|
||||||
|
return blog.summary_text
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
blogs: null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.blogs_containter {
|
||||||
|
@extend .container;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog_containter {
|
||||||
|
@extend .container;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog_cover_image {
|
||||||
|
height: 20vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
52
frontend/src/pages/public/LinkContentViewer.vue
Normal file
52
frontend/src/pages/public/LinkContentViewer.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content_containter">
|
||||||
|
<iframe
|
||||||
|
class="link-iframe"
|
||||||
|
:src="get_link()"
|
||||||
|
frameborder="0"
|
||||||
|
marginheight="0"
|
||||||
|
marginwidth="0"
|
||||||
|
max-width="100%"
|
||||||
|
sandbox="allow-forms allow-modals allow-orientation-lock allow-popups allow-same-origin allow-scripts"
|
||||||
|
scrolling="no"
|
||||||
|
style="border: none; max-width: 100%; max-height: 100vh"
|
||||||
|
allowfullscreen
|
||||||
|
mozallowfullscreen
|
||||||
|
msallowfullscreen
|
||||||
|
webkitallowfullscreen
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'LinkContentViewer',
|
||||||
|
props: {
|
||||||
|
content_link_based64: {
|
||||||
|
required: true,
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {},
|
||||||
|
computed: {},
|
||||||
|
mounted() {},
|
||||||
|
methods: {
|
||||||
|
get_link() {
|
||||||
|
return atob(this.content_link_based64)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.content_containter {
|
||||||
|
@extend .container;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-iframe {
|
||||||
|
@extend .container;
|
||||||
|
height: 70vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
49
frontend/src/pages/public/PdfContentViewer.vue
Normal file
49
frontend/src/pages/public/PdfContentViewer.vue
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div class="">ContentViewer</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { pdfjsLib } from '../../plugins/index'
|
||||||
|
import { ContentApi } from '../../utils/index'
|
||||||
|
import { Buffer } from 'buffer'
|
||||||
|
export default {
|
||||||
|
name: 'PdfContentViewer',
|
||||||
|
props: {
|
||||||
|
content_id: {
|
||||||
|
required: true,
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {},
|
||||||
|
computed: {},
|
||||||
|
mounted() {
|
||||||
|
this.retrieve_blog_content()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
retrieve_blog_content() {
|
||||||
|
ContentApi.retrieve_blog_content(this.content_id)
|
||||||
|
.then((response) => {
|
||||||
|
this.content_media_data = response.data
|
||||||
|
var loadingTask = pdfjsLib.getDocument({
|
||||||
|
data: Buffer.from(this.content_media_data, 'base64')
|
||||||
|
})
|
||||||
|
loadingTask.promise.then(function (pdf) {
|
||||||
|
//
|
||||||
|
// Fetch the first page
|
||||||
|
//
|
||||||
|
pdf.getPage(1).then(function (page) {
|
||||||
|
//rendering
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.mnx_backendErrorHandler(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
content_media_data: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="userProfile" class="user-profile-container">
|
<div v-if="userProfile" class="user-profile-container offcanvas-parent">
|
||||||
<div class="account-panel-container" id="account-panel">
|
<div class="account-panel-container" id="account-panel">
|
||||||
<div class="account-summary-bar-container">
|
<div class="account-summary-bar-container">
|
||||||
<div class="account-summary-header-container">
|
<div class="account-summary-header-container">
|
||||||
@ -429,18 +429,41 @@
|
|||||||
<label class="personal-self-intro-content-label" for="personal-self-intro-editor"
|
<label class="personal-self-intro-content-label" for="personal-self-intro-editor"
|
||||||
>Self-intro</label
|
>Self-intro</label
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
v-if="personalOperation.self_intro.is_editing"
|
||||||
|
class="self-intro-in-header-editing-action-container"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="personal-self-intro-template-button"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="offcanvas"
|
||||||
|
data-bs-target="#offcanvas-template"
|
||||||
|
aria-controls="offcanvas-template"
|
||||||
|
>
|
||||||
|
templates
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="personalOperation.self_intro.is_editing"
|
||||||
|
class="self-intro-in-content-editing-action-container"
|
||||||
|
>
|
||||||
|
<button @click="updateSelfIntro()" class="in-context-foward-button">Update</button>
|
||||||
|
<button @click="stopEdittingSelfintro($event)" class="in-context-back-button">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="personal-self-intro-content-editor"
|
class="personal-self-intro-content-editor"
|
||||||
id="personal-self-intro-editor"
|
id="personal-self-intro-editor"
|
||||||
|
ref="personal_self_intro_editor_div"
|
||||||
v-html="personalOperation.self_intro.content_html"
|
v-html="personalOperation.self_intro.content_html"
|
||||||
contenteditable="false"
|
contenteditable="false"
|
||||||
v-tooltip
|
v-tooltip
|
||||||
title="Click to edit"
|
title="Click to edit"
|
||||||
delay='{"show":"500", "hide":"100"}'
|
delay='{"show":"500", "hide":"100"}'
|
||||||
@click="edittingSelfintro($event)"
|
@click="edittingSelfintro($event)"
|
||||||
@blur="stopEdittingSelfintro($event)"
|
@keyup="keyUpOnSelfIntroEditor($event)"
|
||||||
@keyup.enter="blurInput($event)"
|
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -681,19 +704,72 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="offcanvas offcanvas-end offcanvas-container"
|
||||||
|
tabindex="-1"
|
||||||
|
id="offcanvas-template"
|
||||||
|
aria-labelledby="offcanvas-template"
|
||||||
|
>
|
||||||
|
<div class="offcanvas-header">
|
||||||
|
<h5 class="offcanvas-title" id="offcanvas-template">Apply self-intro template</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn-close"
|
||||||
|
data-bs-dismiss="offcanvas"
|
||||||
|
aria-label="Close"
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div class="offcanvas-body">
|
||||||
|
<div class="accordion" id="template-item-container">
|
||||||
|
<div
|
||||||
|
v-for="(template, index) in availableTemplates"
|
||||||
|
:key="index"
|
||||||
|
:id="'template' + index"
|
||||||
|
class="accordion-item"
|
||||||
|
>
|
||||||
|
<h2 class="accordion-header" :id="'heading' + index">
|
||||||
|
<button
|
||||||
|
class="accordion-button collapsed"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
:data-bs-target="'#' + 'collapse' + index"
|
||||||
|
aria-expanded="false"
|
||||||
|
:aria-controls="'collapse' + index"
|
||||||
|
>
|
||||||
|
{{ template.title }}
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
:id="'collapse' + index"
|
||||||
|
class="accordion-collapse collapse"
|
||||||
|
:aria-labelledby="'heading' + index"
|
||||||
|
data-bs-parent="#template-item-container"
|
||||||
|
>
|
||||||
|
<div class="accordion-body">
|
||||||
|
<button class="select-template-button" @click="selectTemplate(template)">
|
||||||
|
Apply
|
||||||
|
</button>
|
||||||
|
<div class="template-content-textarea" v-html="template.content"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { moneyCollectionTypeEnum } from '../../../types/index'
|
import { moneyCollectionTypeEnum } from '../../../types/index'
|
||||||
|
|
||||||
import { UserProfileApi, elementHandler } from '../../../utils/index'
|
import { UserProfileApi, elementHandler, textAreaAujuster } from '../../../utils/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'UserProfile',
|
name: 'UserProfile',
|
||||||
props: {},
|
props: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchProfile()
|
this.fetchProfile()
|
||||||
|
this.fetchTemplates()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'userProfile.account.basic.first_name': {
|
'userProfile.account.basic.first_name': {
|
||||||
@ -726,6 +802,7 @@ export default {
|
|||||||
userProfile: null,
|
userProfile: null,
|
||||||
message: null,
|
message: null,
|
||||||
accountNeedAttention: false,
|
accountNeedAttention: false,
|
||||||
|
availableTemplates: null,
|
||||||
identityOperation: {
|
identityOperation: {
|
||||||
first_name: null,
|
first_name: null,
|
||||||
last_name: null,
|
last_name: null,
|
||||||
@ -768,7 +845,8 @@ export default {
|
|||||||
personalOperation: {
|
personalOperation: {
|
||||||
self_intro: {
|
self_intro: {
|
||||||
summary: null,
|
summary: null,
|
||||||
content_html: null
|
content_html: '',
|
||||||
|
is_editing: false
|
||||||
},
|
},
|
||||||
expected_salary: {
|
expected_salary: {
|
||||||
hourly: 140
|
hourly: 140
|
||||||
@ -1067,31 +1145,47 @@ export default {
|
|||||||
//self-intro
|
//self-intro
|
||||||
edittingSelfintro($event) {
|
edittingSelfintro($event) {
|
||||||
elementHandler.edittingContent($event.target)
|
elementHandler.edittingContent($event.target)
|
||||||
|
this.personalOperation.self_intro.is_editing = true
|
||||||
$event.target.focus()
|
$event.target.focus()
|
||||||
},
|
},
|
||||||
stopEdittingSelfintro($event) {
|
stopEdittingSelfintro($event) {
|
||||||
elementHandler.stopEdittingContent($event.target)
|
elementHandler.stopEdittingContent($event.target)
|
||||||
if (
|
this.personalOperation.self_intro.is_editing = false
|
||||||
!(
|
this.personalOperation.self_intro.content_html =
|
||||||
this.personalOperation.self_intro.content_html ===
|
|
||||||
this.userProfile.account.basic.self_intro.content_html
|
this.userProfile.account.basic.self_intro.content_html
|
||||||
)
|
|
||||||
) {
|
|
||||||
if (!this.personalOperation.self_intro.content_html) {
|
|
||||||
this.updateSelfIntro(this.personalOperation.self_intro.content_html)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
updateSelfIntro(content) {
|
keyUpOnSelfIntroEditor($event) {
|
||||||
UserProfileApi.updateSelfIntro(content)
|
let element = $event.target
|
||||||
|
textAreaAujuster.adjustHight(element)
|
||||||
|
},
|
||||||
|
updateSelfIntro() {
|
||||||
|
this.personalOperation.self_intro.content_html =
|
||||||
|
this.$refs.personal_self_intro_editor_div.innerHTML
|
||||||
|
if (!this.personalOperation.self_intro.content_html) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
UserProfileApi.updateSelfIntro(this.personalOperation.self_intro.content_html)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.userProfile.account.basic.self_intro = response.data.self_intro
|
this.userProfile.account.basic.self_intro = response.data.self_intro
|
||||||
this.personalOperation.self_intro = response.data.self_intro
|
this.personalOperation.self_intro = response.data.self_intro // makes a reference instead of a copy
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.mnx_backendErrorHandler(error)
|
this.mnx_backendErrorHandler(error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
fetchTemplates() {
|
||||||
|
UserProfileApi.fetchSelfIntroTemplates('')
|
||||||
|
.then((response) => {
|
||||||
|
this.availableTemplates = response.data
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.mnx_backendErrorHandler(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
selectTemplate(template) {
|
||||||
|
this.personalOperation.self_intro.content_html = template.content
|
||||||
|
},
|
||||||
|
|
||||||
//payment
|
//payment
|
||||||
updateLocalPaymentData() {
|
updateLocalPaymentData() {
|
||||||
this.paymentOperation.ready_to_receive_money =
|
this.paymentOperation.ready_to_receive_money =
|
||||||
@ -1555,11 +1649,34 @@ export default {
|
|||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.self-intro-in-header-editing-action-container {
|
||||||
|
@extend .flex-row-container;
|
||||||
|
@extend .justify-content-around;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self-intro-in-content-editing-action-container {
|
||||||
|
@extend .float-end;
|
||||||
|
@extend .flex-row-container;
|
||||||
|
@extend .justify-content-end;
|
||||||
|
@extend .w-20;
|
||||||
|
}
|
||||||
|
|
||||||
.personal-self-intro-template-button {
|
.personal-self-intro-template-button {
|
||||||
@extend .initiate-button;
|
@extend .initiate-button;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.in-context-foward-button {
|
||||||
|
@extend .proceed-button;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.in-context-back-button {
|
||||||
|
@extend .back-button;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
.personal-self-intro-content-editor {
|
.personal-self-intro-content-editor {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
@extend .border;
|
@extend .border;
|
||||||
@ -1818,4 +1935,8 @@ export default {
|
|||||||
@extend .m-auto;
|
@extend .m-auto;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.offcanvas-parent {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -284,14 +284,13 @@ export default {
|
|||||||
back() {
|
back() {
|
||||||
this.mnx_goBack()
|
this.mnx_goBack()
|
||||||
},
|
},
|
||||||
coverLetterDone($event) {
|
coverLetterDone(event) {
|
||||||
this.proposal.content = event.target.innerHTML
|
this.proposal.content = event.target.innerHTML
|
||||||
},
|
},
|
||||||
submit() {
|
submit() {
|
||||||
if (this.uploadFile) {
|
if (this.uploadFile) {
|
||||||
DocumentApi.upload(this.uploadFile)
|
DocumentApi.upload(this.uploadFile)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log(response.data.document_id)
|
|
||||||
return RequestHubApi.makeProposalForRequest(
|
return RequestHubApi.makeProposalForRequest(
|
||||||
this.requestId,
|
this.requestId,
|
||||||
this.proposal.content,
|
this.proposal.content,
|
||||||
|
|||||||
@ -693,15 +693,15 @@ export default {
|
|||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
if (milestone.status === milestoneStatusEnum.IMPLEMENTING) {
|
if (milestone.status === milestoneStatusEnum.IMPLEMENTING) {
|
||||||
if (project.current_user_id === project.proposer_id) {
|
if (project.providers.includes(project.current_user_id)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else if (milestone.status === milestoneStatusEnum.OUTSTANDING) {
|
} else if (milestone.status === milestoneStatusEnum.OUTSTANDING) {
|
||||||
if (project.current_user_id === project.requester_id) {
|
if (project.issuers.includes(project.current_user_id)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else if (milestone.status === milestoneStatusEnum.PAID) {
|
} else if (milestone.status === milestoneStatusEnum.PAID) {
|
||||||
if (project.current_user_id === project.proposer_id) {
|
if (project.providers.includes(project.current_user_id)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -711,7 +711,7 @@ export default {
|
|||||||
handleMilestoneAction(project, milestone) {
|
handleMilestoneAction(project, milestone) {
|
||||||
if (milestone.index === project.current_milestone) {
|
if (milestone.index === project.current_milestone) {
|
||||||
if (milestone.status === milestoneStatusEnum.IMPLEMENTING) {
|
if (milestone.status === milestoneStatusEnum.IMPLEMENTING) {
|
||||||
if (project.current_user_id === project.proposer_id) {
|
if (project.providers.includes(project.current_user_id)) {
|
||||||
WorksapceApi.setMillestoneStatus(
|
WorksapceApi.setMillestoneStatus(
|
||||||
project.id,
|
project.id,
|
||||||
milestone.index,
|
milestone.index,
|
||||||
@ -725,7 +725,7 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (milestone.status === milestoneStatusEnum.OUTSTANDING) {
|
} else if (milestone.status === milestoneStatusEnum.OUTSTANDING) {
|
||||||
if (project.current_user_id === project.requester_id) {
|
if (project.issuers.includes(project.current_user_id)) {
|
||||||
WorksapceApi.createMilestoneCheckoutSession(project.id, milestone.index).then(
|
WorksapceApi.createMilestoneCheckoutSession(project.id, milestone.index).then(
|
||||||
(response) => {
|
(response) => {
|
||||||
if (response.data.result) {
|
if (response.data.result) {
|
||||||
@ -740,7 +740,7 @@ export default {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (milestone.status === milestoneStatusEnum.PAID) {
|
} else if (milestone.status === milestoneStatusEnum.PAID) {
|
||||||
if (project.current_user_id === project.proposer_id) {
|
if (project.providers.includes(project.current_user_id)) {
|
||||||
WorksapceApi.setMillestoneStatus(project.id, milestone.index, milestoneStatusEnum.DONE)
|
WorksapceApi.setMillestoneStatus(project.id, milestone.index, milestoneStatusEnum.DONE)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.fetchView()
|
this.fetchView()
|
||||||
@ -766,19 +766,19 @@ export default {
|
|||||||
return 'Operation Complete'
|
return 'Operation Complete'
|
||||||
} else if (milestone.index === project.current_milestone) {
|
} else if (milestone.index === project.current_milestone) {
|
||||||
if (milestone.status === milestoneStatusEnum.IMPLEMENTING) {
|
if (milestone.status === milestoneStatusEnum.IMPLEMENTING) {
|
||||||
if (project.current_user_id === project.requester_id) {
|
if (project.issuers.includes(project.current_user_id)) {
|
||||||
return 'Wait for completion'
|
return 'Wait for completion'
|
||||||
} else {
|
} else {
|
||||||
return 'Mission complete'
|
return 'Mission complete'
|
||||||
}
|
}
|
||||||
} else if (milestone.status === milestoneStatusEnum.OUTSTANDING) {
|
} else if (milestone.status === milestoneStatusEnum.OUTSTANDING) {
|
||||||
if (project.current_user_id === project.requester_id) {
|
if (project.issuers.includes(project.current_user_id)) {
|
||||||
return 'Payment'
|
return 'Payment'
|
||||||
} else {
|
} else {
|
||||||
return 'Wait for payment'
|
return 'Wait for payment'
|
||||||
}
|
}
|
||||||
} else if (milestone.status === milestoneStatusEnum.PAID) {
|
} else if (milestone.status === milestoneStatusEnum.PAID) {
|
||||||
if (project.current_user_id === project.requester_id) {
|
if (project.issuers.includes(project.current_user_id)) {
|
||||||
return 'Wait for confirmation'
|
return 'Wait for confirmation'
|
||||||
} else {
|
} else {
|
||||||
return 'Confirm receipt'
|
return 'Confirm receipt'
|
||||||
@ -889,17 +889,17 @@ export default {
|
|||||||
switch (issue.status) {
|
switch (issue.status) {
|
||||||
case projectIssueStatusEnum.OPEN:
|
case projectIssueStatusEnum.OPEN:
|
||||||
if (button_text === 'Resolve') {
|
if (button_text === 'Resolve') {
|
||||||
return project.current_user_id === project.proposer_id
|
return project.providers.includes(project.current_user_id)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
if (button_text === 'Reopen' || button_text === 'Confirm') {
|
if (button_text === 'Reopen' || button_text === 'Confirm') {
|
||||||
return project.current_user_id === project.requester_id
|
return project.issuers.includes(project.current_user_id)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case projectIssueStatusEnum.CLOSED:
|
case projectIssueStatusEnum.CLOSED:
|
||||||
if (button_text === 'Reopen') {
|
if (button_text === 'Reopen') {
|
||||||
return project.current_user_id === project.requester_id
|
return project.issuers.includes(project.current_user_id)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import * as pdfjsLib from 'pdfjs-dist'
|
import * as pdfjsLib from 'pdfjs-dist'
|
||||||
|
//need to set worker before the pdfjs can be used.
|
||||||
//pdfjsLib.GlobalWorkerOptions.workerPort = new Worker()
|
// pdfjsLib.GlobalWorkerOptions.workerPort = new Worker(
|
||||||
//new URL('pdfjs-dist/build/pdf.worker.js', import.meta.url)
|
// new URL('pdfjs-dist/build/pdf.worker.mjs', import.meta.url)
|
||||||
|
// )
|
||||||
|
|
||||||
export { pdfjsLib }
|
export { pdfjsLib }
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { store, userRoleEnum } from '../store/index'
|
import { store, userRoleEnum } from '../store/index'
|
||||||
|
|
||||||
//public
|
//public
|
||||||
import About from '../../pages/public/About.vue'
|
import About from '../../pages/public/About.vue'
|
||||||
import Blogs from '../../pages/public/Blogs.vue'
|
import Blogs from '../../pages/public/Blogs.vue'
|
||||||
import Career from '../../pages/public/Career.vue'
|
import Career from '../../pages/public/Career.vue'
|
||||||
import Contact from '../../pages/public/Contact.vue'
|
import Contact from '../../pages/public/Contact.vue'
|
||||||
|
import PdfContentViewer from '../../pages/public/PdfContentViewer.vue'
|
||||||
|
import LinkContentViewer from '../../pages/public/LinkContentViewer.vue'
|
||||||
|
|
||||||
//guest
|
//guest
|
||||||
import FrontDoor from '../../pages/guest/FrontDoor.vue'
|
import FrontDoor from '../../pages/guest/FrontDoor.vue'
|
||||||
@ -107,6 +110,21 @@ const router = createRouter({
|
|||||||
components: { default: Contact, footer: FooterGuest, header: HeaderGuest }
|
components: { default: Contact, footer: FooterGuest, header: HeaderGuest }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'pdf-content-viewer',
|
||||||
|
path: '/pdf-content-viewer/:content_id',
|
||||||
|
meta: { requiredRoles: [userRoleEnum.NONE] },
|
||||||
|
components: { default: PdfContentViewer, footer: FooterGuest, header: HeaderGuest },
|
||||||
|
props: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'link-content-viewer',
|
||||||
|
path: '/link-content-viewer/:content_link_based64',
|
||||||
|
meta: { requiredRoles: [userRoleEnum.NONE] },
|
||||||
|
components: { default: LinkContentViewer, footer: FooterGuest, header: HeaderGuest },
|
||||||
|
props: true
|
||||||
|
},
|
||||||
|
|
||||||
// guest
|
// guest
|
||||||
{
|
{
|
||||||
name: 'front-door',
|
name: 'front-door',
|
||||||
|
|||||||
23
frontend/src/utils/backend/content.js
Normal file
23
frontend/src/utils/backend/content.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { backendAxios } from './axios'
|
||||||
|
class ContentApi {
|
||||||
|
static retrieve_blogs() {
|
||||||
|
const request = backendAxios.post('/api/content/retrieve-blogs', {}, {})
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
static retrieve_blog_content(document_id) {
|
||||||
|
const request = backendAxios.post(
|
||||||
|
'/api/content/retrieve-blog-content',
|
||||||
|
{
|
||||||
|
document_id: document_id
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
|
||||||
|
static retrieve_about_directories() {
|
||||||
|
const request = backendAxios.post('/api/content/retrieve-about-directories', {}, {})
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { ContentApi }
|
||||||
@ -6,3 +6,4 @@ export { ProviderHubApi } from './providerHub'
|
|||||||
export { MessageHubApi } from './messageHub'
|
export { MessageHubApi } from './messageHub'
|
||||||
export { DocumentApi } from './document'
|
export { DocumentApi } from './document'
|
||||||
export { HistoryApi } from './history'
|
export { HistoryApi } from './history'
|
||||||
|
export { ContentApi } from './content'
|
||||||
|
|||||||
@ -208,5 +208,18 @@ class UserProfileApi {
|
|||||||
)
|
)
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
static fetchSelfIntroTemplates(tags) {
|
||||||
|
let jwt = userUtils.getJwtToken()
|
||||||
|
const request = backendAxios.post(
|
||||||
|
'/api/user/profile/fetch-templates-for-self-intro',
|
||||||
|
{
|
||||||
|
tags: tags
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: { Authorization: `Bearer ${jwt}` }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return request
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export { UserProfileApi }
|
export { UserProfileApi }
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export { textAreaAujuster } from './textArea'
|
export { textAreaAujuster } from './textArea'
|
||||||
export { tooltip } from './tooltip'
|
export { tooltip } from './tooltip'
|
||||||
export { elementHandler } from './element'
|
export { elementHandler } from './element'
|
||||||
|
export { mediaDataHandler } from './mediaData'
|
||||||
|
|||||||
12
frontend/src/utils/html/mediaData.js
Normal file
12
frontend/src/utils/html/mediaData.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
class MediaDataHandler {
|
||||||
|
retrieveText(mediaData) {
|
||||||
|
let prefix = 'data:text/plain;base64,'
|
||||||
|
let pos = mediaData.search(prefix)
|
||||||
|
if (pos < 0) return ''
|
||||||
|
return atob(mediaData.substring(pos + prefix.length))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mediaDataHandler = new MediaDataHandler()
|
||||||
|
|
||||||
|
export { mediaDataHandler }
|
||||||
@ -6,7 +6,8 @@ export {
|
|||||||
ProviderHubApi,
|
ProviderHubApi,
|
||||||
MessageHubApi,
|
MessageHubApi,
|
||||||
DocumentApi,
|
DocumentApi,
|
||||||
HistoryApi
|
HistoryApi,
|
||||||
|
ContentApi
|
||||||
} from './backend/index'
|
} from './backend/index'
|
||||||
|
|
||||||
export { userUtils, userProfileUtils, requestIssueUtils, requestHubUtils } from './store/index'
|
export { userUtils, userProfileUtils, requestIssueUtils, requestHubUtils } from './store/index'
|
||||||
@ -15,4 +16,4 @@ export { ValueChecker, DateUtils, OIDUtils } from './common/index'
|
|||||||
|
|
||||||
export { userProfileValidator } from './validator/index'
|
export { userProfileValidator } from './validator/index'
|
||||||
|
|
||||||
export { textAreaAujuster, tooltip, elementHandler } from './html/index'
|
export { textAreaAujuster, tooltip, elementHandler, mediaDataHandler } from './html/index'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user