Merged in feature/PMCORE-2521 (pull request #7592)

PMCORE-2521

Approved-by: Rodrigo Quelca
This commit is contained in:
Henry Jonathan Quispe Quispe
2020-12-08 21:13:49 +00:00
committed by Rodrigo Quelca
11 changed files with 480 additions and 115 deletions

10
package-lock.json generated
View File

@@ -10897,11 +10897,6 @@
"vue": "^2.5.21"
}
},
"vue-slim-tabs": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/vue-slim-tabs/-/vue-slim-tabs-0.4.0.tgz",
"integrity": "sha512-19bwuKs2HICja0E039QmE7N7PMQcjdZXcpigmXlJTtTYGZy40C112tZF6q7bS18XNZGFcd/sP3jOJRGC80gVVw=="
},
"vue-split-panel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/vue-split-panel/-/vue-split-panel-1.0.4.tgz",
@@ -10934,6 +10929,11 @@
"vue-pagination-2": "^3.0"
}
},
"vue-tabs-component": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/vue-tabs-component/-/vue-tabs-component-1.5.0.tgz",
"integrity": "sha512-ld4p+hv49Fimw+zv/7GQqMhbjAHjpbWF3UiJtmMaSnvLKbsB1ysfs9dQH0SZ8NvdYpqqKay/VLIqR9yXgse1Sg=="
},
"vue-template-compiler": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",

View File

@@ -52,7 +52,6 @@
"vue-router": "^3.4.9",
"vue-search-select": "^2.7.0",
"vue-sidebar-menu": "^4.5.1",
"vue-slim-tabs": "^0.4.0",
"vue-split-panel": "^1.0.4",
"vue-tables-2": "^2.1.46",
"vue-upload-component": "^2.8.20",
@@ -62,4 +61,4 @@
"vuetify": "^1.1.4",
"web-animations-js": "^2.3.2"
}
}
}

View File

@@ -45,6 +45,14 @@ export let cases = {
keys: {}
});
},
summary(data) {
return Api.get({
service: "UNASSIGNED_LIST",
params: {
},
keys: {}
});
},
inputdocuments(data) {
var params = new FormData();
params.append('appUid', data.APP_UID);

View File

@@ -1,38 +0,0 @@
<template>
<Tabs>
<Tab
v-for="item in data.items"
:key="item.title"
:title="item.title"
v-on:click="selectedTab"
>
{{ item.title }}
</Tab>
</Tabs>
</template>
<script>
import { Tabs, Tab } from "vue-slim-tabs";
export default {
props: {
data: Object,
},
components: {
Tabs,
Tab,
},
data() {
return {
0: function () {},
};
},
methods: {
selectedTab(e, index) {
if (index === 0) {
}
},
},
};
</script>
<style src="vue-slim-tabs/themes/default.css"></style>

View File

@@ -0,0 +1,56 @@
<template>
<div class="card v-pmase-summary-card">
<div class="card-body">
<div
v-for="section in data"
:key="section.title"
class="v-attached-block"
>
<h6 class="card-subtitle mb-2 text-muted">{{ section.title }}</h6>
<div class="card-text v-pmcase-summary-card-body">
<div
v-for="item in section.items"
:key="item.title"
class="v-attached-block"
>
<span> {{ item.label }} </span>:<span class="font-weight-bold">
{{ item.value }}</span
>
</div>
</div>
<br />
</div>
</div>
</div>
</template>
<script>
export default {
name: "CaseSummary",
props: {
data: Object,
},
data() {
return {};
},
methods: {
classBtn(cls) {
return "btn v-btn-request " + cls;
},
},
};
</script>
<style>
.v-pmcase-summary-card {
font-size: 13px;
}
.v-pmcase-summary-card-body {
padding-left: 15px;
}
.v-pmcase-summary-center {
text-align: center;
}
</style>

View File

@@ -1,40 +0,0 @@
<template>
<Tabs>
<Tab
v-for="item in data.items"
:key="item.title"
:title="item.title"
v-on:click="selectedTab"
>
{{ item.title }}
</Tab>
</Tabs>
</template>
<script>
import { Tabs, Tab } from "vue-slim-tabs";
export default {
props: {
data: Object,
},
components: {
Tabs,
Tab,
},
data() {
return {
0: function () {
},
};
},
methods: {
selectedTab(e, index) {
if (index === 0) {
}
},
},
};
</script>
<style src="vue-slim-tabs/themes/default.css"></style>

View File

@@ -0,0 +1,41 @@
<template>
<section
v-show="isActive"
:aria-hidden="!isActive"
class="tabs-component-panel"
:id="computedId"
role="tabpanel"
>
<slot />
</section>
</template>
<script>
export default {
props: {
id: { default: null },
name: { required: true },
prefix: { default: "" },
suffix: { default: "" },
isDisabled: { default: false },
},
data: () => ({
isActive: false,
isVisible: true,
}),
computed: {
header() {
return this.prefix + this.name + this.suffix;
},
computedId() {
return this.id ? this.id : this.name.toLowerCase().replace(/ /g, "-");
},
hash() {
if (this.isDisabled) {
return "#";
}
return "#" + this.computedId;
},
},
};
</script>

View File

@@ -0,0 +1,160 @@
<template>
<div class="tabs-component">
<ul role="tablist" class="tabs-component-tabs">
<li
v-for="(tab, i) in tabs"
:key="i"
:class="{ 'is-active': tab.isActive, 'is-disabled': tab.isDisabled }"
class="tabs-component-tab"
role="presentation"
v-show="tab.isVisible"
>
<span
v-html="tab.header"
:aria-controls="tab.hash"
:aria-selected="tab.isActive"
@click="selectTab(tab.hash, $event)"
class="tabs-component-tab-a"
role="tab"
></span>
</li>
</ul>
<div class="tabs-component-panels">
<slot />
</div>
</div>
</template>
<script>
import expiringStorage from "./expiringStorage";
export default {
props: {
cacheLifetime: {
default: 5,
},
options: {
type: Object,
required: false,
default: () => ({
useUrlFragment: true,
defaultTabHash: null,
}),
},
},
data: () => ({
tabs: [],
activeTabHash: "",
activeTabIndex: 0,
lastActiveTabHash: "",
}),
computed: {
storageKey() {
return `vue-tabs-component.cache.${window.location.host}${window.location.pathname}`;
},
},
created() {
this.tabs = this.$children;
},
mounted() {
window.addEventListener("hashchange", () =>
this.selectTab(window.location.hash)
);
if (this.findTab(window.location.hash)) {
this.selectTab(window.location.hash);
return;
}
const previousSelectedTabHash = expiringStorage.get(this.storageKey);
if (this.findTab(previousSelectedTabHash)) {
this.selectTab(previousSelectedTabHash);
return;
}
if (
this.options.defaultTabHash !== null &&
this.findTab("#" + this.options.defaultTabHash)
) {
this.selectTab("#" + this.options.defaultTabHash);
return;
}
if (this.tabs.length) {
this.selectTab(this.tabs[0].hash);
}
},
methods: {
findTab(hash) {
return this.tabs.find((tab) => tab.hash === hash);
},
selectTab(selectedTabHash, event) {
// See if we should store the hash in the url fragment.
if (event && !this.options.useUrlFragment) {
event.preventDefault();
}
const selectedTab = this.findTab(selectedTabHash);
if (!selectedTab) {
return;
}
if (selectedTab.isDisabled) {
event.preventDefault();
return;
}
if (this.lastActiveTabHash === selectedTab.hash) {
this.$emit("clicked", { tab: selectedTab });
return;
}
this.tabs.forEach((tab) => {
tab.isActive = tab.hash === selectedTab.hash;
});
this.$emit("changed", { tab: selectedTab });
this.activeTabHash = selectedTab.hash;
this.activeTabIndex = this.getTabIndex(selectedTabHash);
this.lastActiveTabHash = this.activeTabHash = selectedTab.hash;
expiringStorage.set(
this.storageKey,
selectedTab.hash,
this.cacheLifetime
);
},
setTabVisible(hash, visible) {
const tab = this.findTab(hash);
if (!tab) {
return;
}
tab.isVisible = visible;
if (tab.isActive) {
// If tab is active, set a different one as active.
tab.isActive = visible;
this.tabs.every((tab, index, array) => {
if (tab.isVisible) {
tab.isActive = true;
return false;
}
return true;
});
}
},
getTabIndex(hash) {
const tab = this.findTab(hash);
return this.tabs.indexOf(tab);
},
getTabHash(index) {
const tab = this.tabs.find((tab) => this.tabs.indexOf(tab) === index);
if (!tab) {
return;
}
return tab.hash;
},
getActiveTab() {
return this.findTab(this.activeTabHash);
},
getActiveTabIndex() {
return this.getTabIndex(this.activeTabHash);
},
},
};
</script>

View File

@@ -0,0 +1,30 @@
class ExpiringStorage {
get(key) {
const cached = JSON.parse(
localStorage.getItem(key)
);
if (!cached) {
return null;
}
const expires = new Date(cached.expires);
if (expires < new Date()) {
localStorage.removeItem(key);
return null;
}
return cached.value;
}
set(key, value, lifeTimeInMinutes) {
const currentTime = new Date().getTime();
const expires = new Date(currentTime + lifeTimeInMinutes * 60000);
localStorage.setItem(key, JSON.stringify({ value, expires }));
}
}
export default new ExpiringStorage();

View File

@@ -40,7 +40,7 @@
</div>
</v-server-table>
</div>
<Tabs :data="dataTabs"></Tabs>
<TabsCaseDetail :dataCaseSummary="dataCaseSummaryTab"></TabsCaseDetail>
</div>
<div class="col-sm4">
<case-summary
@@ -73,19 +73,18 @@
</template>
<script>
import Tabs from "../components/home/caseDetail/Tabs.vue";
import IoDocuments from "../components/home/caseDetail/IoDocuments.vue";
import CaseSummary from "../components/home/caseDetail/CaseSummary.vue";
import AttachedDocuments from "../components/home/caseDetail/AttachedDocuments.vue";
import CaseComment from "../components/home/caseDetail/CaseComment";
import CaseComments from "../components/home/caseDetail/CaseComments";
import TabsCaseDetail from "../home/TabsCaseDetail.vue";
import Api from "../api/index";
export default {
name: "CaseDetail",
components: {
Tabs,
TabsCaseDetail,
IoDocuments,
CaseSummary,
AttachedDocuments,
@@ -133,6 +132,7 @@ export default {
filterable: false,
},
dataCaseSummary: null,
dataCaseSummaryTab: null,
dataIoDocuments: {
titleInput: this.$i18n.t("ID_REQUEST_DOCUMENTS"),
titleOutput: this.$i18n.t("ID_OUTPUT_DOCUMENTS"),
@@ -143,32 +143,6 @@ export default {
title: "Attached Documents",
items: [],
},
dataTabs: {
items: [
{
title: "Request Summary",
data: {
firstName: "Jason",
lastName: "Burne",
userName: "jburne@processmaker.com",
},
},
{
title: "Process Map",
data: [
{
pro_uid: "123dit",
},
],
},
{
title: "Case History",
},
{
title: "Change Log",
},
],
},
dataComments: {
title: "Comments",
items: [],
@@ -215,10 +189,12 @@ export default {
this.dataAttachedDocuments.items = att;
},
getDataCaseSummary() {
let that = this;
Api.cases
.casesummary(this.dataCase)
.then((response) => {
var data = response.data;
this.formatCaseSummary(response.data);
this.dataCaseSummary = {
title: "Case Summary",
titleActions: "Actions",
@@ -361,6 +337,27 @@ export default {
this.dataComments.items = notesArray;
},
formatCaseSummary(data) {
let index,
sections = [];
this.dataCaseSummaryTab = [];
_.each(data, (o) => {
if (
(index = _.findIndex(sections, (s) => {
return s.title == o.section;
})) == -1
) {
sections.push({
title: o.section,
items: [],
});
index = 0;
}
sections[index].items.push(o);
});
this.dataCaseSummaryTab = sections;
},
},
};
</script>

View File

@@ -0,0 +1,152 @@
<template>
<div>
<tabs>
<tab :name="$t('ID_SUMMARY')">
<PmCaseSummary :data="dataCaseSummary"> </PmCaseSummary>
</tab>
<tab name="Second tab">
<h2 class="page-subtitle">Second tab</h2>
This is the content of the second tab.
</tab>
<tab name="Disabled tab" :is-disabled="true">
<h2 class="page-subtitle">Disabled tab</h2>
This content will be unavailable while :is-disabled prop set to true
</tab>
<tab id="oh-hi-mark" name="Custom fragment">
<h2 class="page-subtitle">Custom fragment</h2>
The hash that is appended to the url can be customized.
</tab>
<tab
prefix="<span class='prefix'>→</span>"
name="Prefix and suffix"
suffix="<span class='suffix'>4</span>"
>
<h2 class="page-subtitle">Prefix and suffix</h2>
A prefix and a suffix can be added HTML allowed.
</tab>
</tabs>
</div>
</template>
<script>
import Tabs from "./../components/tabs/Tabs.vue";
import Tab from "./../components/tabs/Tab.vue";
import PmCaseSummary from "./../components/home/caseDetail/PmCaseSummary.vue";
import Api from "../api/index";
export default {
name: "TabsCaseDetail",
components: {
Tabs,
Tab,
PmCaseSummary,
},
props: {
dataCaseSummary: Array,
},
data() {
return {};
},
mounted() {},
methods: {},
};
</script>
<style>
.tabs-component {
margin: 0 0;
}
.tabs-component-tabs {
border: solid 1px #ddd;
border-radius: 6px;
margin-bottom: 5px;
}
@media (min-width: 700px) {
.tabs-component-tabs {
border: 0;
align-items: stretch;
display: flex;
justify-content: flex-start;
margin-bottom: -1px;
}
}
.tabs-component-tab {
color: #999;
font-size: 14px;
font-weight: 600;
margin-right: 0;
list-style: none;
}
.tabs-component-tab:not(:last-child) {
border-bottom: dotted 1px #ddd;
}
.tabs-component-tab:hover {
color: #666;
}
.tabs-component-tab.is-active {
color: #000;
}
.tabs-component-tab.is-disabled * {
color: #cdcdcd;
cursor: not-allowed !important;
}
@media (min-width: 700px) {
.tabs-component-tab {
background-color: #fff;
border: solid 1px #ddd;
border-radius: 3px 3px 0 0;
margin-right: 0.5em;
transform: translateY(2px);
transition: transform 0.3s ease;
}
.tabs-component-tab.is-active {
border-bottom: solid 1px #fff;
z-index: 2;
transform: translateY(0);
}
}
.tabs-component-tab-a {
align-items: center;
color: inherit;
display: flex;
padding: 0.75em 1em;
text-decoration: none;
}
.tabs-component-panels {
padding: 4em 0;
}
@media (min-width: 700px) {
.tabs-component-panels {
border-top-left-radius: 0;
background-color: #fff;
border: solid 1px #ddd;
border-radius: 0 6px 6px 6px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
padding: 0.5em 0.5em;
}
}
</style>