Skip to content

Commit

Permalink
[OP#41102] UI of adding link to workpackage (#64)
Browse files Browse the repository at this point in the history
* [OP#41102] UI of adding link to workpackage

Co-authored-by: Swikriti Tripathi <swikriti808@gmail.com>
Signed-off-by: Artur Neumann <artur@jankaritech.com>
Signed-off-by: Swikriti Tripathi <swikriti808@gmail.com>
  • Loading branch information
individual-it and SwikritiT authored Mar 10, 2022
1 parent 510f7a6 commit 0a3900b
Show file tree
Hide file tree
Showing 11 changed files with 446 additions and 165 deletions.
1 change: 1 addition & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
['name' => 'openProjectAPI#getOpenProjectUrl', 'url' => '/url', 'verb' => 'GET'],
['name' => 'openProjectAPI#getOpenProjectAvatar', 'url' => '/avatar', 'verb' => 'GET'],
['name' => 'openProjectAPI#getSearchedWorkPackages', 'url' => '/work-packages', 'verb' => 'GET'],
['name' => 'openProjectAPI#linkWorkPackageToFile', 'url' => '/work-packages', 'verb' => 'POST'],
['name' => 'openProjectAPI#getOpenProjectWorkPackageStatus', 'url' => '/statuses/{id}', 'verb' => 'GET'],
['name' => 'openProjectAPI#getOpenProjectWorkPackageType', 'url' => '/types/{id}', 'verb' => 'GET'],
]
Expand Down
11 changes: 11 additions & 0 deletions lib/Controller/OpenProjectAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ public function getNotifications(?string $since = null): DataResponse {
}
return $response;
}

/**
* get searched work packages
*
Expand Down Expand Up @@ -163,6 +164,16 @@ public function getSearchedWorkPackages(?string $searchQuery = null, ?int $fileI
return $response;
}

/**
* @NoAdminRequired
* @param int $workpackageId
* @param int $fileId
* @return DataResponse
*/
public function linkWorkPackageToFile(int $workpackageId = 0, int $fileId = 0): DataResponse {
return new DataResponse("Fake result, to make UI happy");
}

/**
* get status of work packages
*
Expand Down
179 changes: 52 additions & 127 deletions src/components/tab/SearchInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,18 @@
:options="searchResults"
:user-select="true"
label="displayName"
track-by="multiselectKey"
track-by="id"
:internal-search="false"
open-direction="below"
:loading="isStateLoading"
:preselect-first="true"
:preserve-search="true"
@search-change="makeSearchRequest">
@search-change="makeSearchRequest"
@change="linkWorkPackageToFile">
<template #option="{option}">
<div class="searchList">
<div class="searchList__filterWorkPackage">
<div class="filterProjectTypeStatus">
<div class="filterProjectTypeStatus__project">
{{ option.project }}
</div>
<div class="filterProjectTypeStatus__type" :style="{'color':option.typeCol}">
{{ option.typeTitle }}
</div>
<div class="filterProjectTypeStatus__status"
:style="{'background-color':option.statusCol}">
<div class="filterProjectTypeStatus__status__title">
{{ option.statusTitle }}
</div>
</div>
</div>
<div v-if="option.assignee" class="filterAssignee">
<div class="filterAssignee__avatar">
<Avatar
class="item-avatar"
:size="25"
:url="option.picture"
:user="option.assignee"
:display-name="option.assignee" />
</div>
<div class="filterAssignee__assignee">
{{ option.assignee }}
</div>
</div>
</div>
<div class="filterWorkpackageSubject">
<div class="filterWorkpackageSubject__subject">
{{ option.subject }}
</div>
</div>
</div>
<WorkPackage
:key="option.id"
:workpackage="option" />
</template>
<template #noOptions>
{{ translate('Start typing to search') }}
Expand All @@ -66,8 +34,9 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { translate as t } from '@nextcloud/l10n'
import Avatar from '@nextcloud/vue/dist/Components/Avatar'
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
import WorkPackage from './WorkPackage'
import { showError } from '@nextcloud/dialogs'
const STATE_OK = 'ok'
const STATE_ERROR = 'error'
Expand All @@ -78,12 +47,19 @@ const SEARCH_CHAR_LIMIT = 3
export default {
name: 'SearchInput',
components: {
Avatar,
Multiselect,
WorkPackage,
},
props: {
fileInfo: {
type: Object,
required: true,
},
},
data: () => ({
state: STATE_OK,
searchResults: [],
selectedId: [],
}),
computed: {
isStateOk() {
Expand Down Expand Up @@ -126,6 +102,27 @@ export default {
? href.replace(/.*\//, '')
: null
},
async linkWorkPackageToFile(selectedOption) {
const req = {
values: {
workpackageId: selectedOption.id,
fileId: this.fileInfo.id,
},
}
const url = generateUrl('/apps/integration_openproject/work-packages')
try {
await axios.post(url, req)
this.$emit('saved', selectedOption)
this.selectedId.push({
id: selectedOption.id,
})
} catch (e) {
showError(
this.translate('Failed to link file to work-package')
)
}
},
async makeSearchRequest(search) {
if (search.length <= SEARCH_CHAR_LIMIT) {
this.resetState()
Expand Down Expand Up @@ -160,17 +157,21 @@ export default {
+ '=' + userName
const statusColor = await this.getWorkPackageColorAttributes('/apps/integration_openproject/statuses/', statusId)
const typeColor = await this.getWorkPackageColorAttributes('/apps/integration_openproject/types/', typeId)
this.searchResults.push({
id: workPackage.id,
subject: workPackage.subject,
project: workPackage._links.project.title,
statusTitle: workPackage._links.status.title,
typeTitle: workPackage._links.type.title,
assignee: userName,
statusCol: statusColor,
typeCol: typeColor,
picture: avatarUrl,
})
const selectedIdFound = this.selectedId.some(el => el.id === workPackage.id)
const workpackageIdFound = this.searchResults.some(el => el.id === workPackage.id)
if (!workpackageIdFound && !selectedIdFound) {
this.searchResults.push({
id: workPackage.id,
subject: workPackage.subject,
project: workPackage._links.project.title,
statusTitle: workPackage._links.status.title,
typeTitle: workPackage._links.type.title,
assignee: userName,
statusCol: statusColor,
typeCol: typeColor,
picture: avatarUrl,
})
}
}
},
async getWorkPackageColorAttributes(path, id) {
Expand Down Expand Up @@ -200,80 +201,4 @@ export default {
color: #6d6d6d;
}
.searchList {
display: flex;
flex-direction: column;
justify-content: space-between;
&__filterWorkPackage {
margin-top: 8px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.filterProjectTypeStatus {
display: flex;
justify-content: space-between;
&__project {
padding: 6px 6px 6px 12px;
color: #6d6d6d;
font-size: 0.87rem;
}
&__type {
padding: 6px;
text-transform: uppercase;
font-size: 0.87rem;
}
&__status {
margin: 6px;
width: 90px;
height: 25px;
text-align: center;
font-size: 0.75rem;
border-radius: 3px;
&__title {
mix-blend-mode: multiply;
}
}
}
.filterAssignee {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
position: absolute;
right: 0;
&__avatar {
padding: 6px;
}
&__assignee {
padding: 6px 12px 6px 6px;
font-size: 0.81rem;
color: #0096FF;
text-align: center;
}
}
}
.filterWorkpackageSubject {
margin: 12px;
text-align: justify;
&__subject {
font-weight: bold;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
</style>
Loading

0 comments on commit 0a3900b

Please sign in to comment.