Merged in release/3.6.0 (pull request #7707)

Release/3.6.0

Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
Paula Quispe
2021-01-11 16:56:28 +00:00
committed by Julio Cesar Laura Avendaño
69 changed files with 1932 additions and 999 deletions

View File

@@ -35,10 +35,10 @@
"laravel/framework": "5.7.*",
"luracast/restler": "3.0",
"bshaffer/oauth2-server-php": "v1.0",
"colosa/pmui": "release/3.5.0-dev",
"colosa/michelangelofe": "release/3.5.0-dev",
"colosa/pmdynaform": "release/3.5.0-dev",
"colosa/taskscheduler": "release/1.0.0-dev",
"colosa/pmui": "release/3.6.0-dev",
"colosa/michelangelofe": "release/3.6.0-dev",
"colosa/pmdynaform": "release/3.6.0-dev",
"colosa/taskscheduler": "release/1.0.2-dev",
"google/apiclient": "1.1.6",
"dapphp/securimage": "^3.6",
"psr/log": "1.0.0",

735
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -67,6 +67,15 @@ $factory->state(\ProcessMaker\Model\Application::class, 'foreign_keys', function
];
});
$factory->state(\ProcessMaker\Model\Application::class, 'web_entry', function (Faker $faker) {
$appNumber = $faker->unique()->numberBetween(5000);
return [
'APP_NUMBER' => $appNumber * -1,
'APP_STATUS_ID' => 2,
'APP_STATUS' => 'TO_DO'
];
});
$factory->state(\ProcessMaker\Model\Application::class, 'todo', function (Faker $faker) {
return [
'APP_NUMBER' => $faker->unique()->numberBetween(1000),

View File

@@ -86,6 +86,51 @@ $factory->state(\ProcessMaker\Model\Delegation::class, 'foreign_keys', function
];
});
// Create a delegation with the foreign keys
$factory->state(\ProcessMaker\Model\Delegation::class, 'web_entry', function (Faker $faker) {
// Create values in the foreign key relations
$user = factory(\ProcessMaker\Model\User::class)->create();
$category = factory(\ProcessMaker\Model\ProcessCategory::class)->create();
$process = factory(\ProcessMaker\Model\Process::class)->create([
'PRO_CATEGORY' => $category->CATEGORY_UID,
'CATEGORY_ID' => $category->CATEGORY_ID
]);
$task = factory(\ProcessMaker\Model\Task::class)->create([
'PRO_UID' => $process->PRO_UID,
'PRO_ID' => $process->PRO_ID
]);
$application = factory(\ProcessMaker\Model\Application::class)->states('web_entry')->create([
'PRO_UID' => $process->PRO_UID,
'APP_INIT_USER' => $user->USR_UID,
'APP_CUR_USER' => $user->USR_UID
]);
// Return with default values
return [
'DELEGATION_ID' => $faker->unique()->numberBetween(5000),
'APP_UID' => $application->APP_UID,
'DEL_INDEX' => 1,
'APP_NUMBER' => $application->APP_NUMBER,
'DEL_PREVIOUS' => 0,
'PRO_UID' => $process->PRO_UID,
'TAS_UID' => $task->TAS_UID,
'USR_UID' => $user->USR_UID,
'DEL_TYPE' => 'NORMAL',
'DEL_THREAD' => 1,
'DEL_THREAD_STATUS' => 'OPEN',
'DEL_PRIORITY' => 3,
'DEL_DELEGATE_DATE' => $faker->dateTime(),
'DEL_INIT_DATE' => $faker->dateTime(),
'DEL_TASK_DUE_DATE' => $faker->dateTime(),
'DEL_RISK_DATE' => $faker->dateTime(),
'USR_ID' => $user->USR_ID,
'PRO_ID' => $process->PRO_ID,
'TAS_ID' => $task->TAS_ID,
'DEL_DATA' => '',
'DEL_TITLE' => $faker->word()
];
});
// Create a open delegation
$factory->state(\ProcessMaker\Model\Delegation::class, 'open', function (Faker $faker) {
// Create dates with sense

View File

@@ -16,6 +16,8 @@
*/
require_once 'classes/model/om/BaseAuthenticationSource.php';
use Illuminate\Support\Facades\Log;
/**
* @package rbac-classes-model
*/
@@ -69,6 +71,7 @@ class AuthenticationSource extends BaseAuthenticationSource {
$oConnection->begin();
$iResult = $oAuthenticationSource->save();
$oConnection->commit();
Log::channel(':ldapAdvanced')->info("create", Bootstrap::context($aData));
$authSourceServerName = isset($aData['AUTH_SOURCE_SERVER_NAME']) ? ' - Server Name: '.$aData['AUTH_SOURCE_SERVER_NAME'] : '';
$authSourcePort = isset($aData['AUTH_SOURCE_PORT']) ? ' - Port: '.$aData['AUTH_SOURCE_PORT'] : '';
@@ -122,6 +125,7 @@ class AuthenticationSource extends BaseAuthenticationSource {
$oConnection->begin();
$iResult = $oAuthenticationSource->save();
$oConnection->commit();
Log::channel(':ldapAdvanced')->info("update", Bootstrap::context($aData));
G::auditLog("UpdateAuthSource", "Authentication Source Name: ".$aData['AUTH_SOURCE_NAME']." - Authentication Source ID: (".$aData['AUTH_SOURCE_UID'].") ".$authSourceServerName.$authSourcePort.$authSourceEnabledTLS.$authSourceVersion.$authSourceBaseDn.$authAnonymous.$authSourceSearchUser.$authSourceLdapType.$authSourceIdentifier.$authSourceFilter);
return $iResult;
}
@@ -131,6 +135,7 @@ class AuthenticationSource extends BaseAuthenticationSource {
foreach($aValidationFailures as $oValidationFailure) {
$sMessage .= $oValidationFailure->getMessage() . '<br />';
}
Log::channel(':ldapAdvanced')->error($sMessage, Bootstrap::context($aData));
throw(new Exception('The registry cannot be updated!<br />'.$sMessage));
}
}
@@ -158,6 +163,7 @@ class AuthenticationSource extends BaseAuthenticationSource {
$oConnection->begin();
$iResult = $oAuthenticationSource->delete();
$oConnection->commit();
Log::channel(':ldapAdvanced')->info("remove", Bootstrap::context(["AUTH_SOURCE_UID" => $sUID]));
G::auditLog("DeleteAuthSource", "Authentication Source Name: ".$authenticationSource['AUTH_SOURCE_NAME']." Authentication Source ID: (".$sUID.") ");
return $iResult;

View File

@@ -14,7 +14,7 @@ const services = {
GET_LISTS_COMPLETED: "/light/completed",
GET_USERS_PICTURES: "/light/users/data",
FORMS_ARRAY: "/light/project/{pro_uid}/activity/{act_uid}/steps",
GET_NEW_CASES: "/light/start-case",
GET_NEW_CASES: "/case/start-cases?type_view=category",
GET_HISTORY_CASES: "/light/history/{app_uid}",
LOGOUT_USER: "/light/logout",
UPLOAD_LOCATION: "/light/case/{app_uid}/upload/location",

View File

@@ -111,6 +111,11 @@ export let cases = {
window.config.SYS_URI +
`cases/open?APP_UID=${data.APP_UID}&DEL_INDEX=${data.DEL_INDEX}&action=${data.ACTION}`);
},
cases_open(data) {
return axios.get(window.config.SYS_SERVER +
window.config.SYS_URI +
`cases/cases_Open?APP_UID=${data.APP_UID}&DEL_INDEX=${data.DEL_INDEX}&action=${data.ACTION}`);
},
cancel(data) {
var params = new URLSearchParams();
params.append('action', 'cancelCase');

View File

@@ -58,7 +58,7 @@
>
</div>
<button class="btn btn-success btn-sm" @click="onClickComment">
<button class="btn btn-success btn-sm" @click="onClickComment" :disabled="data.noPerms === 1">
{{ $t("ID_SEND") }}
</button>
</div>

View File

@@ -5,7 +5,7 @@
<div class="card-text">
<div
v-for="item in data.inputDocuments"
:key="item.title"
:key="item.data.APP_DOC_UID"
class="v-attached-block"
>
<div class="v-list v-list-row block">
@@ -79,6 +79,13 @@ export default {
return this.icon[icon] ? this.icon[icon] : "fas fa-file-alt";
},
href(item) {
if (item.data.DOWNLOAD_LINK) {
return (
window.config.SYS_SERVER +
window.config.SYS_URI +
`cases/${item.data.DOWNLOAD_LINK}`
);
}
return (
window.config.SYS_SERVER +
window.config.SYS_URI +

View File

@@ -15,7 +15,7 @@
export default {
name: "ProcessMap",
props: {
data: Object,
data: Object
},
data() {
return {

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@
<b-form-group
:state="valueState"
label-for="name-input"
:invalid-feedback="$t('ID_INVALID_CASE_NUMBER_RANGE')"
:invalid-feedback="$t('ID_INVALID_CASE_NUMBER')"
>
<b-form-input
id="name-input"

View File

@@ -9,14 +9,14 @@
<h6>{{ info.detail }}</h6>
<b-form-group :label="info.label">
<b-form-checkbox
v-for="option in info.options"
v-model="info.caseStatuses"
v-for="option in info.items[0].options"
v-model="filter[0].options"
:key="option.value"
:value="option.value"
name="flavour-2a"
stacked
>
{{ option.text }}
{{ option.label }}
</b-form-checkbox>
</b-form-group>
</template>
@@ -31,7 +31,7 @@ export default {
components: {
SearchPopover
},
props: ["tag", "info"],
props: ["tag", "info", "filter"],
methods: {
/**
* Ok button handler
@@ -43,17 +43,18 @@ export default {
* Submit button handler
*/
handleSubmit() {
let selectedOptions = [];
let self = this;
_.forEach(this.info.caseStatuses, function(value) {
selectedOptions.push(_.find(self.info.options, function(o) { return o.value === value; }));
});
this.$emit("updateSearchTag", {
CaseStatus: {
caseStatuses: this.info.caseStatuses.join(","),
selectedOptions: selectedOptions
let selectedLabels = [],
self = this,
item;
this.filter[0].value=this.filter[0].options.join(",");
_.forEach(this.filter[0].options, function(value) {
item = _.find(self.info.items[0].options, function(o) { return o.value === value; });
if (item) {
selectedLabels.push(item.label);
}
});
this.filter[0].label=selectedLabels.join(",");
this.$emit("updateSearchTag", this.filter);
this.$root.$emit("bv::hide::popover")
},
/**

View File

@@ -8,7 +8,8 @@
ref="popover"
triggers="click"
placement="bottom"
class="popovercustom"
class="popovercustom"
@show="onshow"
>
<template #title>
<b-button @click="onClose" class="close" aria-label="Close">
@@ -47,6 +48,12 @@ export default {
*/
onSave() {
this.$emit('savePopover');
},
/**
* Show popover event handler
*/
onshow() {
this.$root.$emit('bv::hide::popover');
}
}
};

View File

@@ -1,6 +1,6 @@
<template>
<div v-if="data.length" class="grouped-cell">
<div v-for="item in data" class="d-flex mb-3">
<div v-for="item in data" v-bind:key="item.TITLE" class="d-flex mb-3">
<div
v-bind:style="{ color: activeColor(item.STATUS) }"
v-b-popover.hover.top="item.DELAYED_MSG"

View File

@@ -1,6 +1,6 @@
<template>
<div class="v-task-cell">
<div v-for="item in data" class="d-flex mb-3">
<div v-for="item in data" v-bind:key="item.TITLE" class="d-flex mb-3">
<div v-bind:style="{ color: activeColor(item.CODE_COLOR) }">
<i class="fas fa-square"></i>
</div>

View File

@@ -29,7 +29,7 @@
:data="tableData"
:columns="columns"
:options="options"
ref="test"
ref="vueTable"
>
<div slot="info" slot-scope="props">
<b-icon
@@ -66,17 +66,19 @@
<div slot="finish_date" slot-scope="props">
{{ props.row.FINISH_DATE }}
</div>
<div slot="duration" slot-scope="props">
<div slot="duration" slot-scope="props">
{{ props.row.DURATION }}
</div>
<div slot="actions" slot-scope="props">
<div class="btn-default">
<i class="fas fa-comments"></i>
<span class="badge badge-light">9</span>
<span class="sr-only">unread messages</span>
<div slot="actions" slot-scope="props">
<div class="btn-default" v-bind:style="{ color: props.row.MESSAGE_COLOR}" @click="openComments(props.row)">
<span class="fas fa-comments"></span>
</div>
</div>
</v-server-table>
<ModalComments
ref="modal-comments"
@postNotes="onPostNotes"
></ModalComments>
</div>
</template>
<script>
@@ -84,6 +86,7 @@ import ButtonFleft from "../components/home/ButtonFleft.vue";
import ModalNewRequest from "./ModalNewRequest.vue";
import AdvancedFilter from "../components/search/AdvancedFilter";
import TaskCell from "../components/vuetable/TaskCell.vue";
import ModalComments from "./modal/ModalComments.vue";
import api from "./../api/index";
import { Event } from "vue-tables-2";
@@ -93,7 +96,8 @@ export default {
AdvancedFilter,
ButtonFleft,
ModalNewRequest,
TaskCell
TaskCell,
ModalComments
},
props: ["id", "name", "filters"],
data() {
@@ -155,12 +159,12 @@ export default {
},
customFilters: ["myfilter"],
},
pmDateFormat: "Y-m-d H:i:s",
pmDateFormat: window.config.FORMATS.dateFormat
};
},
watch: {
id: function() {
this.$refs.test.refresh();
this.$refs.vueTable.refresh();
},
},
methods: {
@@ -198,7 +202,7 @@ export default {
});
},
/**
* Format Response API TODO to grid todo and columns
* Format the service response
*/
formatDataResponse(response) {
let data = [];
@@ -214,6 +218,9 @@ export default {
DURATION: v.DURATION,
DEL_INDEX: v.DEL_INDEX,
APP_UID: v.APP_UID,
PRO_UID: v.PRO_UID,
TAS_UID: v.TAS_UID,
MESSAGE_COLOR: v.CASE_NOTES_COUNT > 0 ? "black":"silver"
});
});
return data;
@@ -401,6 +408,8 @@ export default {
this.$parent.dataCase = {
APP_UID: item.APP_UID,
DEL_INDEX: item.DEL_INDEX,
PRO_UID: item.PRO_UID,
TAS_UID: item.TAS_UID,
APP_NUMBER: item.CASE_NUMBER
};
this.$parent.page = "case-detail";
@@ -414,12 +423,16 @@ export default {
let self = this;
api.cases
.jump(params)
.then(function(data) {
self.$parent.dataCase = params;
self.$parent.page = "XCase";
.then(function(response) {
if (response.data.exists) {
self.$parent.dataCase = params;
self.$parent.page = "XCase";
} else {
self.showAlert(response.data.message, "danger");
}
})
.catch((err) => {
throw new Error(err);
self.showAlert(err.message, "danger");
});
},
/**
@@ -435,7 +448,7 @@ export default {
* @param {string} message - message to be displayen in the body
* @param {string} type - alert type
*/
showAlert(message, type) {
showAlert(message, type) {
this.message = message;
this.variant = type || "info";
this.dismissCountDown = this.dismissSecs;
@@ -495,16 +508,36 @@ export default {
*/
onSearch(params) {
this.$nextTick(() => {
this.$refs.test.refresh();
this.$refs.vueTable.refresh();
});
},
onUpdateFilters(params) {
this.$emit("onUpdateFilters", params);
},
/**
* Open the case notes modal
* @param {object} data - needed to create the data
*/
openComments(data) {
let that = this;
api.cases.open(_.extend({ ACTION: "todo" }, data)).then(() => {
that.$refs["modal-comments"].dataCase = data;
that.$refs["modal-comments"].show();
});
},
/**
* Post notes event handler
*/
onPostNotes() {
this.$refs["vueTable"].getData();
},
},
};
</script>
<style>
.VuePagination__count {
display: none;
}
.v-container-mycases {
padding-top: 20px;
padding-bottom: 20px;
@@ -512,7 +545,7 @@ export default {
padding-right: 50px;
}
.v-user-cell {
display: inline-block;
display: inline-block;
}
.v-user-cell-ellipsis {
white-space: nowrap;

View File

@@ -28,7 +28,6 @@
:options="options"
v-show="showTable"
ref="vueTable"
style="height: 120px"
>
<div slot="task" slot-scope="props">
<TaskCell :data="props.row.TASK" />
@@ -378,6 +377,7 @@ export default {
.casenotes(this.dataCase)
.then((response) => {
that.formatResponseCaseNotes(response.data.notes);
that.dataComments.noPerms = response.data.noPerms || 0;
})
.catch((err) => {
throw new Error(err);
@@ -445,11 +445,11 @@ export default {
let data = [];
_.forEach(response, (v) => {
data.push({
TASK: {
TASK: [{
TITLE: v.TAS_TITLE,
CODE_COLOR: v.TAS_COLOR,
COLOR: v.TAS_COLOR_LABEL,
},
}],
CASE_TITLE: v.DEL_TITLE,
ASSIGNEE: v.USR_FIRSTNAME + " " + v.USR_LASTNAME,
STATUS: v.DEL_THREAD_STATUS,

View File

@@ -33,8 +33,8 @@
</div>
<div slot="priority" slot-scope="props">{{ props.row.PRIORITY }}</div>
<div slot="actions" slot-scope="props">
<button class="btn btn-success btn-sm" @click="openCase(props)">
Continue
<button class="btn btn-success btn-sm" @click="openCase(props.row)">
{{ $t("ID_OPEN_CASE") }}
</button>
</div>
</v-server-table>
@@ -69,13 +69,13 @@ export default {
},
},
columns: [
"detail",
"detail",
"case_number",
"case_title",
"process_name",
"task",
"priority",
"actions",
"actions"
],
tableData: [],
filters: {},
@@ -86,9 +86,7 @@ export default {
case_title: this.$i18n.t("ID_CASE_TITLE"),
process_name: this.$i18n.t("ID_PROCESS_NAME"),
task: this.$i18n.t("ID_TASK"),
priority: this.$i18n.t("ID_PRIORITY"),
actions: "",
detail: "",
actions: ""
},
selectable: {
mode: "single",
@@ -162,57 +160,20 @@ export default {
CASE_NUMBER: v.APP_NUMBER,
CASE_TITLE: v.DEL_TITLE,
PROCESS_NAME: v.PRO_TITLE,
TASK: {
TASK: [{
TITLE: v.TAS_TITLE,
CODE_COLOR: v.TAS_COLOR,
COLOR: v.TAS_COLOR_LABEL,
},
USR_FIRSTNAME: v.USR_FIRSTNAME,
USR_LASTNAME: v.USR_LASTNAME,
USR_USERNAME: v.USR_USERNAME,
DUE_DATE: v.DEL_TASK_DUE_DATE,
DELEGATION_DATE: v.DEL_DELEGATE_DATE,
}],
PRIORITY: v.DEL_PRIORITY_LABEL,
PRO_UID: v.PRO_UID,
TAS_UID: v.TAS_UID,
DEL_INDEX: v.DEL_INDEX,
APP_UID: v.APP_UID,
APP_UID: v.APP_UID
});
});
return data;
},
/**
* Get for user format name configured in Processmaker Environment Settings
*
* @param {string} name
* @param {string} lastName
* @param {string} userName
* @return {string} nameFormat
*/
nameFormatCases(name, lastName, userName) {
let nameFormat = "";
if (/^\s*$/.test(name) && /^\s*$/.test(lastName)) {
return nameFormat;
}
if (this.nameFormat === "@firstName @lastName") {
nameFormat = name + " " + lastName;
} else if (this.nameFormat === "@firstName @lastName (@userName)") {
nameFormat = name + " " + lastName + " (" + userName + ")";
} else if (this.nameFormat === "@userName") {
nameFormat = userName;
} else if (this.nameFormat === "@userName (@firstName @lastName)") {
nameFormat = userName + " (" + name + " " + lastName + ")";
} else if (this.nameFormat === "@lastName @firstName") {
nameFormat = lastName + " " + name;
} else if (this.nameFormat === "@lastName, @firstName") {
nameFormat = lastName + ", " + name;
} else if (this.nameFormat === "@lastName, @firstName (@userName)") {
nameFormat = lastName + ", " + name + " (" + userName + ")";
} else {
nameFormat = name + " " + lastName;
}
return nameFormat;
},
/**
* Open selected cases in the inbox
*
@@ -220,22 +181,22 @@ export default {
*/
openCase(item) {
this.$emit("onUpdateDataCase", {
APP_UID: item.row.APP_UID,
DEL_INDEX: item.row.DEL_INDEX,
PRO_UID: item.row.PRO_UID,
TAS_UID: item.row.TAS_UID,
APP_UID: item.APP_UID,
DEL_INDEX: item.DEL_INDEX,
PRO_UID: item.PRO_UID,
TAS_UID: item.TAS_UID,
ACTION: "draft",
});
this.$emit("onUpdatePage", "XCase");
},
/**
* Open case detail
* Open case detail from draft
*
* @param {object} item
*/
openCaseDetail(item) {
let that = this;
api.cases.open(_.extend({ ACTION: "todo" }, item)).then(() => {
api.cases.cases_open(_.extend({ ACTION: "todo" }, item)).then(() => {
that.$emit("onUpdateDataCase", {
APP_UID: item.APP_UID,
DEL_INDEX: item.DEL_INDEX,

View File

@@ -22,6 +22,7 @@
ref="component"
:filters="filters"
:id="pageId"
:pageUri="pageUri"
:name="pageName"
@onSubmitFilter="onSubmitFilter"
@onRemoveFilter="onRemoveFilter"
@@ -46,6 +47,7 @@ import CaseDetail from "./CaseDetail";
import XCase from "./XCase";
import TaskReassignments from "./TaskReassignments";
import AdvancedSearch from "./AdvancedSearch";
import LegacyFrame from "./LegacyFrame";
import api from "./../api/index";
@@ -64,6 +66,7 @@ export default {
Paused,
Unassigned,
CaseDetail,
LegacyFrame
},
data() {
return {
@@ -78,7 +81,19 @@ export default {
sidebarWidth: "310px",
pageId: null,
pageName: null,
filters: null,
pageUri: null,
filters: null,
menuMap: {
CASES_MY_CASES: "MyCases",
CASES_SEARCH: "advanced-search",
CASES_INBOX: "todo",
CASES_DRAFT: "draft",
CASES_PAUSED: "paused",
CASES_SELFSERVICE: "unassigned",
CONSOLIDATED_CASES: "batch-routing",
CASES_TO_REASSIGN: "task-reassignments",
CASES_FOLDERS: "my-documents"
}
};
},
mounted() {
@@ -86,20 +101,29 @@ export default {
window.addEventListener("resize", this.onResize);
this.getMenu();
this.listenerIframe();
window.setInterval(this.setCounter, parseInt(window.config.FORMATS.casesListRefreshTime) * 1000);
window.setInterval(
this.setCounter,
parseInt(window.config.FORMATS.casesListRefreshTime) * 1000
);
},
methods: {
/**
* Listener for iframes childs
*/
listenerIframe(){
listenerIframe() {
let that = this,
eventMethod = window.addEventListener? "addEventListener": "attachEvent",
eventer = window[eventMethod],
messageEvent = eventMethod === "attachEvent"? "onmessage": "message";
eventMethod = window.addEventListener
? "addEventListener"
: "attachEvent",
eventer = window[eventMethod],
messageEvent =
eventMethod === "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
if (e.data === "redirect=todo" || e.message === "redirect=todo"){
eventer(messageEvent, function(e) {
if (
e.data === "redirect=todo" ||
e.message === "redirect=todo"
) {
that.page = "todo";
}
});
@@ -111,6 +135,7 @@ export default {
api.menu
.get()
.then((response) => {
this.setDefaultCasesMenu(response.data);
this.menu = this.mappingMenu(response.data);
this.setCounter();
})
@@ -118,6 +143,18 @@ export default {
console.error(e);
});
},
/**
* Set default cases menu option
*/
setDefaultCasesMenu(data) {
let menuItem = _.find(data, function(o) {
return o.id === window.config._nodeId;
});
if (menuItem && menuItem.href) {
this.page = this.menuMap[window.config._nodeId] || "MyCases";
this.$router.push(menuItem.href);
}
},
/**
* Do a mapping of vue view for menus
* @returns array
@@ -126,22 +163,13 @@ export default {
var i,
j,
newData = data,
auxId,
viewVue = {
CASES_MY_CASES: "MyCases",
CASES_SEARCH: "advanced-search",
CASES_INBOX: "todo",
CASES_DRAFT: "draft",
CASES_PAUSED: "paused",
CASES_SELFSERVICE: "unassigned",
CONSOLIDATED_CASES: "batch-routing",
CASES_TO_REASSIGN: "task-reassignments",
CASES_FOLDERS: "my-documents",
};
auxId;
for (i = 0; i < data.length; i += 1) {
auxId = data[i].id || "";
if (auxId !== "" && viewVue[auxId]) {
newData[i].id = viewVue[auxId];
if (auxId !== "" && this.menuMap[auxId]) {
newData[i].id = this.menuMap[auxId];
} else if (newData[i].href) {
newData[i].id = "LegacyFrame";
}
}
return newData;
@@ -151,10 +179,16 @@ export default {
this.page = "advanced-search";
this.filters = item.item.filters;
this.pageId = item.item.id;
this.pageUri = item.item.href;
this.pageName = item.item.title;
} else {
this.filters = [];
this.pageId = null;
this.pageUri = item.item.href;
this.page = item.item.id || "MyCases";
if (this.$refs["component"] && this.$refs["component"].updateView) {
this.$refs["component"].updateView();
}
}
},
setCounter() {
@@ -167,7 +201,7 @@ export default {
var i,
j,
data = response.data;
that.counters = data;
that.counters = data;
for (i = 0; i < that.menu.length; i += 1) {
if (that.menu[i].id && data[that.menu[i].id]) {
that.menu[i].badge.text = data[that.menu[i].id];
@@ -179,16 +213,6 @@ export default {
});
}
},
/**
* Update page component
*/
updatePage(data, page, callback) {
this.dataCase = data;
this.page = page;
if (this.$refs["component"] && this.$refs["component"].update) {
this.$refs["component"].update(data, callback);
}
},
onResize() {
if (window.innerWidth <= 767) {
this.isOnMobile = true;
@@ -256,6 +280,9 @@ export default {
onUpdatePage(page) {
this.lastPage = this.page;
this.page = page;
if (this.$refs["component"] && this.$refs["component"].updateView) {
this.$refs["component"].updateView();
}
},
onUpdateDataCase(data) {
this.dataCase = data;
@@ -279,7 +306,7 @@ export default {
onUpdateFilters(filters) {
this.filters = filters;
}
},
}
};
</script>

View File

@@ -0,0 +1,40 @@
<template>
<div>
<iframe
:width="width"
ref="xIFrame"
frameborder="0"
:src="pageUri"
:height="height"
allowfullscreen
></iframe>
</div>
</template>
<script>
export default {
name: "LegacyFrame",
components: {},
props: {
pageUri: String,
},
mounted() {
this.height = window.innerHeight - this.diffHeight;
},
data() {
return {
height: "100%",
width: "100%",
diffHeight: 10
};
},
methods: {
classBtn(cls) {
return "btn v-btn-request " + cls;
},
},
};
</script>
<style>
</style>

View File

@@ -131,21 +131,21 @@ export default {
categories = [];
_.each(data, (o) => {
index = _.findIndex(categories, (c) => {
return c.id == o.categoryId;
return c.id == o.pro_category;
});
if (index == -1) {
categories.push({
id: o.categoryId,
title: o.categoryName,
id: o.pro_category,
title: o.category_name,
items: [],
});
index = categories.length - 1;
}
categories[index].items.push({
title: o.text,
description: o.text,
task_uid: o.taskId,
pro_uid: o.processId,
title: o.pro_title,
description: o.pro_description,
task_uid: o.tas_uid,
pro_uid: o.pro_uid,
onClick: that.startNewCase,
});
});

View File

@@ -3,7 +3,7 @@
<button-fleft :data="newCase"></button-fleft>
<MyCasesFilter
:filters="filters"
:title="$t('ID_MY_CASES')"
:title="title"
@onRemoveFilter="onRemoveFilter"
@onUpdateFilters="onUpdateFilters"
/>
@@ -39,14 +39,12 @@
{{ props.row.DURATION }}
</div>
<div slot="actions" slot-scope="props">
<div class="btn-default" @click="openComments(props.row)">
<i class="fas fa-comments"></i>
<span class="badge badge-light">9</span>
<span class="sr-only">unread messages</span>
<div class="btn-default" v-bind:style="{ color: props.row.MESSAGE_COLOR}" @click="openComments(props.row)">
<span class="fas fa-comments"></span>
</div>
</div>
</v-server-table>
<ModalComments ref="modal-comments"></ModalComments>
<ModalComments ref="modal-comments" @postNotes="onPostNotes"></ModalComments>
</div>
</template>
@@ -73,6 +71,7 @@ export default {
data() {
return {
metrics: [],
title: this.$i18n.t('ID_MY_CASES'),
filter: "CASES_INBOX",
allView: [],
filterHeader: "STARTED",
@@ -122,11 +121,16 @@ export default {
},
},
translations: null,
pmDateFormat: "Y-m-d H:i:s",
pmDateFormat: window.config.FORMATS.dateFormat
};
},
mounted() {
this.getHeaders();
// force to open start cases modal
// if the user has start case as a default case menu option
if (window.config._nodeId === "CASES_START_CASE") {
this.$refs["newRequest"].show();
}
},
watch: {},
computed: {
@@ -195,14 +199,15 @@ export default {
CASE_TITLE: v.DEL_TITLE,
PROCESS_NAME: v.PRO_TITLE,
STATUS: v.APP_STATUS,
START_DATE: v.APP_CREATE_DATE || "",
FINISH_DATE: v.APP_FINISH_DATE || "",
START_DATE: v.APP_CREATE_DATE_LABEL || "",
FINISH_DATE: v.APP_FINISH_DATE_LABEL || "",
PENDING_TASKS: that.formantPendingTask(v.PENDING),
DURATION: v.DURATION,
DEL_INDEX: v.DEL_INDEX,
APP_UID: v.APP_UID,
PRO_UID: v.PRO_UID,
TAS_UID: v.TAS_UID,
MESSAGE_COLOR: v.CASE_NOTES_COUNT > 0 ? "black":"silver"
});
});
return data;
@@ -402,6 +407,7 @@ export default {
item: v.id,
icon: info[v.id].icon,
onClick: (obj) => {
that.title = obj.title;
that.filterHeader = obj.item;
that.$refs["vueTable"].getData();
},
@@ -410,6 +416,10 @@ export default {
});
return data;
},
/**
* Open the case notes modal
* @param {object} data - needed to create the data
*/
openComments(data) {
let that = this;
api.cases.open(_.extend({ ACTION: "todo" }, data)).then(() => {
@@ -427,6 +437,12 @@ export default {
});
}
},
/**
* Post notes event handler
*/
onPostNotes() {
this.$refs["vueTable"].getData();
}
},
};
</script>

View File

@@ -191,16 +191,16 @@ export default {
CASE_NUMBER: v.APP_NUMBER,
CASE_TITLE: v.DEL_TITLE,
PROCESS_NAME: v.PRO_TITLE,
TASK: {
TASK: [{
TITLE: v.TAS_TITLE,
CODE_COLOR: v.TAS_COLOR,
COLOR: v.TAS_COLOR_LABEL,
},
}],
USR_FIRSTNAME: v.USR_FIRSTNAME,
USR_LASTNAME: v.USR_LASTNAME,
USR_USERNAME: v.USR_USERNAME,
DUE_DATE: v.DEL_TASK_DUE_DATE,
DELEGATION_DATE: v.DEL_DELEGATE_DATE,
DUE_DATE: v.DEL_TASK_DUE_DATE_LABEL,
DELEGATION_DATE: v.DEL_DELEGATE_DATE_LABEL,
PRIORITY: v.DEL_PRIORITY_LABEL,
DEL_INDEX: v.DEL_INDEX,
APP_UID: v.APP_UID,
@@ -249,7 +249,7 @@ export default {
*/
openCaseDetail(item) {
let that = this;
api.cases.open(_.extend({ ACTION: "todo" }, item)).then(() => {
api.cases.cases_open(_.extend({ ACTION: "todo" }, item)).then(() => {
that.$emit("onUpdateDataCase", {
APP_UID: item.APP_UID,
DEL_INDEX: item.DEL_INDEX,

View File

@@ -1,11 +1,12 @@
<template>
<div>
<tabs>
<tabs @changed="changed">
<tab :name="$t('ID_SUMMARY')">
<PmCaseSummary :data="dataCaseSummary"> </PmCaseSummary>
</tab>
<tab :name="$t('ID_PROCESS_MAP')">
<ProcessMap :data="dataCase"> </ProcessMap>
<ProcessMap :data="dataCase" v-if="currentTab == $t('ID_PROCESS_MAP')">
</ProcessMap>
</tab>
<tab :name="$t('ID_CASE_HISTORY')">
<CaseHistory :data="dataCase"> </CaseHistory>
@@ -41,11 +42,20 @@ export default {
dataCaseSummary: Array,
},
data() {
return {};
return {
currentTab: ""
};
},
mounted() {},
methods: {},
methods: {
/**
* When change the tab selection
**/
changed(selectedTab) {
this.currentTab = selectedTab.tab.name;
}
}
};
</script>
<style>

View File

@@ -183,16 +183,16 @@ export default {
CASE_NUMBER: v.APP_NUMBER,
CASE_TITLE: v.DEL_TITLE,
PROCESS_NAME: v.PRO_TITLE,
TASK: {
TASK: [{
TITLE: v.TAS_TITLE,
CODE_COLOR: v.TAS_COLOR,
COLOR: v.TAS_COLOR_LABEL,
},
}],
USR_FIRSTNAME: v.USR_FIRSTNAME,
USR_LASTNAME: v.USR_LASTNAME,
USR_USERNAME: v.USR_USERNAME,
DUE_DATE: v.DEL_TASK_DUE_DATE,
DELEGATION_DATE: v.DEL_DELEGATE_DATE,
DUE_DATE: v.DEL_TASK_DUE_DATE_LABEL,
DELEGATION_DATE: v.DEL_DELEGATE_DATE_LABEL,
PRIORITY: v.DEL_PRIORITY_LABEL,
DEL_INDEX: v.DEL_INDEX,
APP_UID: v.APP_UID,
@@ -256,7 +256,7 @@ export default {
*/
openCaseDetail(item) {
let that = this;
api.cases.open(_.extend({ ACTION: "todo" }, item)).then(() => {
api.cases.cases_open(_.extend({ ACTION: "todo" }, item)).then(() => {
that.$emit("onUpdateDataCase", {
APP_UID: item.APP_UID,
DEL_INDEX: item.DEL_INDEX,
@@ -276,6 +276,12 @@ export default {
});
}
},
/**
* update view in component
*/
updateView(){
this.$refs["vueTable"].getData();
}
},
};
</script>

View File

@@ -188,16 +188,16 @@ export default {
CASE_NUMBER: v.APP_NUMBER,
CASE_TITLE: v.DEL_TITLE,
PROCESS_NAME: v.PRO_TITLE,
TASK: {
TASK: [{
TITLE: v.TAS_TITLE,
CODE_COLOR: v.TAS_COLOR,
COLOR: v.TAS_COLOR_LABEL,
},
}],
USR_FIRSTNAME: v.USR_FIRSTNAME,
USR_LASTNAME: v.USR_LASTNAME,
USR_USERNAME: v.USR_USERNAME,
DUE_DATE: v.DEL_TASK_DUE_DATE,
DELEGATION_DATE: v.DEL_DELEGATE_DATE,
DUE_DATE: v.DEL_TASK_DUE_DATE_LABEL,
DELEGATION_DATE: v.DEL_DELEGATE_DATE_LABEL,
PRIORITY: v.DEL_PRIORITY_LABEL,
PRO_UID: v.PRO_UID,
TAS_UID: v.TAS_UID,
@@ -262,7 +262,7 @@ export default {
*/
openCaseDetail(item) {
let that = this;
api.cases.open(_.extend({ ACTION: "todo" }, item)).then(() => {
api.cases.cases_open(_.extend({ ACTION: "todo" }, item)).then(() => {
that.$emit("onUpdateDataCase", {
APP_UID: item.APP_UID,
DEL_INDEX: item.DEL_INDEX,

View File

@@ -99,6 +99,8 @@ export default {
that.attachDocuments = false;
that.dataAttachedDocuments.items = [];
that.getCasesNotes();
this.$refs["modal-comments"].hide();
this.$emit("postNotes");
} else {
that.showAlert(response.data.message, "danger");
that.dataAttachedDocuments.items = [];

View File

@@ -38,9 +38,11 @@
.v-sidebar-menu .vsm--item {
position: relative;
display: block;
width: 90%;
margin-left: 10px;
}
.vsm_collapsed .vsm--item {
margin-left: 0px;
}
.v-sidebar-menu .vsm--link {
cursor: pointer;
@@ -109,6 +111,10 @@
margin-right: 10px
}
.vsm--link_level-2>.vsm--icon {
margin-top: 8px;
}
.v-sidebar-menu .vsm--arrow {
width: 30px;
text-align: center;
@@ -270,7 +276,13 @@
}
.v-sidebar-menu {
background-color: #0099dd
background-color: #0099dd;
}
.v-sidebar-menu .vsm--scroll-wrapper {
height: 100%;
overflow-y: auto;
overflow-x: hidden;
}
.v-sidebar-menu .vsm--link {
@@ -390,4 +402,8 @@
.v-sidebar-menu .vsm--arrow.vsm--arrow_open-rtl {
-webkit-transform: translateY(-50%) rotate(90deg);
transform: translateY(-50%) rotate(270deg) !important;
}
}
.vsm--mobile-item {
max-width: 200px !important;
}

View File

@@ -238,6 +238,27 @@ class SearchTest extends TestCase
$this->assertNotEmpty($result);
}
/**
* It tests web entry with negative appNumbers
*
* @covers \ProcessMaker\BusinessModel\Cases\Search::getData()
* @test
*/
public function it_get_web_entry_not_submitted()
{
// Create factories related to the delegation cases
$cases = $this->createSearch();
$casesNotSubmitted = factory(Delegation::class, 5)->states('web_entry')->create();
// Create new Search object
$search = new Search();
// Set order by column value
$search->setOrderByColumn('APP_NUMBER');
$result = $search->getData();
// Review if the cases not submitted are not considered
$this->assertNotEmpty($result);
$this->assertEquals(count($result) , count($cases));
}
/**
* It tests the getCounter method
*

Some files were not shown because too many files have changed in this diff Show More