update task metrics

This commit is contained in:
Henry Jordan
2021-08-12 19:05:50 +00:00
51 changed files with 5756 additions and 1133 deletions

1040
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,10 +21,14 @@
},
"dependencies": {
"apexcharts": "^3.27.3",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^2.0.2",
"axios": "^0.15.3",
"bootstrap": "^4.5.3",
"bootstrap-colorpicker": "^3.0.3",
"bootstrap-vue": "^2.19.0",
"bootstrap-vue-font-awesome-picker": "^0.1.3",
"chart.js": "^2.7.2",
"dateformat": "^3.0.3",
"faker": "^5.1.0",
@@ -40,6 +44,9 @@
"promise-polyfill": "8.1.3",
"sortablejs": "^1.13.0",
"uiv": "^0.28.0",
"v-color": "^1.1.2",
"verte": "0.0.12",
"vfa-picker": "^5.9.1",
"vue": "^2.6.12",
"vue-apexcharts": "^1.6.1",
"vue-awesome-swiper": "^3.1.3",
@@ -49,6 +56,7 @@
"vue-faker": "^3.0.0",
"vue-fullscreen": "^2.1.3",
"vue-i18n": "^8.22.2",
"vue-icon-picker": "^1.0.0",
"vue-js-toggle-button": "^1.3.1",
"vue-multiselect": "^2.1.6",
"vue-muuri": "^0.1.2",

View File

@@ -0,0 +1,63 @@
<template>
<div>
<b-modal
ref="modal-delete-list"
hide-footer
size="md"
>
<template v-slot:modal-title>
{{ $t('ID_DELETE_CUSTOM_CASE_LIST') }}
</template>
<b-container fluid>
<p>
{{ $t("ID_ARE_YOU_SURE_DELETE_CUSTOM_CASE_LIST") }}
</p>
</b-container>
<div class="modal-footer">
<div class="float-right">
<b-button
variant="danger"
data-dismiss="modal"
@click="hide"
>
{{ $t("ID_NO") }}
</b-button>
<b-button
variant="success"
@click="deleteCustomCaseList"
>
{{ $t("ID_YES") }}
</b-button>
</div>
</div>
</b-modal>
</div>
</template>
<script>
import api from "./../settings/customCaseList/Api/CaseList";
export default {
name: "ModalDeleteCaseList",
data() {
return {
data: null
}
},
methods: {
show() {
this.$refs["modal-delete-list"].show();
},
hide() {
this.$refs["modal-delete-list"].hide();
},
deleteCustomCaseList() {
api.deleteCaseList(this.data).then((response) => {
if (response.statusText == "OK") {
that.$refs["modal-pause-case"].hide();
that.$parent.$refs["vueTable"].getData();
}
});
}
}
}
</script>

View File

@@ -36,6 +36,19 @@ class caseListApi extends Api {
keys: {}
});
}
deleteCaseList(data) {
return axios.delete(
window.config.SYS_SERVER_API +
'/api/1.0/' +
window.config.SYS_WORKSPACE +
'/caseList/' + data.id, {
headers: {
'Authorization': 'Bearer ' + window.config.SYS_CREDENTIALS.accessToken,
"Accept-Language": window.config.SYS_LANG
}
}
);
}
}
let api = new caseListApi(Services);

View File

@@ -0,0 +1,320 @@
<template>
<div id="home">
<div class="demo">
<div class="container">
<h5>{{ $t("ID_NEW_CASES_LISTS") }}</h5>
<div class="row">
<div class="col-sm">
<b-row>
<b-col>
<b-form-group
id="nameLabel"
label="Name"
label-for="name"
>
<b-form-input
id="name"
v-model="params.name"
placeholder="Set a Case List Name"
required
></b-form-input>
</b-form-group>
</b-col>
<b-col>
<b-form-group
id="tableLabel"
label="PM Table "
label-for="name"
>
<multiselect
v-model="params.tableUid"
:options="pmTablesOptions"
placeholder="Chose an option"
label="label"
track-by="value"
:show-no-results="false"
@search-change="asyncFind"
:loading="isLoading"
id="ajax"
:limit="10"
:clear-on-select="true"
>
</multiselect>
</b-form-group>
</b-col>
</b-row>
<b-form-group
id="descriptionLabel"
label="Description "
label-for="description"
>
<b-form-textarea
id="description"
v-model="params.description"
placeholder="Some Text"
rows="1"
max-rows="1"
></b-form-textarea>
</b-form-group>
<b-row>
<b-col cols="10">
<v-client-table
:columns="columns"
v-model="data"
:options="options"
>
</v-client-table>
</b-col>
<b-col cols="2">
<!-- Control panel -->
<div class="control-panel">
<div class="vertical-center">
<button
type="button"
class="btn btn-light"
@click="assignAll()"
:disabled="isButtonDisabled"
>
<i
class="fa fa-angle-double-right"
></i>
</button>
<button
type="button"
class="btn btn-light"
@click="assignSelected()"
:disabled="isButtonDisabled"
>
<i class="fa fa-angle-right"></i>
</button>
<button
type="button"
class="btn btn-light"
@click="unassignSelected()"
:disabled="isButtonDisabled"
>
<i class="fa fa-angle-left"></i>
</button>
<button
type="button"
class="btn btn-light"
@click="unassignAll()"
:disabled="isButtonDisabled"
>
<i
class="fa fa-angle-double-right"
></i>
</button>
</div>
</div>
<!-- End Control panel -->
</b-col>
</b-row>
<b-form-group
id="iconLabel"
label="Icon "
label-for="icon"
>
<icon-picker
@selected="onSelectIcon"
:default="params.iconList"
/>
</b-form-group>
<div>
<b-form-group
id="menuColor"
label="Menu Color "
label-for="icon"
>
<verte
:value="params.iconColor"
id="icon"
@input="onChangeColor"
picker="square"
menuPosition="left"
model="hex"
>
<svg viewBox="0 0 50 50">
<path
d="M 10 10 H 90 V 90 H 10 L 10 10"
/>
</svg>
</verte>
</b-form-group>
</div>
<div>
<b-form-group
id="screenColor"
label="Screen Color Icon"
label-for="screen"
>
<verte
:value="params.iconColorScreen"
@input="onChangeColor"
picker="square"
menuPosition="left"
model="hex"
>
<svg viewBox="0 0 50 50">
<path
d="M 10 10 H 90 V 90 H 10 L 10 10"
/>
</svg>
</verte>
</b-form-group>
</div>
</div>
<div class="col-sm">
<v-client-table
:columns="columnsCaseList"
v-model="data"
:options="caseListOptions"
>
</v-client-table>
</div>
</div>
<div>
<b-button variant="danger" @click="onCancel"
>Cancel</b-button
>
<b-button variant="outline-primary">Preview</b-button>
<b-button variant="success">Save</b-button>
</div>
</div>
</div>
</div>
</template>
<script>
import utils from "../../../utils/utils";
import Multiselect from "vue-multiselect";
import api from "./../../../api/index";
import IconPicker from "../../../components/iconPicker/IconPicker.vue";
export default {
name: "CaseListSketh",
components: {
Multiselect,
IconPicker,
IconPicker,
},
props: ["params"],
data() {
return {
icon: "fas fa-user-cog",
isLoading: false,
isButtonDisabled: false,
pmTablesOptions: [],
columns: ["name", "field", "type", "source", "source"],
data: utils.getData(),
options: {
headings: {
name: "Name",
field: "Field",
type: "Type",
source: "Source",
},
filterable: true,
},
columnsCaseList: [
"name",
"field",
"type",
"source",
"typeOfSearching",
"enableSearchFilter",
"actions",
],
caseListOptions: {
headings: {
name: "Name",
field: "Field",
type: "Type",
typeOfSearching: "Type of Searching",
enableSearchFilter: "Enable Search Filter",
},
filterable: false,
perPage: 1000,
perPageValues: [],
texts: {
count: "",
},
},
};
},
mounted() {},
methods: {
unassignSelected() {},
unassignAll() {},
assignSelected() {},
assignAll() {},
onSelectIcon(data) {
console.log(data);
// this.params.iconList = data;
},
onChangeColor(color) {
console.log(color);
this.menuColor = color;
},
onCancel() {
this.$emit("closeSketch");
},
onChange(e) {
console.log(e);
},
/**
* Find asynchronously in the server
* @param {string} query - string from the text field
*/
asyncFind(query) {
let self = this;
this.isLoading = true;
self.processes = [];
api.filters
.processList(query)
.then((response) => {
self.processes = [];
_.forEach(response.data, function(elem, key) {
self.pmTablesOptions.push({
label: elem.PRO_TITLE,
value: elem.PRO_ID,
});
});
this.isLoading = false;
})
.catch((e) => {
console.error(err);
});
},
},
};
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<style scoped>
.verte {
position: relative;
display: flex;
justify-content: normal;
}
.control-panel {
height: 100%;
width: 8%;
float: left;
position: relative;
}
.vertical-center {
margin: 0;
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.vertical-center > button {
width: 70%;
margin: 5px;
}
</style>

View File

@@ -3,13 +3,16 @@
id="home"
>
<div class="demo">
<div class="container">
<div class="container" v-if="!showSketch">
<h5 >{{ $t("ID_CUSTOM_CASES_LISTS") }}</h5>
<div class="x_content">
<b-container fluid>
<b-tabs content-class="mt-3">
<b-tab :title="$t('TO_DO')" active>
<Tables module="inbox"/>
<Tables module="inbox"
@showSketch="onShowSketch"
@closeSketch="onCloseSketch"
/>
</b-tab>
<b-tab :title="$t('ID_DRAFT')" lazy>
<Tables module="draft"/>
@@ -25,26 +28,42 @@
</div>
</div>
<div class="container" v-if="showSketch">
<CaseListSketch
@showSketch="onShowSketch"
@closeSketch="onCloseSketch"
:params="params"
/>
</div>
</div>
</div>
</template>
<script>
import Tables from "./Tables";
import CaseListSketch from "./CaseListSketch"
export default {
name: "CustomCaseList",
components: {
Tables
Tables,
CaseListSketch
},
data() {
return {
showSketch: false,
params: {}
};
},
mounted() {
},
methods: {
onShowSketch (params) {
this.showSketch = true;
this.params = params;
},
onCloseSketch (params) {
this.showSketch = false;
}
}
};
</script>

View File

@@ -1,5 +1,6 @@
<template>
<div id="people">
<ModalDeleteCaseList ref="modal-delete-list"></ModalDeleteCaseList>
<button-fleft :data="newList"></button-fleft>
<button-fleft :data="importList"></button-fleft>
<v-server-table
@@ -27,13 +28,15 @@ import ButtonFleft from "../../../components/home/ButtonFleft.vue";
import Ellipsis from "../../../components/utils/ellipsis.vue";
import utils from "../../../utils/utils";
import OwnerCell from "../../../components/vuetable/OwnerCell";
import ModalDeleteCaseList from "./../../Modals/ModalDeleteCaseList.vue"
export default {
name: "Tables",
props: ["module"],
components: {
ButtonFleft,
Ellipsis,
OwnerCell
OwnerCell,
ModalDeleteCaseList
},
data() {
return {
@@ -55,6 +58,17 @@ export default {
title: this.$i18n.t("New List"),
class: "btn-success",
onClick: () => {
this.$emit("showSketch", {
name: "Rocko",
description: "algo te texto",
tableUid: "1234",
iconList: 'far fa-calendar-alt',
iconColor: '#4287f5',
iconColorScreen:'#4287f5',
type: this.module
});
//TODO button
}
},
@@ -76,8 +90,6 @@ export default {
],
tableData: [],
options: {
perPage:25,
perPageValues:[25],
filterable: true,
headings: {
name: this.$i18n.t("ID_NAME"),
@@ -171,6 +183,14 @@ export default {
data.push(v);
});
return data;
},
/**
* Show modal to delete a custom case list
* @param {object} data
*/
showModalDelete(data) {
this.$refs["modal-delete-list"].data = data;
this.$refs["modal-delete-list"].show();
}
}
};

View File

@@ -2,22 +2,22 @@ import Vue from "vue";
import VueRouter from "vue-router";
import VueSidebarMenu from "vue-sidebar-menu";
import VueI18n from 'vue-i18n';
import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue';
import { BootstrapVue } from 'bootstrap-vue';
import { ServerTable, Event, ClientTable} from 'vue-tables-2';
import Sortable from 'sortablejs';
import "@fortawesome/fontawesome-free/css/all.css";
import "@fortawesome/fontawesome-free/js/all.js";
import 'bootstrap/dist/css/bootstrap-grid.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import CustomCaseList from "./CustomCaseList";
import Verte from 'verte';
import 'verte/dist/verte.css';
// register component globally
Vue.component('verte', Verte);
Vue.use(VueRouter);
Vue.use(VueSidebarMenu);
Vue.use(BootstrapVue);
Vue.use(BootstrapVueIcons);
Vue.use(VueI18n);
Vue.use(ServerTable, {}, false, 'bootstrap3', {});
Vue.use(ClientTable, {}, false, 'bootstrap3', {});
window.ProcessMaker = {
@@ -48,5 +48,6 @@ new Vue({
// eslint-disable-line no-new
el: "#customCaseList",
router,
components: { Verte },
render: (h) => h(CustomCaseList),
});

View File

@@ -0,0 +1,24 @@
import ApiInstance from "./Api.js";
import Services from "./Services";
let Api = new ApiInstance( Services );
export let config = {
get(data) {
return Api.get({
service: "GET_CONFIG",
keys: data
});
},
post(data) {
return Api.post({
service: "CONFIG",
data: data
});
},
put(data) {
return Api.put({
service: "CONFIG",
data: data
});
},
};

View File

@@ -1,7 +1,7 @@
import axios from "axios";
import ApiInstance from "./Api.js";
import Services from "./Services";
let Api = new ApiInstance( Services );
let Api = new ApiInstance(Services);
export let filters = {
get(data) {
return Api.get({
@@ -88,11 +88,16 @@ export let filters = {
* Service to get the categories list
*/
categories(query) {
let pr = {
limit: 15,
offset: 0
};
if (query) {
pr["name"] = query;
}
return Api.get({
service: "CATEGORIES",
params: {
name: query,
},
params: pr,
keys: {},
});
},

View File

@@ -13,11 +13,18 @@ export let process = {
});
}
},
categories(dt) {
totalCasesByProcess(dt) {
return Api.get({
service: "TOTAL_CASES_BY_PROCESS",
params: dt,
keys: {}
});
},
processCategories() {
return Api.fetch({
service: "CATEGORIES",
service: "PROCESS_CATEGORIES",
method: "get",
data: dt,
data: {},
keys: {}
});
}

View File

@@ -69,8 +69,10 @@
CATEGORIES: "/home/categories",
DEBUG_STATUS: "/home/process-debug-status?processUid={prj_uid}",
LIST_TOTAL_CASES: "/metrics/list-total-cases",
TOTAL_CASES_BY_PROCESS:"/metrics/total-cases-by-process",
CONFIG: "/home/config",
GET_CONFIG: "/home/config/{id}/{name}",
PAUSE_CASE: "/cases/{app_uid}/pause",
REASSIGN_CASE: "/cases/{app_uid}/reassign-case",
REASSIGN_USERS: "/light/userstoreassign/{task_uid}",
CATEGORIES: "/processcategory/categories"
REASSIGN_USERS: "/light/userstoreassign/{task_uid}"
};

View File

@@ -1,7 +1,7 @@
import { menu } from "./Menu";
import { cases, casesHeader } from "./Cases";
import { config } from "./Config";
import { caseNotes } from "./CaseNotes";
import { process } from "./Process";
import { filters } from "./Filters";
@@ -13,5 +13,6 @@ export default {
casesHeader,
process,
caseNotes,
filters
filters,
config
};

View File

@@ -0,0 +1,239 @@
<template>
<div class="rbt-icon-picker">
<b-button @click="popUpActive = true">
<i ref="icon" :class="icon"></i>
</b-button>
<div class="rip-popup-component" :style="popupActiveStyle">
<div class="rip-popup-bg"></div>
<div class="rip-popup">
<div class="rip-popup-content">
<div class="rip-search">
<div class="rip-input">
<label for="ripSearch" style="display: none;"
>Search for Icon</label
>
<input
id="ripSearch"
placeholder="Search for Icon"
v-model="searchText"
@input="searchTextChanged"
/>
<span class="input-append">
<i class="fas fa-search"></i>
</span>
</div>
</div>
<div class="rip-content">
<div class="rip-not-found" v-show="loading">
<i class="fas fa-spinner fa-pulse"></i>
</div>
<div class="rip-icons" v-show="!loading">
<h4 class="icon-title">
Regular Icons
</h4>
<p
style="text-align: center;"
v-if="regularIcons.length <= 0"
>
<i class="fas fa-eye-slash"></i>
Sorry, No icons found!
</p>
<ul class="rip-row" v-if="regularIcons.length > 0">
<li
v-for="(icon, index) in regularIcons"
:key="index"
class="rip-col"
>
<div class="icon-content text-center">
<div
class="icon-el"
@click="selectIcon(icon, 'far')"
>
<i :class="`far fa-${icon}`"></i>
</div>
<div class="icon-title">
{{ icon }}
</div>
</div>
</li>
</ul>
<h4 class="icon-title">
Brand Icons
</h4>
<p
style="text-align: center;"
v-if="brandIcons.length <= 0"
>
<i class="fas fa-eye-slash"></i>
Sorry, No Brand icons found!
</p>
<ul class="rip-row" v-if="brandIcons.length > 0">
<li
v-for="(icon, index) in brandIcons"
:key="index"
class="rip-col"
>
<div class="icon-content text-center">
<div
class="icon-el"
@click="selectIcon(icon, 'fab')"
>
<i :class="`fab fa-${icon}`"></i>
</div>
<div class="icon-title">
{{ icon }}
</div>
</div>
</li>
</ul>
<h4 class="icon-title">
Solid Icons
</h4>
<p
style="text-align: center;"
v-if="solidIcons.length <= 0"
>
<i class="fas fa-eye-slash"></i>
Sorry, No Solid icons found!
</p>
<ul class="rip-row" v-if="solidIcons.length > 0">
<li
v-for="(icon, index) in solidIcons"
:key="index"
class="rip-col"
>
<div class="icon-content text-center">
<div
class="icon-el"
@click="selectIcon(icon, 'fas')"
>
<i :class="`fas fa-${icon}`"></i>
</div>
<div class="icon-title">
{{ icon }}
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ripIcons from "./assets/icons";
export default {
name: "VueAwesomeIconPicker",
props: {
button: {
type: String,
default: "Pick A Icon",
},
color: {
type: String,
default: "black",
},
title: {
type: String,
default: "Vue Awesome Icon Picker",
},
iconPreview: {
type: Boolean,
default: true,
},
default: {
type: String,
default: null,
},
},
data() {
return {
loading: false,
allIcons: {
brand: [],
regular: [],
solid: [],
},
popUpActive: false,
icon: null,
searchText: "",
searchIconNotFound: false,
};
},
watch: {
color() {
console.log("colores");
},
},
methods: {
selectIcon(icon, type) {
this.icon = `${type} fa-${icon}`;
this.popUpActive = false;
this.$emit("selected", this.icon);
},
searchTextChanged() {
this.searchIcon(this.searchText);
},
setDefaultIcons() {
this.allIcons.brand = ripIcons.brand;
this.allIcons.regular = ripIcons.regular;
this.allIcons.solid = ripIcons.solid;
},
searchIcon(txt) {
this.loading = true;
if (txt && txt.length > 0) {
setTimeout(() => {
this.loading = false;
}, 950);
txt = txt.toLowerCase();
Object.keys(ripIcons).forEach((key) => {
setTimeout(() => {
let icons = ripIcons[key].filter(
(ico) => ico.indexOf(txt) > -1
);
if (icons && icons.length > 0) {
this.allIcons[key] = icons;
} else {
this.allIcons[key] = [];
}
}, 320);
});
} else {
setTimeout(() => {
this.setDefaultIcons();
this.loading = false;
}, 950);
}
},
},
created() {
this.setDefaultIcons();
if (this.default) {
this.icon = this.default;
}
},
computed: {
popupActiveStyle() {
return !this.popUpActive ? "display: none;" : "";
},
brandIcons() {
return this.loading ? [] : this.allIcons.brand;
},
solidIcons() {
return this.loading ? [] : this.allIcons.solid;
},
regularIcons() {
return this.loading ? [] : this.allIcons.regular;
},
},
};
</script>
<style lang="scss" scoped>
@import "./assets/RbtIconPicker";
</style>

View File

@@ -0,0 +1,239 @@
.rbt-icon-picker {
.icon-preview {
font-size: 22px;
padding: 10px 20px 0;
display: inline-block;
}
.picker-btn {
color: #fff;
background: #339af0;
padding: 12px 25px;
border: 0;
border-radius: 2px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.02em;
cursor: pointer;
transition: all .25s ease-in;
&:hover {
background: #2c89d6;
}
}
}
.rip-popup-component {
text-align: center;
z-index: 5999999;
transition: all .2s;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
opacity: 1;
.rip-popup-bg {
width: 100%;
background: rgba(0,0,0,.4);
position: absolute;
top: 0;
height: 100%;
z-index: 10;
transition: all .25s ease;
opacity: 1;
left: 0;
}
.rip-popup {
transition: all .2s;
z-index: 100;
margin: 10px;
width: calc(100% - 30px);
height: calc(100% - 30px);
border-radius: 6px;
box-shadow: 0 5px 20px 0 rgba(0,0,0,.1);
background: #f8f9fa;
animation: rebound .3s;
.rip-popup-header {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
background: rgba(0,0,0,.05);
border-radius: 5px 5px;
position: relative;
h2 {
transition: all .23s ease .1s;
padding: 8px 8px 8px 12px;
font-size: 18px;
text-align: center;
width: 100%;
}
span {
background: #ffffff;
transition: all .23s ease .1s;
position: relative;
padding: 8px;
cursor: pointer;
box-shadow: 0 5px 20px 0 rgba(0,0,0,.1);
border-radius: 5px;
color: rgba(0,0,0,.6);
transform: translate(8px,-8px);
line-height: 16px;
font-size: 30px;
&:hover {
box-shadow: 0 0 0 0 rgba(0,0,0,.1);
transform: translate(5px,-5px);
}
}
}
.rip-popup-content {
padding: 14px;
font-size: 14px;
transition: all .23s ease .1s;
overflow: auto;
max-height: calc(100vh - 100px);
margin-top: 5px;
margin-bottom: 5px;
.rip-search {
.rip-input {
display: flex;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
position: relative;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
padding-bottom: 20px;
border-bottom: 1px dashed #e5e5e5;
margin-bottom: 20px;
input {
width: 100% !important;
transition: all .1s ease-in-out;
padding: 16px 48px 16px 24px;
font-size: 25px;
border: 2px solid #dee2e6;
box-shadow: inset 0 0.25rem 0.125rem 0 rgba(0,0,0,0.05);
color: #495057;
border-radius: 4px;
&::placeholder {
color: #c9cbcd;
}
}
span {
position: absolute;
right: 25px;
font-size: 28px;
color: #caccce;
opacity: 0.4;
}
}
}
.rip-content {
width: 100%;
.rip-not-found {
min-height: 75vh;
display: flex;
align-items: center;
align-self: center;
align-content: center;
min-width: 100%;
text-align: center;
svg {
margin: 0 auto;
font-size: 50px;
color: #adb5bd;
}
}
h4.icon-title {
font-size: 20px;
text-transform: uppercase;
letter-spacing: 0.03em;
margin-bottom: 25px;
}
.rip-row {
width: 100%;
display: flex;
flex-wrap: wrap;
margin: 0;
padding: 0;
.rip-col {
text-align: center;
padding: 0 0 16px;
width: 25%;
list-style: none;
.icon-content {
border-radius: 3px;
transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1);
transform: translateZ(0);
.icon-el {
padding: 8px;
font-size: 35px;
font-weight: 900;
color: #495057;
cursor: pointer;
transition: all ;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
&:hover {
color: #fff;
background: #339af0;
}
}
.icon-title {
padding: 8px 4px;
font-size: 13px;
color: #adb5bd;
&:hover {
color: #495057;
}
}
&:hover {
background: #fff;
box-shadow: 0 0.25rem 0.125rem 0 rgba(0,0,0,0.05);
}
}
@media (min-width: 576px) {
width: 20%;
}
@media (min-width: 768px) {
width: 16.6667%;
}
@media (min-width: 1200px) {
width: 11.1111%;
}
}
}
}
}
}
}
@keyframes rebound {
0% {
-webkit-transform: scale(.9);
transform: scale(.9);
}
50% {
-webkit-transform: scale(1.08);
transform: scale(1.08);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}

View File

@@ -0,0 +1,437 @@
const brand = [
'500px',
'accessible-icon',
'accusoft',
'acquisitions-incorporated',
'adn',
'adobe',
'adversal',
'affiliatetheme',
'airbnb',
'algolia',
'alipay',
'amazon',
'amazon-pay',
'amilia',
'android',
'angellist',
'angrycreative',
'angular',
'app-store',
'app-store-ios',
'apper',
'apple',
'apple-pay',
'artstation',
'asymmetrik',
'atlassian',
'audible',
'autoprefixer',
'avianex',
'aviato',
'aws',
'bandcamp',
'battle-net',
'behance',
'behance-square',
'bimobject',
'bitbucket',
'bitcoin',
'bity',
'black-tie',
'blackberry',
'blogger',
'blogger-b',
'bluetooth',
'bluetooth-b',
'bootstrap',
'btc',
'buffer',
'buromobelexperte',
'buy-n-large',
'buysellads',
'canadian-maple-leaf',
'cc-amazon-pay',
'cc-amex',
'cc-apple-pay',
'cc-diners-club',
'cc-discover',
'cc-jcb',
'cc-mastercard',
'cc-paypal',
'cc-stripe',
'cc-visa',
'centercode',
'centos',
'chrome',
'chromecast',
'cloudscale',
'cloudsmith',
'cloudversify',
'codepen',
'codiepie',
'confluence',
'connectdevelop',
'contao',
'cotton-bureau',
'cpanel',
'creative-commons',
'creative-commons-by',
'creative-commons-nc',
'creative-commons-nc-eu',
'creative-commons-nc-jp',
'creative-commons-nd',
'creative-commons-pd',
'creative-commons-pd-alt',
'creative-commons-remix',
'creative-commons-sa',
'creative-commons-sampling',
'creative-commons-sampling-plus',
'creative-commons-share',
'creative-commons-zero',
'critical-role',
'css3',
'css3-alt',
'cuttlefish',
'd-and-d',
'd-and-d-beyond',
'dashcube',
'delicious',
'deploydog',
'deskpro',
'dev',
'deviantart',
'dhl',
'diaspora',
'digg',
'digital-ocean',
'discord',
'discourse',
'dochub',
'docker',
'draft2digital',
'dribbble',
'dribbble-square',
'dropbox',
'drupal',
'dyalog',
'earlybirds',
'ebay',
'edge',
'elementor',
'ello',
'ember',
'empire',
'envira',
'erlang',
'ethereum',
'etsy',
'evernote',
'expeditedssl',
'facebook',
'facebook-f',
'facebook-messenger',
'facebook-square',
'fantasy-flight-games',
'fedex',
'fedora',
'figma',
'firefox',
'first-order',
'first-order-alt',
'firstdraft',
'flickr',
'flipboard',
'fly',
'font-awesome',
'font-awesome-alt',
'font-awesome-flag',
'fonticons',
'fonticons-fi',
'fort-awesome',
'fort-awesome-alt',
'forumbee',
'foursquare',
'free-code-camp',
'freebsd',
'fulcrum',
'galactic-republic',
'galactic-senate',
'get-pocket',
'gg',
'gg-circle',
'git',
'git-alt',
'git-square',
'github',
'github-alt',
'github-square',
'gitkraken',
'gitlab',
'gitter',
'glide',
'glide-g',
'gofore',
'goodreads',
'goodreads-g',
'google',
'google-drive',
'google-play',
'google-plus',
'google-plus-g',
'google-plus-square',
'google-wallet',
'gratipay',
'grav',
'gripfire',
'grunt',
'gulp',
'hacker-news',
'hacker-news-square',
'hackerrank',
'hips',
'hire-a-helper',
'hooli',
'hornbill',
'hotjar',
'houzz',
'html5',
'hubspot',
'imdb',
'instagram',
'intercom',
'internet-explorer',
'invision',
'ioxhost',
'itch-io',
'itunes',
'itunes-note',
'java',
'jedi-order',
'jenkins',
'jira',
'joget',
'joomla',
'js',
'js-square',
'jsfiddle',
'kaggle',
'keybase',
'keycdn',
'kickstarter',
'kickstarter-k',
'korvue',
'laravel',
'lastfm',
'lastfm-square',
'leanpub',
'less',
'line',
'linkedin',
'linkedin-in',
'linode',
'linux',
'lyft',
'magento',
'mailchimp',
'mandalorian',
'markdown',
'mastodon',
'maxcdn',
'mdb',
'medapps',
'medium',
'medium-m',
'medrt',
'meetup',
'megaport',
'mendeley',
'microsoft',
'mix',
'mixcloud',
'mizuni',
'modx',
'monero',
'napster',
'neos',
'nimblr',
'node',
'node-js',
'npm',
'ns8',
'nutritionix',
'odnoklassniki',
'odnoklassniki-square',
'old-republic',
'opencart',
'openid',
'opera',
'optin-monster',
'orcid',
'osi',
'page4',
'pagelines',
'palfed',
'patreon',
'paypal',
'penny-arcade',
'periscope',
'phabricator',
'phoenix-framework',
'phoenix-squadron',
'php',
'pied-piper',
'pied-piper-alt',
'pied-piper-hat',
'pied-piper-pp',
'pinterest',
'pinterest-p',
'pinterest-square',
'playstation',
'product-hunt',
'pushed',
'python',
'qq',
'quinscape',
'quora',
'r-project',
'raspberry-pi',
'ravelry',
'react',
'reacteurope',
'readme',
'rebel',
'red-river',
'reddit',
'reddit-alien',
'reddit-square',
'redhat',
'renren',
'replyd',
'researchgate',
'resolving',
'rev',
'rocketchat',
'rockrms',
'safari',
'salesforce',
'sass',
'schlix',
'scribd',
'searchengin',
'sellcast',
'sellsy',
'servicestack',
'shirtsinbulk',
'shopware',
'simplybuilt',
'sistrix',
'sith',
'sketch',
'skyatlas',
'skype',
'slack',
'slack-hash',
'slideshare',
'snapchat',
'snapchat-ghost',
'snapchat-square',
'soundcloud',
'sourcetree',
'speakap',
'speaker-deck',
'spotify',
'squarespace',
'stack-exchange',
'stack-overflow',
'stackpath',
'staylinked',
'steam',
'steam-square',
'steam-symbol',
'sticker-mule',
'strava',
'stripe',
'stripe-s',
'studiovinari',
'stumbleupon',
'stumbleupon-circle',
'superpowers',
'supple',
'suse',
'swift',
'symfony',
'teamspeak',
'telegram',
'telegram-plane',
'tencent-weibo',
'the-red-yeti',
'themeco',
'themeisle',
'think-peaks',
'trade-federation',
'trello',
'tripadvisor',
'tumblr',
'tumblr-square',
'twitch',
'twitter',
'twitter-square',
'typo3',
'uber',
'ubuntu',
'uikit',
'umbraco',
'uniregistry',
'untappd',
'ups',
'usb',
'usps',
'ussunnah',
'vaadin',
'viacoin',
'viadeo',
'viadeo-square',
'viber',
'vimeo',
'vimeo-square',
'vimeo-v',
'vine',
'vk',
'vnv',
'vuejs',
'waze',
'weebly',
'weibo',
'weixin',
'whatsapp',
'whatsapp-square',
'whmcs',
'wikipedia-w',
'windows',
'wix',
'wizards-of-the-coast',
'wolf-pack-battalion',
'wordpress',
'wordpress-simple',
'wpbeginner',
'wpexplorer',
'wpforms',
'wpressr',
'xbox',
'xing',
'xing-square',
'y-combinator',
'yahoo',
'yammer',
'yandex',
'yandex-international',
'yarn',
'yelp',
'yoast',
'youtube',
'youtube-square',
'zhihu'
];
export default brand;

View File

@@ -0,0 +1,7 @@
import solid from "./solid";
import regular from "./regular";
import brand from "./brand";
const icons = { solid, brand, regular };
export default icons;

View File

@@ -0,0 +1,155 @@
const regular = [
'address-book',
'address-card',
'angry',
'arrow-alt-circle-down',
'arrow-alt-circle-left',
'arrow-alt-circle-right',
'arrow-alt-circle-up',
'bell',
'bell-slash',
'bookmark',
'building',
'calendar',
'calendar-alt',
'calendar-check',
'calendar-minus',
'calendar-plus',
'calendar-times',
'caret-square-down',
'caret-square-left',
'caret-square-right',
'caret-square-up',
'chart-bar',
'check-circle',
'check-square',
'circle',
'clipboard',
'clock',
'clone',
'closed-captioning',
'comment',
'comment-alt',
'comment-dots',
'comments',
'compass',
'copy',
'copyright',
'credit-card',
'dizzy',
'dot-circle',
'edit',
'envelope',
'envelope-open',
'eye',
'eye-slash',
'file',
'file-alt',
'file-archive',
'file-audio',
'file-code',
'file-excel',
'file-image',
'file-pdf',
'file-powerpoint',
'file-video',
'file-word',
'flag',
'flushed',
'folder',
'folder-open',
'frown',
'frown-open',
'futbol',
'gem',
'grimace',
'grin',
'grin-alt',
'grin-beam',
'grin-beam-sweat',
'grin-hearts',
'grin-squint',
'grin-squint-tears',
'grin-stars',
'grin-tears',
'grin-tongue',
'grin-tongue-squint',
'grin-tongue-wink',
'grin-wink',
'hand-lizard',
'hand-paper',
'hand-peace',
'hand-point-down',
'hand-point-left',
'hand-point-right',
'hand-point-up',
'hand-pointer',
'hand-rock',
'hand-scissors',
'hand-spock',
'handshake',
'hdd',
'heart',
'hospital',
'hourglass',
'id-badge',
'id-card',
'image',
'images',
'keyboard',
'kiss',
'kiss-beam',
'kiss-wink-heart',
'laugh',
'laugh-beam',
'laugh-squint',
'laugh-wink',
'lemon',
'life-ring',
'lightbulb',
'list-alt',
'map',
'meh',
'meh-blank',
'meh-rolling-eyes',
'minus-square',
'money-bill-alt',
'moon',
'newspaper',
'object-group',
'object-ungroup',
'paper-plane',
'pause-circle',
'play-circle',
'plus-square',
'question-circle',
'registered',
'sad-cry',
'sad-tear',
'save',
'share-square',
'smile',
'smile-beam',
'smile-wink',
'snowflake',
'square',
'star',
'star-half',
'sticky-note',
'stop-circle',
'sun',
'surprise',
'thumbs-down',
'thumbs-up',
'times-circle',
'tired',
'trash-alt',
'user',
'user-circle',
'window-close',
'window-maximize',
'window-minimize',
'window-restore'
];
export default regular;

View File

@@ -0,0 +1,962 @@
const solid = [
'ad',
'address-book',
'address-card',
'adjust',
'air-freshener',
'align-center',
'align-justify',
'align-left',
'align-right',
'allergies',
'ambulance',
'american-sign-language-interpreting',
'anchor',
'angle-double-down',
'angle-double-left',
'angle-double-right',
'angle-double-up',
'angle-down',
'angle-left',
'angle-right',
'angle-up',
'angry',
'ankh',
'apple-alt',
'archive',
'archway',
'arrow-alt-circle-down',
'arrow-alt-circle-left',
'arrow-alt-circle-right',
'arrow-alt-circle-up',
'arrow-circle-down',
'arrow-circle-left',
'arrow-circle-right',
'arrow-circle-up',
'arrow-down',
'arrow-left',
'arrow-right',
'arrow-up',
'arrows-alt',
'arrows-alt-h',
'arrows-alt-v',
'assistive-listening-systems',
'asterisk',
'at',
'atlas',
'atom',
'audio-description',
'award',
'baby',
'baby-carriage',
'backspace',
'backward',
'bacon',
'balance-scale',
'balance-scale-left',
'balance-scale-right',
'ban',
'band-aid',
'barcode',
'bars',
'baseball-ball',
'basketball-ball',
'bath',
'battery-empty',
'battery-full',
'battery-half',
'battery-quarter',
'battery-three-quarters',
'bed',
'beer',
'bell',
'bell-slash',
'bezier-curve',
'bible',
'bicycle',
'biking',
'binoculars',
'biohazard',
'birthday-cake',
'blender',
'blender-phone',
'blind',
'blog',
'bold',
'bolt',
'bomb',
'bone',
'bong',
'book',
'book-dead',
'book-medical',
'book-open',
'book-reader',
'bookmark',
'border-all',
'border-none',
'border-style',
'bowling-ball',
'box',
'box-open',
'boxes',
'braille',
'brain',
'bread-slice',
'briefcase',
'briefcase-medical',
'broadcast-tower',
'broom',
'brush',
'bug',
'building',
'bullhorn',
'bullseye',
'burn',
'bus',
'bus-alt',
'business-time',
'calculator',
'calendar',
'calendar-alt',
'calendar-check',
'calendar-day',
'calendar-minus',
'calendar-plus',
'calendar-times',
'calendar-week',
'camera',
'camera-retro',
'campground',
'candy-cane',
'cannabis',
'capsules',
'car',
'car-alt',
'car-battery',
'car-crash',
'car-side',
'caret-down',
'caret-left',
'caret-right',
'caret-square-down',
'caret-square-left',
'caret-square-right',
'caret-square-up',
'caret-up',
'carrot',
'cart-arrow-down',
'cart-plus',
'cash-register',
'cat',
'certificate',
'chair',
'chalkboard',
'chalkboard-teacher',
'charging-station',
'chart-area',
'chart-bar',
'chart-line',
'chart-pie',
'check',
'check-circle',
'check-double',
'check-square',
'cheese',
'chess',
'chess-bishop',
'chess-board',
'chess-king',
'chess-knight',
'chess-pawn',
'chess-queen',
'chess-rook',
'chevron-circle-down',
'chevron-circle-left',
'chevron-circle-right',
'chevron-circle-up',
'chevron-down',
'chevron-left',
'chevron-right',
'chevron-up',
'child',
'church',
'circle',
'circle-notch',
'city',
'clinic-medical',
'clipboard',
'clipboard-check',
'clipboard-list',
'clock',
'clone',
'closed-captioning',
'cloud',
'cloud-download-alt',
'cloud-meatball',
'cloud-moon',
'cloud-moon-rain',
'cloud-rain',
'cloud-showers-heavy',
'cloud-sun',
'cloud-sun-rain',
'cloud-upload-alt',
'cocktail',
'code',
'code-branch',
'coffee',
'cog',
'cogs',
'coins',
'columns',
'comment',
'comment-alt',
'comment-dollar',
'comment-dots',
'comment-medical',
'comment-slash',
'comments',
'comments-dollar',
'compact-disc',
'compass',
'compress',
'compress-arrows-alt',
'concierge-bell',
'cookie',
'cookie-bite',
'copy',
'copyright',
'couch',
'credit-card',
'crop',
'crop-alt',
'cross',
'crosshairs',
'crow',
'crown',
'crutch',
'cube',
'cubes',
'cut',
'database',
'deaf',
'democrat',
'desktop',
'dharmachakra',
'diagnoses',
'dice',
'dice-d20',
'dice-d6',
'dice-five',
'dice-four',
'dice-one',
'dice-six',
'dice-three',
'dice-two',
'digital-tachograph',
'directions',
'divide',
'dizzy',
'dna',
'dog',
'dollar-sign',
'dolly',
'dolly-flatbed',
'donate',
'door-closed',
'door-open',
'dot-circle',
'dove',
'download',
'drafting-compass',
'dragon',
'draw-polygon',
'drum',
'drum-steelpan',
'drumstick-bite',
'dumbbell',
'dumpster',
'dumpster-fire',
'dungeon',
'edit',
'egg',
'eject',
'ellipsis-h',
'ellipsis-v',
'envelope',
'envelope-open',
'envelope-open-text',
'envelope-square',
'equals',
'eraser',
'ethernet',
'euro-sign',
'exchange-alt',
'exclamation',
'exclamation-circle',
'exclamation-triangle',
'expand',
'expand-arrows-alt',
'external-link-alt',
'external-link-square-alt',
'eye',
'eye-dropper',
'eye-slash',
'fan',
'fast-backward',
'fast-forward',
'fax',
'feather',
'feather-alt',
'female',
'fighter-jet',
'file',
'file-alt',
'file-archive',
'file-audio',
'file-code',
'file-contract',
'file-csv',
'file-download',
'file-excel',
'file-export',
'file-image',
'file-import',
'file-invoice',
'file-invoice-dollar',
'file-medical',
'file-medical-alt',
'file-pdf',
'file-powerpoint',
'file-prescription',
'file-signature',
'file-upload',
'file-video',
'file-word',
'fill',
'fill-drip',
'film',
'filter',
'fingerprint',
'fire',
'fire-alt',
'fire-extinguisher',
'first-aid',
'fish',
'fist-raised',
'flag',
'flag-checkered',
'flag-usa',
'flask',
'flushed',
'folder',
'folder-minus',
'folder-open',
'folder-plus',
'font',
'football-ball',
'forward',
'frog',
'frown',
'frown-open',
'funnel-dollar',
'futbol',
'gamepad',
'gas-pump',
'gavel',
'gem',
'genderless',
'ghost',
'gift',
'gifts',
'glass-cheers',
'glass-martini',
'glass-martini-alt',
'glass-whiskey',
'glasses',
'globe',
'globe-africa',
'globe-americas',
'globe-asia',
'globe-europe',
'golf-ball',
'gopuram',
'graduation-cap',
'greater-than',
'greater-than-equal',
'grimace',
'grin',
'grin-alt',
'grin-beam',
'grin-beam-sweat',
'grin-hearts',
'grin-squint',
'grin-squint-tears',
'grin-stars',
'grin-tears',
'grin-tongue',
'grin-tongue-squint',
'grin-tongue-wink',
'grin-wink',
'grip-horizontal',
'grip-lines',
'grip-lines-vertical',
'grip-vertical',
'guitar',
'h-square',
'hamburger',
'hammer',
'hamsa',
'hand-holding',
'hand-holding-heart',
'hand-holding-usd',
'hand-lizard',
'hand-middle-finger',
'hand-paper',
'hand-peace',
'hand-point-down',
'hand-point-left',
'hand-point-right',
'hand-point-up',
'hand-pointer',
'hand-rock',
'hand-scissors',
'hand-spock',
'hands',
'hands-helping',
'handshake',
'hanukiah',
'hard-hat',
'hashtag',
'hat-cowboy',
'hat-cowboy-side',
'hat-wizard',
'heading',
'headphones',
'headphones-alt',
'headset',
'heart',
'heart-broken',
'heartbeat',
'helicopter',
'highlighter',
'hiking',
'hippo',
'history',
'hockey-puck',
'holly-berry',
'home',
'horse',
'horse-head',
'hospital',
'hospital-alt',
'hospital-symbol',
'hot-tub',
'hotdog',
'hotel',
'hourglass',
'hourglass-end',
'hourglass-half',
'hourglass-start',
'house-damage',
'hryvnia',
'i-cursor',
'ice-cream',
'icicles',
'icons',
'id-badge',
'id-card',
'id-card-alt',
'igloo',
'image',
'images',
'inbox',
'indent',
'industry',
'infinity',
'info',
'info-circle',
'italic',
'jedi',
'joint',
'journal-whills',
'kaaba',
'key',
'keyboard',
'khanda',
'kiss',
'kiss-beam',
'kiss-wink-heart',
'kiwi-bird',
'landmark',
'language',
'laptop',
'laptop-code',
'laptop-medical',
'laugh',
'laugh-beam',
'laugh-squint',
'laugh-wink',
'layer-group',
'leaf',
'lemon',
'less-than',
'less-than-equal',
'level-down-alt',
'level-up-alt',
'life-ring',
'lightbulb',
'link',
'lira-sign',
'list',
'list-alt',
'list-ol',
'list-ul',
'location-arrow',
'lock',
'lock-open',
'long-arrow-alt-down',
'long-arrow-alt-left',
'long-arrow-alt-right',
'long-arrow-alt-up',
'low-vision',
'luggage-cart',
'magic',
'magnet',
'mail-bulk',
'male',
'map',
'map-marked',
'map-marked-alt',
'map-marker',
'map-marker-alt',
'map-pin',
'map-signs',
'marker',
'mars',
'mars-double',
'mars-stroke',
'mars-stroke-h',
'mars-stroke-v',
'mask',
'medal',
'medkit',
'meh',
'meh-blank',
'meh-rolling-eyes',
'memory',
'menorah',
'mercury',
'meteor',
'microchip',
'microphone',
'microphone-alt',
'microphone-alt-slash',
'microphone-slash',
'microscope',
'minus',
'minus-circle',
'minus-square',
'mitten',
'mobile',
'mobile-alt',
'money-bill',
'money-bill-alt',
'money-bill-wave',
'money-bill-wave-alt',
'money-check',
'money-check-alt',
'monument',
'moon',
'mortar-pestle',
'mosque',
'motorcycle',
'mountain',
'mouse',
'mouse-pointer',
'mug-hot',
'music',
'network-wired',
'neuter',
'newspaper',
'not-equal',
'notes-medical',
'object-group',
'object-ungroup',
'oil-can',
'om',
'otter',
'outdent',
'pager',
'paint-brush',
'paint-roller',
'palette',
'pallet',
'paper-plane',
'paperclip',
'parachute-box',
'paragraph',
'parking',
'passport',
'pastafarianism',
'paste',
'pause',
'pause-circle',
'paw',
'peace',
'pen',
'pen-alt',
'pen-fancy',
'pen-nib',
'pen-square',
'pencil-alt',
'pencil-ruler',
'people-carry',
'pepper-hot',
'percent',
'percentage',
'person-booth',
'phone',
'phone-alt',
'phone-slash',
'phone-square',
'phone-square-alt',
'phone-volume',
'photo-video',
'piggy-bank',
'pills',
'pizza-slice',
'place-of-worship',
'plane',
'plane-arrival',
'plane-departure',
'play',
'play-circle',
'plug',
'plus',
'plus-circle',
'plus-square',
'podcast',
'poll',
'poll-h',
'poo',
'poo-storm',
'poop',
'portrait',
'pound-sign',
'power-off',
'pray',
'praying-hands',
'prescription',
'prescription-bottle',
'prescription-bottle-alt',
'print',
'procedures',
'project-diagram',
'puzzle-piece',
'qrcode',
'question',
'question-circle',
'quidditch',
'quote-left',
'quote-right',
'quran',
'radiation',
'radiation-alt',
'rainbow',
'random',
'receipt',
'record-vinyl',
'recycle',
'redo',
'redo-alt',
'registered',
'remove-format',
'reply',
'reply-all',
'republican',
'restroom',
'retweet',
'ribbon',
'ring',
'road',
'robot',
'rocket',
'route',
'rss',
'rss-square',
'ruble-sign',
'ruler',
'ruler-combined',
'ruler-horizontal',
'ruler-vertical',
'running',
'rupee-sign',
'sad-cry',
'sad-tear',
'satellite',
'satellite-dish',
'save',
'school',
'screwdriver',
'scroll',
'sd-card',
'search',
'search-dollar',
'search-location',
'search-minus',
'search-plus',
'seedling',
'server',
'shapes',
'share',
'share-alt',
'share-alt-square',
'share-square',
'shekel-sign',
'shield-alt',
'ship',
'shipping-fast',
'shoe-prints',
'shopping-bag',
'shopping-basket',
'shopping-cart',
'shower',
'shuttle-van',
'sign',
'sign-in-alt',
'sign-language',
'sign-out-alt',
'signal',
'signature',
'sim-card',
'sitemap',
'skating',
'skiing',
'skiing-nordic',
'skull',
'skull-crossbones',
'slash',
'sleigh',
'sliders-h',
'smile',
'smile-beam',
'smile-wink',
'smog',
'smoking',
'smoking-ban',
'sms',
'snowboarding',
'snowflake',
'snowman',
'snowplow',
'socks',
'solar-panel',
'sort',
'sort-alpha-down',
'sort-alpha-down-alt',
'sort-alpha-up',
'sort-alpha-up-alt',
'sort-amount-down',
'sort-amount-down-alt',
'sort-amount-up',
'sort-amount-up-alt',
'sort-down',
'sort-numeric-down',
'sort-numeric-down-alt',
'sort-numeric-up',
'sort-numeric-up-alt',
'sort-up',
'spa',
'space-shuttle',
'spell-check',
'spider',
'spinner',
'splotch',
'spray-can',
'square',
'square-full',
'square-root-alt',
'stamp',
'star',
'star-and-crescent',
'star-half',
'star-half-alt',
'star-of-david',
'star-of-life',
'step-backward',
'step-forward',
'stethoscope',
'sticky-note',
'stop',
'stop-circle',
'stopwatch',
'store',
'store-alt',
'stream',
'street-view',
'strikethrough',
'stroopwafel',
'subscript',
'subway',
'suitcase',
'suitcase-rolling',
'sun',
'superscript',
'surprise',
'swatchbook',
'swimmer',
'swimming-pool',
'synagogue',
'sync',
'sync-alt',
'syringe',
'table',
'table-tennis',
'tablet',
'tablet-alt',
'tablets',
'tachometer-alt',
'tag',
'tags',
'tape',
'tasks',
'taxi',
'teeth',
'teeth-open',
'temperature-high',
'temperature-low',
'tenge',
'terminal',
'text-height',
'text-width',
'th',
'th-large',
'th-list',
'theater-masks',
'thermometer',
'thermometer-empty',
'thermometer-full',
'thermometer-half',
'thermometer-quarter',
'thermometer-three-quarters',
'thumbs-down',
'thumbs-up',
'thumbtack',
'ticket-alt',
'times',
'times-circle',
'tint',
'tint-slash',
'tired',
'toggle-off',
'toggle-on',
'toilet',
'toilet-paper',
'toolbox',
'tools',
'tooth',
'torah',
'torii-gate',
'tractor',
'trademark',
'traffic-light',
'train',
'tram',
'transgender',
'transgender-alt',
'trash',
'trash-alt',
'trash-restore',
'trash-restore-alt',
'tree',
'trophy',
'truck',
'truck-loading',
'truck-monster',
'truck-moving',
'truck-pickup',
'tshirt',
'tty',
'tv',
'umbrella',
'umbrella-beach',
'underline',
'undo',
'undo-alt',
'universal-access',
'university',
'unlink',
'unlock',
'unlock-alt',
'upload',
'user',
'user-alt',
'user-alt-slash',
'user-astronaut',
'user-check',
'user-circle',
'user-clock',
'user-cog',
'user-edit',
'user-friends',
'user-graduate',
'user-injured',
'user-lock',
'user-md',
'user-minus',
'user-ninja',
'user-nurse',
'user-plus',
'user-secret',
'user-shield',
'user-slash',
'user-tag',
'user-tie',
'user-times',
'users',
'users-cog',
'utensil-spoon',
'utensils',
'vector-square',
'venus',
'venus-double',
'venus-mars',
'vial',
'vials',
'video',
'video-slash',
'vihara',
'voicemail',
'volleyball-ball',
'volume-down',
'volume-mute',
'volume-off',
'volume-up',
'vote-yea',
'vr-cardboard',
'walking',
'wallet',
'warehouse',
'water',
'wave-square',
'weight',
'weight-hanging',
'wheelchair',
'wifi',
'wind',
'window-close',
'window-maximize',
'window-minimize',
'window-restore',
'wine-bottle',
'wine-glass',
'wine-glass-alt',
'won-sign',
'wrench',
'x-ray',
'yen-sign',
'yin-yang'
];
export default solid;

View File

@@ -235,7 +235,9 @@ export default {
initialFilters = this.prepareFilterItems(element.items, this.selected, true);
}
//adding process name filter
if (self.byProcessName !== "") {
initialFilters =[...new Set([...initialFilters,...this.prepareFilterItems(this.processName.items, self.byProcessName, true)])];
}
this.$emit("onUpdateFilters", {params: initialFilters, refresh: false});
},
/**

View File

@@ -0,0 +1,53 @@
<template>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li
v-for="item in formatOptions(options)"
:key="item.label"
:class="item.classObject"
>
<span v-if="item.classObject.active === true">{{ item.label }}</span>
<a
v-if="item.classObject.active === false"
href="#"
@click="item.onClick"
>{{ item.label }}</a
>
</li>
</ol>
</nav>
</template>
<script>
import _ from "lodash";
export default {
name: "BreadCrumb",
props: ["options"],
data() {
return {};
},
methods: {
/**
* format options to Bread Crumbs
*/
formatOptions(data) {
let options = data;
for (let i = 0; i <= options.length - 1; i++) {
if (i === options.length - 1) {
options[i].classObject = {
"breadcrumb-item": true,
active: true,
};
} else {
options[i].classObject = {
"breadcrumb-item": true,
active: false,
};
}
}
console.log("aquii");
return options;
},
},
};
</script>

View File

@@ -0,0 +1,17 @@
<template>
<font-awesome-icon v-if="props.sortable" :icon="icon" class="fa-pull-right"/>
</template>
<script>
export default {
name: "VtSortControl",
props: ['props'],
computed: {
icon() {
// if not sorted return base icon
if (!this.props.sortStatus.sorted) return 'sort';
// return sort direction icon
return this.props.sortStatus.asc ? 'sort-amount-up' : 'sort-amount-down';
}
}
}
</script>

View File

@@ -169,21 +169,12 @@ export default {
selectAllMode: "page",
programmatic: false,
},
sortable: [],
orderBy: {},
requestFunction(data) {
return this.$parent.$parent.getCasesForVueTable(data);
},
customFilters: ["myfilter"],
settings: {
"actions":{
class: "fas fa-cog",
id:"pm-dr-column-settings",
events:{
click(){
that.$root.$emit('bv::show::popover', 'pm-dr-column-settings')
}
}
}
}
customFilters: ["myfilter"]
},
pmDateFormat: window.config.FORMATS.dateFormat,
clickCount: 0,

View File

@@ -22,6 +22,7 @@
ref="vueTable"
@row-click="onRowClick"
:key="random"
name="draft"
>
<div slot="detail" slot-scope="props">
<div class="btn-default" @click="openCaseDetail(props.row)">
@@ -194,6 +195,7 @@ import VueCardView from "../../components/dataViews/vueCardView/VueCardView.vue"
import VueListView from "../../components/dataViews/vueListView/VueListView.vue";
import defaultMixins from "./defaultMixins";
import Ellipsis from '../../components/utils/ellipsis.vue';
import { Event } from 'vue-tables-2';
export default {
name: "Draft",
@@ -209,10 +211,15 @@ export default {
VueCardView,
VueListView
},
props: ["defaultOption", "filters"],
props: ["defaultOption", "settings"],
data() {
let that = this;
return {
columMap: {
case_number: "APP_NUMBER",
case_title: "DEL_TITLE",
process_name: "PRO_TITLE"
},
newCase: {
title: this.$i18n.t("ID_NEW_CASE"),
class: "btn-success",
@@ -220,7 +227,14 @@ export default {
this.$refs["newRequest"].show();
},
},
columns: [
filters:
this.settings && this.settings.filters
? this.settings.filters
: {},
columns:
this.settings && this.settings.columns
? this.settings.columns
: [
"detail",
"case_number",
"case_title",
@@ -234,7 +248,7 @@ export default {
options: {
filterable: false,
headings: {
detail: "",
detail: this.$i18n.t("ID_DETAIL_CASE"),
case_number: this.$i18n.t("ID_MYCASE_NUMBER"),
case_title: this.$i18n.t("ID_CASE_TITLE"),
process_name: this.$i18n.t("ID_PROCESS_NAME"),
@@ -249,6 +263,8 @@ export default {
selectAllMode: "page",
programmatic: false,
},
sortable: ['case_number'],
orderBy: this.settings && this.settings.orderBy ? this.settings.orderBy: {},
requestFunction(data) {
return this.$parent.$parent.getCasesForVueTable(data);
},
@@ -294,9 +310,21 @@ export default {
this.initFilters();
},
mounted() {
let that = this;
this.openDefaultCase();
// define sort event
Event.$on('vue-tables.draft.sorted', function (data) {
that.$emit("updateUserSettings", "orderBy", data);
});
},
watch: {
columns: function (val) {
this.$emit("updateUserSettings", "columns", val);
},
filters: function (val) {
this.$emit("updateUserSettings", "filters", val);
},
},
watch: {},
computed: {
/**
* Build our ProcessMaker apiClient
@@ -388,7 +416,8 @@ export default {
paged,
limit = data.limit,
start = data.page === 1 ? 0 : limit * (data.page - 1),
filters = {};
filters = {},
sort = "";
paged = start + "," + limit;
filters = {
@@ -400,6 +429,10 @@ export default {
filters[item.filterVar] = item.value;
}
});
sort = that.prepareSortString(data);
if (sort) {
filters["sort"] = sort;
}
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases
.draft(filters)
@@ -415,6 +448,18 @@ export default {
});
});
},
/**
* Prepare sort string to be sended in the service
* @param {object} data
* @returns {string}
*/
prepareSortString(data){
let sort = "";
if (data.orderBy && this.columMap[data.orderBy]) {
sort = `${this.columMap[data.orderBy]},${data.ascending === 1 ? "ASC": "DESC"}`;
}
return sort;
},
/**
* Format Response API TODO to grid todo and columns
*/
@@ -480,7 +525,7 @@ export default {
},
onRemoveFilter(data) {},
onUpdateFilters(data) {
this.$emit("onUpdateFilters", data.params);
this.filters = data.params;
if (data.refresh) {
this.$nextTick(() => {
if (this.typeView === "GRID") {

View File

@@ -87,8 +87,10 @@ export default {
_.forIn(this.filters, function (item, key) {
if (item.value && item.value != "") {
if(filters && item.value) {
filters[item.filterVar] = item.value;
}
}
});
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases

View File

@@ -20,11 +20,12 @@
<component
v-bind:is="page"
ref="component"
:filters="filters"
:id="pageId"
:pageUri="pageUri"
:name="pageName"
:defaultOption="defaultOption"
:settings="config.setting[page]"
:filters="filters"
@onSubmitFilter="onSubmitFilter"
@onRemoveFilter="onRemoveFilter"
@onUpdatePage="onUpdatePage"
@@ -32,6 +33,7 @@
@onLastPage="onLastPage"
@onUpdateFilters="onUpdateFilters"
@cleanDefaultOption="cleanDefaultOption"
@updateUserSettings="updateUserSettings"
></component>
</div>
</div>
@@ -87,6 +89,11 @@ export default {
pageName: null,
pageUri: null,
filters: null,
config: {
id: window.config.userId || "1",
name: "home",
setting: {}
},
menuMap: {
CASES_MY_CASES: "MyCases",
CASES_SENT: "MyCases",
@@ -105,6 +112,7 @@ export default {
mounted() {
this.onResize();
this.getMenu();
this.getUserSettings();
this.listenerIframe();
window.setInterval(
this.setCounter,
@@ -150,6 +158,65 @@ export default {
console.error(e);
});
},
/**
* Gets the user config
*/
getUserSettings() {
api.config
.get({
id: this.config.id,
name: this.config.name
})
.then((response) => {
if (response.data) {
this.config = response.data;
} else {
this.createUserSettings();
}
})
.catch((e) => {
console.error(e);
});
},
/**
* Creates the user config service
*/
createUserSettings() {
api.config
.post({
...this.configParams,
...{setting: '{}'}
})
.then((response) => {
if (response.data) {
this.config = response.data;
}
})
.catch((e) => {
console.error(e);
});
},
/**
* Update the user config service
*/
updateUserSettings(prop, data) {
if (this.config.setting) {
if (!this.config.setting[this.page]) {
this.config.setting[this.page] = {};
}
this.config.setting[this.page][prop] = data;
api.config
.put(this.config)
.then((response) => {
if (response.data) {
//TODO success response
}
})
.catch((e) => {
console.error(e);
});
}
},
/**
* Set default cases menu option
*/
@@ -337,7 +404,7 @@ export default {
},
onUpdateFilters(filters) {
this.filters = filters;
}
},
}
};
</script>

View File

@@ -25,6 +25,7 @@
ref="vueTable"
@row-click="onRowClick"
:key="random"
name="todo"
>
<div slot="detail" slot-scope="props">
<div class="btn-default" @click="openCaseDetail(props.row)">
@@ -227,6 +228,7 @@ import defaultMixins from "./defaultMixins";
import Ellipsis from '../../components/utils/ellipsis.vue';
import ModalPauseCase from '../modal/ModalPauseCase.vue';
import ModalReassignCase from '../modal/ModalReassignCase.vue';
import { Event } from 'vue-tables-2';
import CurrentUserCell from "../../components/vuetable/CurrentUserCell.vue";
export default {
@@ -246,10 +248,15 @@ export default {
ModalReassignCase,
CurrentUserCell,
},
props: ["defaultOption", "filters"],
props: ["defaultOption", "settings"],
data() {
let that = this;
return {
columMap: {
case_number: "APP_NUMBER",
case_title: "DEL_TITLE",
process_name: "PRO_TITLE"
},
newCase: {
title: this.$i18n.t("ID_NEW_CASE"),
class: "btn-success",
@@ -257,7 +264,14 @@ export default {
this.$refs["newRequest"].show();
},
},
columns: [
filters:
this.settings && this.settings.filters
? this.settings.filters
: {},
columns:
this.settings && this.settings.columns
? this.settings.columns
: [
"detail",
"case_number",
"case_title",
@@ -302,6 +316,8 @@ export default {
selectAllMode: "page",
programmatic: false,
},
sortable: ['case_number'],
orderBy: this.settings && this.settings.orderBy ? this.settings.orderBy: {},
requestFunction(data) {
return this.$parent.$parent.getCasesForVueTable(data);
},
@@ -338,10 +354,22 @@ export default {
this.initFilters();
},
mounted() {
let that = this;
// force to open case
this.openDefaultCase();
// define sort event
Event.$on('vue-tables.todo.sorted', function (data) {
that.$emit("updateUserSettings", "orderBy", data);
});
},
watch: {
columns: function (val) {
this.$emit("updateUserSettings", "columns", val);
},
filters: function (val) {
this.$emit("updateUserSettings", "filters", val);
},
},
watch: {},
computed: {
/**
* Build our ProcessMaker apiClient
@@ -433,18 +461,22 @@ export default {
paged,
limit = data.limit,
start = data.page === 1 ? 0 : limit * (data.page - 1),
filters = {};
filters = {},
sort = "";
paged = start + "," + limit;
filters = {
paged: paged,
};
}
_.forIn(this.filters, function (item, key) {
if(filters && item.value) {
filters[item.filterVar] = item.value;
}
});
sort = that.prepareSortString(data);
if (sort) {
filters["sort"] = sort;
}
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases
.todo(filters)
@@ -460,6 +492,18 @@ export default {
});
});
},
/**
* Prepare sort string to be sended in the service
* @param {object} data
* @returns {string}
*/
prepareSortString(data){
let sort = "";
if (data.orderBy && this.columMap[data.orderBy]) {
sort = `${this.columMap[data.orderBy]},${data.ascending === 1 ? "ASC": "DESC"}`;
}
return sort;
},
/**
* Format Response API TODO to grid todo and columns
*/
@@ -562,7 +606,7 @@ export default {
},
onRemoveFilter(data) {},
onUpdateFilters(data) {
this.$emit("onUpdateFilters", data.params);
this.filters = data.params;
if (data.refresh) {
this.$nextTick(() => {
if (this.typeView === "GRID") {

View File

@@ -120,7 +120,9 @@ export default {
paged: paged,
};
_.forIn(this.filters, function (item, key) {
if(filters && item.value) {
filters[item.filterVar] = item.value;
}
});
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases

View File

@@ -20,12 +20,19 @@
/>
<header-counter :data="headers"> </header-counter>
<modal-new-request ref="newRequest"></modal-new-request>
<settings-popover :options="formatColumnSettings(options.headings)" target="pm-dr-column-settings" @onUpdateColumnSettings="onUpdateColumnSettings" :key="random+1" :selected="formatColumnSelected(columns)"/>
<settings-popover
:options="formatColumnSettings(options.headings)"
target="pm-dr-column-settings"
@onUpdateColumnSettings="onUpdateColumnSettings"
:key="random + 1"
:selected="formatColumnSelected(columns)"
/>
<v-server-table
:data="tableData"
:columns="columns"
:options="options"
ref="vueTable"
name="mycases"
@row-click="onRowClick"
:key="random"
>
@@ -57,12 +64,19 @@
{{ props.row.DURATION }}
</div>
<div slot="actions" slot-scope="props">
<div class="btn-default" v-bind:style="{ color: props.row.MESSAGE_COLOR}" @click="openComments(props.row)">
<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>
<ModalComments
ref="modal-comments"
@postNotes="onPostNotes"
></ModalComments>
</div>
</template>
@@ -76,6 +90,7 @@ import GroupedCell from "../../components/vuetable/GroupedCell.vue";
import api from "../../api/index";
import utils from "../../utils/utils";
import defaultMixins from "./defaultMixins";
import { Event } from "vue-tables-2";
export default {
name: "MyCases",
@@ -88,7 +103,7 @@ export default {
GroupedCell,
ModalComments,
},
props: ["filters", "defaultOption"],
props: ["defaultOption", "settings"],
data() {
let that = this;
return {
@@ -96,10 +111,10 @@ export default {
dismissSecs: 5,
dismissCountDown: 0,
message: "",
variant: "info"
variant: "info",
},
metrics: [],
title: this.$i18n.t('ID_MY_CASES'),
title: this.$i18n.t("ID_MY_CASES"),
filter: "CASES_INBOX",
allView: [],
filterHeader: "STARTED",
@@ -107,6 +122,11 @@ export default {
icon:"fas fa-inbox"
},
headers: [],
columMap: {
case_number: "APP_NUMBER",
case_title: "DEL_TITLE",
process_name: "PRO_TITLE",
},
random: _.random(0,1000000000),
newCase: {
title: this.$i18n.t("ID_NEW_CASE"),
@@ -115,7 +135,14 @@ export default {
this.$refs["newRequest"].show();
},
},
columns: [
filters:
this.settings && this.settings.filters
? this.settings.filters
: {},
columns:
this.settings && this.settings.columns
? this.settings.columns
: [
"case_number",
"case_title",
"process_name",
@@ -141,13 +168,13 @@ export default {
actions: "",
},
texts: {
count:this.$i18n.t("ID_SHOWING_FROM_RECORDS_COUNT"),
count: this.$i18n.t("ID_SHOWING_FROM_RECORDS_COUNT"),
first: this.$i18n.t("ID_FIRST"),
last: this.$i18n.t("ID_LAST"),
filter: this.$i18n.t("ID_FILTER") + ":",
limit: this.$i18n.t("ID_RECORDS") + ":",
page: this.$i18n.t("ID_PAGE") + ":",
noResults: this.$i18n.t("ID_NO_MATCHING_RECORDS")
noResults: this.$i18n.t("ID_NO_MATCHING_RECORDS"),
},
selectable: {
mode: "single",
@@ -157,35 +184,44 @@ export default {
selectAllMode: "page",
programmatic: false,
},
sortable: ["case_number"],
orderBy:
this.settings && this.settings.orderBy
? this.settings.orderBy
: {},
requestFunction(data) {
return this.$parent.$parent.getCasesForVueTable(data);
},
settings: {
"actions":{
actions: {
class: "fas fa-cog",
id:"pm-dr-column-settings",
events:{
click(){
that.$root.$emit('bv::show::popover', 'pm-dr-column-settings')
}
}
}
}
id: "pm-dr-column-settings",
events: {
click() {
that.$root.$emit(
"bv::show::popover",
"pm-dr-column-settings"
);
},
},
},
},
},
translations: null,
pmDateFormat: window.config.FORMATS.dateFormat,
clickCount: 0,
singleClickTimer: null,
statusTitle: {
"ON_TIME": this.$i18n.t("ID_IN_PROGRESS"),
"OVERDUE": this.$i18n.t("ID_TASK_OVERDUE"),
"DRAFT": this.$i18n.t("ID_IN_DRAFT"),
"PAUSED": this.$i18n.t("ID_PAUSED"),
"UNASSIGNED": this.$i18n.t("ID_UNASSIGNED")
}
ON_TIME: this.$i18n.t("ID_IN_PROGRESS"),
OVERDUE: this.$i18n.t("ID_TASK_OVERDUE"),
DRAFT: this.$i18n.t("ID_IN_DRAFT"),
PAUSED: this.$i18n.t("ID_PAUSED"),
UNASSIGNED: this.$i18n.t("ID_UNASSIGNED"),
},
};
},
mounted() {
let that = this;
this.getHeaders();
this.openDefaultCase();
// force to open start cases modal
@@ -193,8 +229,19 @@ export default {
if (window.config._nodeId === "CASES_START_CASE") {
this.$refs["newRequest"].show();
}
// define sort event
Event.$on("vue-tables.mycases.sorted", function(data) {
that.$emit("updateUserSettings", "orderBy", data);
});
},
watch: {
columns: function(val) {
this.$emit("updateUserSettings", "columns", val);
},
filters: function(val) {
this.$emit("updateUserSettings", "filters", val);
},
},
watch: {},
computed: {
/**
* Build our ProcessMaker apiClient
@@ -211,12 +258,12 @@ export default {
*/
openDefaultCase() {
let params;
if(this.defaultOption) {
if (this.defaultOption) {
params = utils.getAllUrlParams(this.defaultOption);
if (params && params.app_uid && params.del_index) {
this.openCase({
APP_UID: params.app_uid,
DEL_INDEX: params.del_index
DEL_INDEX: params.del_index,
});
this.$emit("cleanDefaultOption");
}
@@ -250,7 +297,7 @@ export default {
DEL_INDEX: item.DEL_INDEX,
PRO_UID: item.PRO_UID,
TAS_UID: item.TAS_UID,
ACTION: "todo"
ACTION: "todo",
});
this.$emit("onUpdatePage", "XCase");
},
@@ -262,14 +309,19 @@ export default {
openCaseDetail(item) {
let that = this;
api.cases.open(_.extend({ ACTION: "todo" }, item)).then(() => {
api.cases.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,
PRO_UID: item.PRO_UID,
TAS_UID: item.TAS_UID,
APP_NUMBER: item.CASE_NUMBER,
ACTION: that.filterHeader === "SUPERVISING" ? "to_revise": "todo"
ACTION:
that.filterHeader === "SUPERVISING"
? "to_revise"
: "todo",
});
that.$emit("onUpdatePage", "case-detail");
});
@@ -314,18 +366,22 @@ export default {
paged,
limit = data.limit,
start = data.page === 1 ? 0 : limit * (data.page - 1),
filters = {};
filters = {},
sort = "";
paged = start + "," + limit;
filters = {
filter: that.filterHeader,
paged: paged,
};
_.forIn(this.filters, function (item, key) {
if(filters && item.value) {
_.forIn(this.filters, function(item, key) {
if (filters && item.value) {
filters[item.filterVar] = item.value;
}
});
sort = that.prepareSortString(data);
if (sort) {
filters["sort"] = sort;
}
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases
.myCases(filters)
@@ -341,6 +397,20 @@ export default {
});
});
},
/**
* Prepare sort string to be sended in the service
* @param {object} data
* @returns {string}
*/
prepareSortString(data) {
let sort = "";
if (data.orderBy && this.columMap[data.orderBy]) {
sort = `${this.columMap[data.orderBy]},${
data.ascending === 1 ? "ASC" : "DESC"
}`;
}
return sort;
},
/**
* Format Response API TODO to grid inbox and columns
*/
@@ -355,13 +425,16 @@ export default {
STATUS: v.APP_STATUS,
START_DATE: v.APP_CREATE_DATE_LABEL || "",
FINISH_DATE: v.APP_FINISH_DATE_LABEL || "",
PENDING_TASKS: that.formantPendingTask(v.PENDING, v.APP_STATUS),
PENDING_TASKS: that.formantPendingTask(
v.PENDING,
v.APP_STATUS
),
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"
MESSAGE_COLOR: v.CASE_NOTES_COUNT > 0 ? "black" : "silver",
});
});
return data;
@@ -378,23 +451,31 @@ export default {
userName: data[i].user_tooltip.usr_username || "",
firstName: data[i].user_tooltip.usr_firstname || "",
lastName: data[i].user_tooltip.usr_lastname || "",
format: window.config.FORMATS.format || null
format: window.config.FORMATS.format || null,
});
dataFormat.push(
{
dataFormat.push({
TAS_NAME: data[i].tas_title,
STATUS: data[i].tas_color,
DELAYED_TITLE: this.delayedTitle(data[i], status),
DELAYED_MSG: data[i].tas_status === "OVERDUE" && status !== "COMPLETED" ? data[i].delay : "",
AVATAR: userDataFormat !== "" ? window.config.SYS_SERVER_AJAX +
DELAYED_MSG:
data[i].tas_status === "OVERDUE" &&
status !== "COMPLETED"
? data[i].delay
: "",
AVATAR:
userDataFormat !== ""
? window.config.SYS_SERVER_AJAX +
window.config.SYS_URI +
`users/users_ViewPhotoGrid?pUID=${data[i].user_id}` : "",
USERNAME: userDataFormat !== "" ? userDataFormat : this.$i18n.t("ID_UNASSIGNED"),
`users/users_ViewPhotoGrid?pUID=${data[i].user_id}`
: "",
USERNAME:
userDataFormat !== ""
? userDataFormat
: this.$i18n.t("ID_UNASSIGNED"),
POSITION: data[i].user_tooltip.usr_position,
EMAIL: data[i].user_tooltip.usr_email,
UNASSIGNED: userDataFormat !== "" ? true : false
}
);
UNASSIGNED: userDataFormat !== "" ? true : false,
});
}
return dataFormat;
},
@@ -408,10 +489,15 @@ export default {
let title = "";
if (status === "COMPLETED") {
title = this.$i18n.t("ID_COMPLETED") + ": ";
title += data.tas_status === "ON_TIME" ? this.$i18n.t("ID_ON_TIME"): this.$i18n.t("ID_TASK_OVERDUE");
title +=
data.tas_status === "ON_TIME"
? this.$i18n.t("ID_ON_TIME")
: this.$i18n.t("ID_TASK_OVERDUE");
} else {
title = data.tas_status === "OVERDUE" ?
this.$i18n.t("ID_DELAYED") + ":" : this.statusTitle[data.tas_status];
title =
data.tas_status === "OVERDUE"
? this.$i18n.t("ID_DELAYED") + ":"
: this.statusTitle[data.tas_status];
}
return title;
},
@@ -528,7 +614,7 @@ export default {
};
_.forEach(response, (v) => {
//Hack for display the SUPERVISING CARD
if(!(v.id === "SUPERVISING" && v.counter === 0)){
if (!(v.id === "SUPERVISING" && v.counter === 0)) {
data.push({
title: v.title,
counter: v.counter,
@@ -542,7 +628,7 @@ export default {
that.filterHeaderObject = obj;
that.random = _.random(0,1000000000);
},
class: info[v.id].class
class: info[v.id].class,
});
}
});
@@ -559,10 +645,9 @@ export default {
that.$refs["modal-comments"].show();
});
},
onRemoveFilter(data) {
},
onRemoveFilter(data) {},
onUpdateFilters(data) {
this.$emit("onUpdateFilters", data.params);
this.filters = data.params;
if (data.refresh) {
this.$nextTick(() => {
this.$refs["vueTable"].getData();

View File

@@ -23,6 +23,7 @@
ref="vueTable"
@row-click="onRowClick"
:key="random"
name="paused"
>
<div slot="detail" slot-scope="props">
<div class="btn-default" @click="openCaseDetail(props.row)">
@@ -226,6 +227,7 @@ import VueListView from "../../components/dataViews/vueListView/VueListView.vue"
import defaultMixins from "./defaultMixins";
import Ellipsis from '../../components/utils/ellipsis.vue';
import ModalReassignCase from '../modal/ModalReassignCase.vue';
import { Event } from 'vue-tables-2';
import CurrentUserCell from "../../components/vuetable/CurrentUserCell.vue";
export default {
@@ -245,10 +247,15 @@ export default {
ModalReassignCase,
CurrentUserCell,
},
props: ["defaultOption", "filters"],
props: ["defaultOption", "settings"],
data() {
let that = this;
return {
columMap: {
case_number: "APP_NUMBER",
case_title: "DEL_TITLE",
process_name: "PRO_TITLE"
},
newCase: {
title: this.$i18n.t("ID_NEW_CASE"),
class: "btn-success",
@@ -256,7 +263,14 @@ export default {
this.$refs["newRequest"].show();
},
},
columns: [
filters:
this.settings && this.settings.filters
? this.settings.filters
: {},
columns:
this.settings && this.settings.columns
? this.settings.columns
: [
"detail",
"case_number",
"case_title",
@@ -266,7 +280,7 @@ export default {
"due_date",
"delegation_date",
"priority",
"actions",
"actions"
],
tableData: [],
icon:"far fa-pause-circle",
@@ -301,6 +315,8 @@ export default {
selectAllMode: "page",
programmatic: false,
},
sortable: ['case_number'],
orderBy: this.settings && this.settings.orderBy ? this.settings.orderBy: {},
requestFunction(data) {
return this.$parent.$parent.getCasesForVueTable(data);
},
@@ -337,10 +353,21 @@ export default {
this.initFilters();
},
mounted() {
let that = this;
// force to open case
this.openDefaultCase();
Event.$on('vue-tables.paused.sorted', function (data) {
that.$emit("updateUserSettings", "orderBy", data);
});
},
watch: {
columns: function (val) {
this.$emit("updateUserSettings", "columns", val);
},
filters: function (val) {
this.$emit("updateUserSettings", "filters", val);
},
},
watch: {},
computed: {
/**
* Build our ProcessMaker apiClient
@@ -432,7 +459,8 @@ export default {
paged,
limit = data.limit,
start = data.page === 1 ? 0 : limit * (data.page - 1),
filters = {};
filters = {},
sort = "";
paged = start + "," + limit;
filters = {
@@ -444,6 +472,10 @@ export default {
filters[item.filterVar] = item.value;
}
});
sort = that.prepareSortString(data);
if (sort) {
filters["sort"] = sort;
}
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases
.paused(filters)
@@ -459,6 +491,18 @@ export default {
});
});
},
/**
* Prepare sort string to be sended in the service
* @param {object} data
* @returns {string}
*/
prepareSortString(data){
let sort = "";
if (data.orderBy && this.columMap[data.orderBy]) {
sort = `${this.columMap[data.orderBy]},${data.ascending === 1 ? "ASC": "DESC"}`;
}
return sort;
},
/**
* Format Response API TODO to grid todo and columns
*/
@@ -560,7 +604,7 @@ export default {
},
onRemoveFilter(data) {},
onUpdateFilters(data) {
this.$emit("onUpdateFilters", data.params);
this.filters = data.params;
if (data.refresh) {
this.$nextTick(() => {
if (this.typeView === "GRID") {

View File

@@ -86,7 +86,7 @@ export default {
};
_.forIn(this.filters, function (item, key) {
if (item.value && item.value != "") {
if(filters && item.value) {
filters[item.filterVar] = item.value;
}
});

View File

@@ -8,7 +8,7 @@
<h6 class="v-search-title">Drill Down Navigator</h6>
</div>
<div
v-for="item in loadItems(data, index)"
v-for="item in loadItems(data, level)"
:key="item.content"
class="vp-padding-b10"
>
@@ -16,9 +16,7 @@
{{ item.label }}
</span>
<div class="vp-inline-block">
<span :class="item.classObject" @click="onClick(item)">
{{ item.content }}</span
>
<span :class="item.classObject"> {{ item.content }}</span>
</div>
</div>
</div>
@@ -30,11 +28,10 @@ export default {
name: "DrillDown",
mixins: [],
components: {},
props: [],
props: ["level"],
data() {
let that = this;
return {
index: 0,
classObject: {
"rounded-circle": true,
"v-pm-drill-down-number": true,
@@ -43,6 +40,11 @@ export default {
"vp-block": true,
},
data: [
{
label: "Level",
content: "0",
click() {},
},
{
label: "Level",
content: "1",
@@ -58,11 +60,6 @@ export default {
content: "3",
click() {},
},
{
label: "Level",
content: "4",
click() {},
},
],
};
},
@@ -147,5 +144,6 @@ export default {
.v-pm-drill-down {
vertical-align: top;
padding-left: 50px;
}
</style>

View File

@@ -0,0 +1,183 @@
<template>
<div class="pm-all-view-popover">
<b-popover
:target="target"
ref="popover"
triggers="click"
placement="bottom"
@show="onshow"
>
<template #title>{{ $t("ID_PROCESSES").toUpperCase() }}</template>
<div>
<div class="input-group input-group-sm mb-3">
<span class="input-group-text" id="inputGroup-sizing-sm"
><i class="fas fa-search"></i
></span>
<input
type="text"
class="form-control"
aria-describedby="inputGroup-sizing-sm"
@keyup="search"
v-model="text"
/>
</div>
<div class="form-check border-bottom">
<input
class="form-check-input"
type="checkbox"
v-model="allColumns"
@change="toogleAllColumns"
/>
<label class="form-check-label" for="flexCheckDefault">
{{ $t("ID_ALL") }}
</label>
</div>
<b-form-group>
<b-form-checkbox-group
v-model="localSelected"
:options="results"
value-field="key"
text-field="value"
name="flavour-2a"
@change="changeOptions"
stacked
></b-form-checkbox-group>
</b-form-group>
<div class="v-popover-footer">
<div class="float-right">
<b-button @click="onClose" size="sm" variant="danger">
{{ $t("ID_CANCEL") }}</b-button
>
<b-button @click="onSave" size="sm" variant="success">{{
$t("ID_SAVE")
}}</b-button>
</div>
</div>
</div>
</b-popover>
</div>
</template>
<script>
export default {
name: "ProcessPopover",
props: ["target"],
data() {
return {
options: [],
text: "",
results: [],
allColumns: false,
localSelected: [],
selected: [],
};
},
mounted() {
this.results = this.options;
this.localSelected = this.selected;
},
methods: {
/**
* Set options
*/
setOptions(options) {
this.options = options;
this.results = options;
},
/**
* Set selected options
*/
setSelectedOptions(options) {
console.log("SELECTED");
this.selected = options;
this.localSelected = options;
},
/**
* Close buton click handler
*/
onClose() {
this.$refs.popover.$emit("close");
this.$emit("closePopover");
},
/**
* Save button click handler
*/
onSave() {
let sels;
sels = _.clone(this.localSelected);
this.$root.$emit("bv::hide::popover");
this.$emit("onUpdateColumnSettings", sels);
},
/**
* Show popover event handler
*/
onshow() {
this.$root.$emit("bv::hide::popover");
},
/**
* Search in the column name
*/
search() {
let txt = this.text.toLowerCase(),
val,
opts = [];
opts = _.filter(this.options, function (o) {
val = o.value.toLowerCase();
return val.search(txt) != -1;
});
this.results = opts;
},
/**
* Toogle all options in popover
*/
toogleAllColumns() {
let res = [];
if (this.allColumns) {
_.each(this.options, function (o) {
res.push(o.key);
});
}
this.selected = res;
},
/**
* Handler when change options event
*/
changeOptions() {
let that = this,
res = [];
_.each(this.options, function (o) {
if (
_.findIndex(that.localSelected, function (v) {
return v === o.key;
}) != -1
) {
res.push(o.key);
}
});
this.localSelected = res;
},
},
};
</script>
<style scoped>
.pm-all-view-popover .popover {
max-width: 350px !important;
min-width: 200px !important;
}
.v-popover-footer {
display: flow-root;
}
</style>

View File

@@ -2,13 +2,16 @@
<div id="v-pm-task-metrics" ref="v-pm-task-metrics" class="v-pm-task-metrics">
<button-fleft :data="newCase"></button-fleft>
<div class="p-1 v-flex">
<h5 class="v-search-title">Task metrics</h5>
<h4 class="v-search-title">
Task metrics
<span class="vp-padding-r3"> <i class="fas fa-chart-pie"></i></span>
</h4>
</div>
<modal-new-request ref="newRequest"></modal-new-request>
<div class="d-inline-flex p-2">
<vue-charts />
<vue-charts @onChangeLevel="changeLevel" />
<div class="vp-6"></div>
<drill-down />
<drill-down :level="level" />
</div>
</div>
</template>
@@ -32,7 +35,9 @@ export default {
props: [],
data() {
let that = this;
return {};
return {
level: 0,
};
},
created() {},
mounted() {},
@@ -40,7 +45,11 @@ export default {
computed: {},
updated() {},
beforeCreate() {},
methods: {},
methods: {
changeLevel(lv) {
this.level = lv;
},
},
};
</script>
<style>
@@ -51,7 +60,7 @@ export default {
padding-right: 50px;
}
.vp-6 {
padding: 3.5rem !important;
.vp-padding-r3 {
padding-right: 3rem;
}
</style>

View File

@@ -1,9 +1,15 @@
<template>
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
<div class="p-1 v-flex">
<h6 class="v-search-title">Number of tasks per Task Status</h6>
<h6 class="v-search-title">Number of Tasks Status per Process</h6>
<div>
<label class="vp-inline-block">{{ $t("ID_PROCESS_CATEGORY") }}</label>
<BreadCrumb :options="dataBreadCrumbs(data)" />
<ProcessPopover
:options="optionsProcesses"
target="pm-task-process"
ref="pm-task-process"
@onUpdateColumnSettings="onUpdateColumnSettings"
/>
<div class="vp-width-p40 vp-inline-block">
<multiselect
v-model="category"
@@ -11,12 +17,30 @@
:searchable="false"
:close-on-select="false"
:show-labels="false"
placeholder="Pick a value"
track-by="id"
label="name"
@select="changeOption"
></multiselect>
</div>
<label class="vp-inline-block vp-padding-l20">{{
$t("ID_MAFE_a4ffdcf0dc1f31b9acaf295d75b51d00")
}}</label>
<div class="vp-inline-block">
<b-form-checkbox v-model="top" name="check-button" switch>
</b-form-checkbox>
</div>
<div class="vp-inline-block vp-right vp-padding-r40">
<h4
class="v-search-title"
@click="showProcessesPopover"
id="pm-task-process"
>
<i class="fas fa-cog"></i>
</h4>
</div>
</div>
<apexchart
ref="apexchart1"
ref="LevelOneChart"
:width="width"
:options="optionsBar"
:series="seriesBar"
@@ -28,6 +52,8 @@
<script>
import _ from "lodash";
import Api from "../../api/index";
import BreadCrumb from "../../components/utils/BreadCrumb.vue";
import ProcessPopover from "./ProcessPopover.vue";
import Multiselect from "vue-multiselect";
export default {
@@ -35,29 +61,45 @@ export default {
mixins: [],
components: {
Multiselect,
BreadCrumb,
ProcessPopover,
},
props: [],
props: ["data"],
data() {
let that = this;
return {
category: null,
dataProcesses: null, //Data API processes
optionsCategory: [],
optionsProcesses: [],
selectedProcesses: [],
top: false,
width: 0,
totalCases: [],
currentSelection: null,
seriesBar: [
{
data: [400, 430, 448, 470],
data: [],
},
],
optionsBar: {
chart: {
type: "bar",
id: "apexchart2",
id: "LevelOneChart",
toolbar: {
show: false,
},
events: {
legendClick: function (chartContext, seriesIndex, config) {
console.log("click");
that.currentSelection = that.totalCases[seriesIndex];
console.log("LEGENDDDDDDDDDDDDD");
that.$emit("updateDataLevel", {
id: that.currentSelection["PRO_ID"],
name: that.currentSelection["PRO_TITLE"],
level: 1,
data: that.currentSelection,
});
},
},
},
@@ -70,20 +112,13 @@ export default {
},
legend: {
position: "left",
offsetY: 50,
fontSize: "18px",
},
colors: ["#33b2df", "#546E7A", "#d4526e", "#13d8aa"],
dataLabels: {
enabled: false,
},
xaxis: {
categories: [
this.$i18n.t("ID_INBOX"),
this.$i18n.t("ID_DRAFT"),
this.$i18n.t("ID_PAUSED"),
this.$i18n.t("ID_UNASSIGNED"),
],
categories: [],
},
tooltip: {
x: {
@@ -104,8 +139,7 @@ export default {
mounted() {
this.getBodyHeight();
this.getCategories();
//this.getDataDonut();
//this.getData();
this.getProcesses();
},
watch: {},
computed: {},
@@ -116,72 +150,15 @@ export default {
* Return the height for Vue Card View body
*/
getBodyHeight() {
this.width = window.innerHeight * 0.8;
this.width = window.innerHeight;
},
/**
* Change view - donut/bar
* Get Categories form API
*/
changeView(view) {
this.typeView = view;
this.getData();
},
/**
* Get data from rest API
*/
getData() {
let that = this;
Api.cases
.listTotalCases()
.then((response) => {
that.formatData(response.data);
})
.catch((response) => {});
},
/**
* Format the data for chart
*/
formatData(data) {
let l = [],
c = [],
s = [];
_.each(data, (el) => {
l.push(el["List Name"]);
s.push(el["Total"]);
if (el["Color"] == "green") {
c.push("#179a6e");
}
if (el["Color"] == "yellow") {
c.push("#feb019");
}
if (el["Color"] == "blue") {
c.push("#008ffb");
}
if (el["Color"] == "gray") {
c.push("#8f99a0");
}
});
this.seriesDonut = s;
this.seriesBar = [
{
data: s,
},
];
this.$refs["apexchart1"].updateOptions({ labels: l, colors: c });
this.$refs["apexchart2"].updateOptions({ labels: l, colors: c });
this.$apexcharts.exec("apexchart1", "updateSeries", s);
this.$apexcharts.exec("apexchart2", "updateSeries", [
{
data: s,
},
]);
},
getCategories() {
let that = this;
console.log("jonas");
Api.process
.categories({
name:""
})
Api.filters
.categories()
.then((response) => {
that.formatDataCategories(response.data);
})
@@ -189,14 +166,157 @@ export default {
console.error(err);
});
},
/**
* Get Processes form API
*/
getProcesses() {
let that = this;
Api.filters
.processList("")
.then((response) => {
that.formatDataProcesses(response.data);
that.changeOption({
id: 0,
});
})
.catch((e) => {
console.error(err);
});
},
/**
* Format categories for multiselect
*/
formatDataCategories(data) {
let array = [];
array.push({
name: "No Categories",
id: "0",
});
_.each(data, (el) => {
array.push(el["cat_name"]);
array.push({ name: el["CATEGORY_NAME"], id: el["CATEGORY_ID"] });
});
this.optionsCategory = array;
this.category = array[0];
},
/**
* Format processes for popover
*/
formatDataProcesses(data) {
let sels = [],
labels = [],
array = [];
_.each(data, (el) => {
array.push({ value: el["PRO_TITLE"], key: el["PRO_ID"] });
sels.push(el["PRO_ID"]);
labels;
});
this.optionsProcesses = array;
this.selectedProcesses = sels;
//Update the labels
this.dataProcesses = data;
this.updateLabels(data);
console.log("aaaaaaaaaaaaaaaaa aaaaaaa");
},
/**
* Change the options in TOTAL CASES BY PROCESS
*/
changeOption(option) {
let that = this,
dt = {};
if (this.data.length > 0) {
dt = {
category: option.id,
caseList: this.data[0].id.toLowerCase(),
processes: this.selectedProcesses,
};
Api.process
.totalCasesByProcess(dt)
.then((response) => {
that.totalCases = response.data;
that.formatTotalCases(response.data);
})
.catch((e) => {
console.error(err);
});
}
},
/**
* Show the processes popover
*/
showProcessesPopover() {
this.$root.$emit("bv::show::popover", "pm-task-process");
this.$refs["pm-task-process"].setOptions(this.optionsProcesses);
this.$refs["pm-task-process"].setSelectedOptions(this.selectedProcesses);
},
formatTotalCases(data) {
let serie = [],
labels = [];
_.each(data, (el) => {
serie.push(el["TOTAL"]);
labels.push(el["PRO_TITLE"]);
});
this.$refs["LevelOneChart"].updateOptions({ labels: labels });
this.$apexcharts.exec("LevelOneChart", "updateSeries", [
{
data: serie,
},
]);
},
dataBreadCrumbs(options) {
let res = [],
that = this;
res.push({
label: "Start",
onClick() {
console.log("STARTTTTTTTTTT");
that.$emit("onChangeLevel", 0);
},
});
_.each(options, (el) => {
res.push({
label: el.id,
onClick() {
that.$emit("onChangeLevel", el.level);
},
});
});
return res;
},
/**
* Update list processes in chart
*/
onUpdateColumnSettings(data) {
let res;
this.selectedProcesses = data;
res = _.intersectionBy(this.totalCases, data, (el) => {
if (_.isNumber(el)) {
return el;
}
if (_.isObject(el) && el["PRO_ID"]) {
return el["PRO_ID"];
}
});
this.formatTotalCases(res);
},
updateLabels(processes) {
let labels = [];
_.each(processes, (el) => {
labels.push(el["PRO_TITLE"]);
});
this.$refs["LevelOneChart"].updateOptions({ labels: labels });
},
updateSerie(processes) {
let labels = [];
_.each(processes, (el) => {
labels.push(el["TOTAL"]);
});
this.$refs["LevelOneChart"].updateOptions({ labels: labels });
},
},
};
</script>
@@ -212,5 +332,17 @@ export default {
.vp-inline-block {
display: inline-block;
}
.vp-padding-l20 {
padding-left: 20px;
}
.vp-padding-r40 {
padding-right: 40px;
}
.vp-right {
float: right;
}
</style>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>

View File

@@ -0,0 +1,315 @@
<template>
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
<div class="p-1 v-flex">
<h6 class="v-search-title">Number of Tasks Status per Process</h6>
<div>
<BreadCrumb :options="dataBreadCrumbs(data)" />
<div class="vp-width-p30 vp-inline-block">
<b-form-datepicker id="date-from" size="sm"></b-form-datepicker>
</div>
<div class="vp-width-p30 vp-inline-block">
<b-form-datepicker id="date-to" size="sm"></b-form-datepicker>
</div>
<div class="vp-inline-block">
<b-button-group size="sm">
<b-button variant="outline-secondary">{{ $t("ID_DAY") }}</b-button>
<b-button variant="outline-secondary">{{
$t("ID_MONTH")
}}</b-button>
<b-button variant="outline-secondary">{{ $t("ID_YEAR") }}</b-button>
</b-button-group>
</div>
</div>
<apexchart
ref="apexchart1"
:width="width"
:options="options"
:series="series"
></apexchart>
</div>
</div>
</template>
<script>
import _ from "lodash";
import Api from "../../api/index";
import Multiselect from "vue-multiselect";
import BreadCrumb from "../../components/utils/BreadCrumb.vue";
export default {
name: "VueChartLvOne",
mixins: [],
components: {
Multiselect,
BreadCrumb,
},
props: ["data"],
data() {
let that = this;
return {
category: null,
optionsCategory: [],
top: false,
width: 0,
series: [
{
name: "TEAM 1",
data: this.generateDayWiseTimeSeries(
new Date("11/02/2017").getTime(),
20,
{
min: 10,
max: 60,
}
),
},
{
name: "TEAM 2",
data: this.generateDayWiseTimeSeries(
new Date("11 Feb 2017 GMT").getTime(),
20,
{
min: 10,
max: 60,
}
),
},
{
name: "TEAM 3",
data: this.generateDayWiseTimeSeries(
new Date("11 Feb 2017 GMT").getTime(),
30,
{
min: 10,
max: 60,
}
),
},
{
name: "TEAM 4",
data: this.generateDayWiseTimeSeries(
new Date("11 Feb 2017 GMT").getTime(),
10,
{
min: 10,
max: 60,
}
),
},
{
name: "TEAM 5",
data: this.generateDayWiseTimeSeries(
new Date("11 Feb 2017 GMT").getTime(),
30,
{
min: 10,
max: 60,
}
),
},
],
options: {
chart: {
height: 350,
type: "scatter",
zoom: {
type: "xy",
},
},
dataLabels: {
enabled: false,
},
grid: {
xaxis: {
lines: {
show: true,
},
},
yaxis: {
lines: {
show: true,
},
},
},
xaxis: {
type: "datetime",
},
yaxis: {
max: 70,
},
},
};
},
created() {},
mounted() {
this.getBodyHeight();
this.getCategories();
//this.getDataDonut();
//this.getData();
},
watch: {},
computed: {},
updated() {},
beforeCreate() {},
methods: {
/**
* Return the height for Vue Card View body
*/
getBodyHeight() {
this.width = window.innerHeight;
},
/**
* Change view - donut/bar
*/
changeView(view) {
this.typeView = view;
this.getData();
},
/**
* Get data from rest API
*/
getData() {
let that = this;
Api.cases
.listTotalCases()
.then((response) => {
that.formatData(response.data);
})
.catch((response) => {});
},
/**
* Format the data for chart
*/
formatData(data) {
let l = [],
c = [],
s = [];
_.each(data, (el) => {
l.push(el["List Name"]);
s.push(el["Total"]);
if (el["Color"] == "green") {
c.push("#179a6e");
}
if (el["Color"] == "yellow") {
c.push("#feb019");
}
if (el["Color"] == "blue") {
c.push("#008ffb");
}
if (el["Color"] == "gray") {
c.push("#8f99a0");
}
});
this.seriesDonut = s;
this.seriesBar = [
{
data: s,
},
];
this.$refs["apexchart1"].updateOptions({ labels: l, colors: c });
this.$refs["apexchart2"].updateOptions({ labels: l, colors: c });
this.$apexcharts.exec("apexchart1", "updateSeries", s);
this.$apexcharts.exec("apexchart2", "updateSeries", [
{
data: s,
},
]);
},
getCategories() {
let that = this;
console.log("jonas");
Api.filters
.categories()
.then((response) => {
that.formatDataCategories(response.data);
})
.catch((e) => {
console.error(err);
});
},
formatDataCategories(data) {
let array = [];
_.each(data, (el) => {
array.push({ name: el["CATEGORY_NAME"], id: el["CATEGORY_ID"] });
});
this.optionsCategory = array;
this.category = array[0];
},
changeOption(option) {
console.log("asda sdas d");
let dt = {
category: option.id,
caseList:
this.data && this.data.dataLv0
? this.data.dataLv0["List Name"].toLowerCase()
: "inbox",
};
Api.process
.processTotalCases(dt)
.then((response) => {
console.log("asda sdas d11111111111111");
console.log(response);
})
.catch((e) => {
console.error(err);
});
},
dataBreadCrumbs(options) {
let res = [],
that = this;
res.push({
label: "Start",
onClick() {
console.log("STARTTTTTTTTTT");
that.$emit("onChangeLevel", 0);
},
});
_.each(options, (el) => {
res.push({
label: el.name,
onClick() {
that.$emit("onChangeLevel", el.level);
},
});
});
return res;
},
generateDayWiseTimeSeries(baseval, count, yrange) {
var i = 0;
var series = [];
while (i < count) {
var y =
Math.floor(Math.random() * (yrange.max - yrange.min + 1)) +
yrange.min;
series.push([baseval, y]);
baseval += 86400000;
i++;
}
console.log(series);
return series;
},
},
};
</script>
<style>
.vp-task-metrics-label {
display: inline-block;
}
.vp-width-p30 {
width: 30%;
}
.vp-inline-block {
display: inline-block;
}
.vp-padding-l20 {
padding-left: 20px;
}
</style>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>

View File

@@ -18,14 +18,14 @@
></apexchart>
<div class="row">
<div class="col-sm vp-center">
<div class="col-sm vp-align-right">
<button
@click="changeView('donut')"
type="button"
class="btn btn-primary"
>
<i class="fas fa-chart-pie"></i
><span class="vp-padding-l10">View</span>
><span class="vp-padding-l10">{{ $t("ID_VIEW") }}</span>
</button>
</div>
<div class="col-sm">
@@ -35,7 +35,7 @@
class="btn btn-primary"
>
<i class="fas fa-chart-bar"></i
><span class="vp-padding-l10">View</span>
><span class="vp-padding-l10">{{ $t("ID_VIEW") }}</span>
</button>
</div>
</div>
@@ -54,8 +54,10 @@ export default {
data() {
let that = this;
return {
typeView: "bar",
typeView: "donut",
width: 0,
data: [],
currentSelection: null,
seriesDonut: [],
optionsDonut: {
labels: [
@@ -67,6 +69,17 @@ export default {
chart: {
id: "apexchart1",
type: "donut",
events: {
legendClick: function (chartContext, seriesIndex, config) {
that.currentSelection = that.data[seriesIndex];
that.$emit("updateDataLevel", {
id: that.currentSelection["List Name"],
name: that.currentSelection["List Name"],
level: 0,
data: that.currentSelection,
});
},
},
},
legend: {
position: "top",
@@ -85,6 +98,17 @@ export default {
toolbar: {
show: false,
},
events: {
legendClick: function (chartContext, seriesIndex, config) {
that.currentSelection = that.data[seriesIndex];
that.$emit("updateDataLevel", {
id: that.currentSelection["List Name"],
name: that.currentSelection["List Name"],
level: 0,
data: that.currentSelection,
});
},
},
},
plotOptions: {
bar: {
@@ -126,7 +150,6 @@ export default {
created() {},
mounted() {
this.getBodyHeight();
//this.getDataDonut();
this.getData();
},
watch: {},
@@ -138,7 +161,7 @@ export default {
* Return the height for Vue Card View body
*/
getBodyHeight() {
this.width = window.innerHeight * 0.8;
this.width = window.innerHeight * 0.9;
},
/**
* Change view - donut/bar
@@ -182,6 +205,7 @@ export default {
c.push("#8f99a0");
}
});
this.data = data;
this.seriesDonut = s;
this.seriesBar = [
{
@@ -205,6 +229,10 @@ export default {
text-align: center;
}
.vp-align-right {
text-align: right;
}
.vp-padding-l10 {
padding-left: 10px;
}

View File

@@ -1,16 +1,27 @@
<template>
<div
id="v-pm-charts"
ref="v-pm-charts"
class="v-pm-charts vp-inline-block"
>
<vue-chart-lv-one/>
<div id="v-pm-charts" ref="v-pm-charts" class="v-pm-charts vp-inline-block">
<vue-chart-lv-zero
v-show="level === 0"
@updateDataLevel="updateDataLevel"
/>
<vue-chart-lv-one
v-if="level === 1"
:data="data"
@onChangeLevel="onChangeLevel"
@updateDataLevel="updateDataLevel"
/>
<vue-chart-lv-two
v-if="level === 2"
:data="data"
@onChangeLevel="onChangeLevel"
/>
</div>
</template>
<script>
import VueChartLvZero from "./VueChartLvZero.vue";
import VueChartLvOne from "./VueChartLvOne.vue";
import VueChartLvTwo from "./VueChartLvTwo.vue";
export default {
name: "VueCharts",
@@ -18,12 +29,15 @@ export default {
components: {
VueChartLvZero,
VueChartLvOne,
VueChartLvTwo,
},
props: [],
data() {
let that = this;
return {
width: 0,
level: 0,
data: [],
dataBreadCrumbs: [],
};
},
created() {},
@@ -32,7 +46,31 @@ export default {
computed: {},
updated() {},
beforeCreate() {},
methods: {},
methods: {
/**
* Set data level 0
*/
updateDataLevel(data) {
this.data.push(data);
this.level = data.level + 1;
this.$emit("onChangeLevel", this.level);
},
/**
* Format data to vue charts any level
*/
formatData() {
return {
level: this.level,
data: this.data,
};
},
onChangeLevel(lv) {
console.log("leveeeeeeeeeeeeeee");
this.level = lv;
this.$emit("onChangeLevel", this.level);
},
},
};
</script>
<style>

View File

@@ -21,6 +21,7 @@
ref="vueTable"
@row-click="onRowClick"
:key="random"
name="unassigned"
>
<div slot="detail" slot-scope="props">
<div class="btn-default" @click="openCaseDetail(props.row)">
@@ -222,6 +223,7 @@ import VueCardView from "../../components/dataViews/vueCardView/VueCardView.vue"
import VueListView from "../../components/dataViews/vueListView/VueListView.vue";
import defaultMixins from "./defaultMixins";
import ModalPauseCase from '../modal/ModalPauseCase.vue';
import { Event } from 'vue-tables-2';
import CurrentUserCell from "../../components/vuetable/CurrentUserCell.vue";
export default {
@@ -241,10 +243,15 @@ export default {
ModalPauseCase,
CurrentUserCell,
},
props: ["defaultOption", "filters"],
props: ["defaultOption", "settings"],
data() {
let that = this;
return {
columMap: {
case_number: "APP_NUMBER",
case_title: "DEL_TITLE",
process_name: "PRO_TITLE"
},
newCase: {
title: this.$i18n.t("ID_NEW_CASE"),
class: "btn-success",
@@ -252,7 +259,14 @@ export default {
this.$refs["newRequest"].show();
},
},
columns: [
filters:
this.settings && this.settings.filters
? this.settings.filters
: {},
columns:
this.settings && this.settings.columns
? this.settings.columns
: [
"detail",
"case_number",
"case_title",
@@ -262,7 +276,7 @@ export default {
"due_date",
"delegation_date",
"priority",
"actions",
"actions"
],
icon:"fas fa-users",
options: {
@@ -296,6 +310,8 @@ export default {
selectAllMode: "page",
programmatic: false,
},
sortable: ['case_number'],
orderBy: this.settings && this.settings.orderBy ? this.settings.orderBy: {},
requestFunction(data) {
return this.$parent.$parent.getCasesForVueTable(data);
},
@@ -329,9 +345,21 @@ export default {
};
},
mounted() {
let that = this;
this.initFilters();
// define sort event
Event.$on('vue-tables.unassigned.sorted', function (data) {
that.$emit("updateUserSettings", "orderBy", data);
});
},
watch: {
columns: function (val) {
this.$emit("updateUserSettings", "columns", val);
},
filters: function (val) {
this.$emit("updateUserSettings", "filters", val);
},
},
watch: {},
computed: {
/**
* Build our ProcessMaker apiClient
@@ -397,7 +425,8 @@ export default {
paged,
limit = data.limit,
start = data.page === 1 ? 0 : limit * (data.page - 1),
filters = {};
filters = {},
sort = "";
paged = start + "," + limit;
filters = {
@@ -409,6 +438,10 @@ export default {
filters[item.filterVar] = item.value;
}
});
sort = that.prepareSortString(data);
if (sort) {
filters["sort"] = sort;
}
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases
.unassigned(filters)
@@ -424,6 +457,18 @@ export default {
});
});
},
/**
* Prepare sort string to be sended in the service
* @param {object} data
* @returns {string}
*/
prepareSortString(data){
let sort = "";
if (data.orderBy && this.columMap[data.orderBy]) {
sort = `${this.columMap[data.orderBy]},${data.ascending === 1 ? "ASC": "DESC"}`;
}
return sort;
},
/**
* Format Response API TODO to grid todo and columns
*/
@@ -530,7 +575,7 @@ export default {
onRemoveFilter(data) {},
onUpdateFilters(data) {
if (data.params) {
this.$emit("onUpdateFilters", data.params);
this.filters = data.params;
}
if (data.refresh) {
this.$nextTick(() => {

View File

@@ -86,7 +86,9 @@ export default {
};
_.forIn(this.filters, function (item, key) {
if(filters && item.value) {
filters[item.filterVar] = item.value;
}
});
return new Promise((resolutionFunc, rejectionFunc) => {
api.cases

View File

@@ -5,6 +5,7 @@ import VueI18n from 'vue-i18n';
import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue';
import { ServerTable, Event, ClientTable } from 'vue-tables-2';
import VtTableHeadingCustom from './../components/vuetable/extends/VtTableHeadingCustom';
import VtSortControl from './../components/vuetable/extends/VtSortControl';
import SettingsPopover from "../components/vuetable/SettingsPopover.vue";
import Sortable from 'sortablejs';
import "@fortawesome/fontawesome-free/css/all.css";
@@ -13,6 +14,10 @@ import 'bootstrap/dist/css/bootstrap-grid.css';
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap-vue/dist/bootstrap-vue.css';
import VueApexCharts from 'vue-apexcharts'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import Home from "./Home";
Vue.use(VueApexCharts);
@@ -21,9 +26,11 @@ Vue.use(VueSidebarMenu);
Vue.use(BootstrapVue);
Vue.use(BootstrapVueIcons);
Vue.use(VueI18n);
Vue.component('font-awesome-icon', FontAwesomeIcon);
Vue.use(ServerTable, {}, false, 'bootstrap3', {
tableHeading: VtTableHeadingCustom
tableHeading: VtTableHeadingCustom,
sortControl: VtSortControl
});
Vue.use(ClientTable, {}, false, 'bootstrap3', {});
Vue.component('settings-popover', SettingsPopover);

View File

@@ -89,5 +89,359 @@ export default {
}
return obj;
},
getData() {
return [{
code: "ZW",
name: "Zimbabwe",
created_at: "2015-04-24T01:46:50.459583",
updated_at: "2015-04-24T01:46:50.459593",
uri: "http://api.lobbyfacts.eu/api/1/country/245",
id: 245
}, {
code: "ZM",
name: "Zambia",
created_at: "2015-04-24T01:46:50.457459",
updated_at: "2015-04-24T01:46:50.457468",
uri: "http://api.lobbyfacts.eu/api/1/country/244",
id: 244
}, {
code: "YE",
name: "Yemen",
created_at: "2015-04-24T01:46:50.454731",
updated_at: "2015-04-24T01:46:50.454741",
uri: "http://api.lobbyfacts.eu/api/1/country/243",
id: 243
}, {
code: "EH",
name: "Western Sahara",
created_at: "2015-04-24T01:46:50.452002",
updated_at: "2015-04-24T01:46:50.452011",
uri: "http://api.lobbyfacts.eu/api/1/country/242",
id: 242
}, {
code: "WF",
name: "Wallis & Futuna",
created_at: "2015-04-24T01:46:50.449346",
updated_at: "2015-04-24T01:46:50.449355",
uri: "http://api.lobbyfacts.eu/api/1/country/241",
id: 241
}, {
code: "VN",
name: "Vietnam",
created_at: "2015-04-24T01:46:50.446644",
updated_at: "2015-04-24T01:46:50.446652",
uri: "http://api.lobbyfacts.eu/api/1/country/240",
id: 240
}, {
code: "VE",
name: "Venezuela",
created_at: "2015-04-24T01:46:50.444031",
updated_at: "2015-04-24T01:46:50.444040",
uri: "http://api.lobbyfacts.eu/api/1/country/239",
id: 239
}, {
code: "VU",
name: "Vanuatu",
created_at: "2015-04-24T01:46:50.441423",
updated_at: "2015-04-24T01:46:50.441433",
uri: "http://api.lobbyfacts.eu/api/1/country/238",
id: 238
}, {
code: "UZ",
name: "Uzbekistan",
created_at: "2015-04-24T01:46:50.438748",
updated_at: "2015-04-24T01:46:50.438757",
uri: "http://api.lobbyfacts.eu/api/1/country/237",
id: 237
}, {
code: "UY",
name: "Uruguay",
created_at: "2015-04-24T01:46:50.435761",
updated_at: "2015-04-24T01:46:50.435770",
uri: "http://api.lobbyfacts.eu/api/1/country/236",
id: 236
}, {
code: "VI",
name: "United States Virgin Islands",
created_at: "2015-04-24T01:46:50.433229",
updated_at: "2015-04-24T01:46:50.433238",
uri: "http://api.lobbyfacts.eu/api/1/country/235",
id: 235
}, {
code: "US",
name: "United States",
created_at: "2015-04-24T01:46:50.430335",
updated_at: "2015-04-24T01:46:50.430340",
uri: "http://api.lobbyfacts.eu/api/1/country/234",
id: 234
}, {
code: "GB",
name: "United Kingdom",
created_at: "2015-04-24T01:46:50.427956",
updated_at: "2015-04-24T01:46:50.427961",
uri: "http://api.lobbyfacts.eu/api/1/country/233",
id: 233
}, {
code: "AE",
name: "United Arab Emirates",
created_at: "2015-04-24T01:46:50.425383",
updated_at: "2015-04-24T01:46:50.425392",
uri: "http://api.lobbyfacts.eu/api/1/country/232",
id: 232
}, {
code: "UA",
name: "Ukraine",
created_at: "2015-04-24T01:46:50.422970",
updated_at: "2015-04-24T01:46:50.422980",
uri: "http://api.lobbyfacts.eu/api/1/country/231",
id: 231
}, {
code: "UG",
name: "Uganda",
created_at: "2015-04-24T01:46:50.419963",
updated_at: "2015-04-24T01:46:50.419968",
uri: "http://api.lobbyfacts.eu/api/1/country/230",
id: 230
}, {
code: "TV",
name: "Tuvalu",
created_at: "2015-04-24T01:46:50.417896",
updated_at: "2015-04-24T01:46:50.417906",
uri: "http://api.lobbyfacts.eu/api/1/country/229",
id: 229
}, {
code: "TC",
name: "Turks & Caicos Islands",
created_at: "2015-04-24T01:46:50.414854",
updated_at: "2015-04-24T01:46:50.414868",
uri: "http://api.lobbyfacts.eu/api/1/country/228",
id: 228
}, {
code: "TM",
name: "Turkmenistan",
created_at: "2015-04-24T01:46:50.412601",
updated_at: "2015-04-24T01:46:50.412605",
uri: "http://api.lobbyfacts.eu/api/1/country/227",
id: 227
}, {
code: "TR",
name: "Turkey",
created_at: "2015-04-24T01:46:50.411105",
updated_at: "2015-04-24T01:46:50.411110",
uri: "http://api.lobbyfacts.eu/api/1/country/226",
id: 226
}, {
code: "TN",
name: "Tunisia",
created_at: "2015-04-24T01:46:50.409535",
updated_at: "2015-04-24T01:46:50.409539",
uri: "http://api.lobbyfacts.eu/api/1/country/225",
id: 225
}, {
code: "TT",
name: "Trinidad & Tobago",
created_at: "2015-04-24T01:46:50.408030",
updated_at: "2015-04-24T01:46:50.408034",
uri: "http://api.lobbyfacts.eu/api/1/country/224",
id: 224
}, {
code: "TO",
name: "Tonga",
created_at: "2015-04-24T01:46:50.406306",
updated_at: "2015-04-24T01:46:50.406311",
uri: "http://api.lobbyfacts.eu/api/1/country/223",
id: 223
}, {
code: "TK",
name: "Tokelau",
created_at: "2015-04-24T01:46:50.404794",
updated_at: "2015-04-24T01:46:50.404799",
uri: "http://api.lobbyfacts.eu/api/1/country/222",
id: 222
}, {
code: "TG",
name: "Togo",
created_at: "2015-04-24T01:46:50.403306",
updated_at: "2015-04-24T01:46:50.403310",
uri: "http://api.lobbyfacts.eu/api/1/country/221",
id: 221
}, {
code: "TH",
name: "Thailand",
created_at: "2015-04-24T01:46:50.400840",
updated_at: "2015-04-24T01:46:50.400849",
uri: "http://api.lobbyfacts.eu/api/1/country/220",
id: 220
}, {
code: "TZ",
name: "Tanzania",
created_at: "2015-04-24T01:46:50.397846",
updated_at: "2015-04-24T01:46:50.397855",
uri: "http://api.lobbyfacts.eu/api/1/country/219",
id: 219
}, {
code: "TJ",
name: "Tajikistan",
created_at: "2015-04-24T01:46:50.394924",
updated_at: "2015-04-24T01:46:50.394933",
uri: "http://api.lobbyfacts.eu/api/1/country/218",
id: 218
}, {
code: "TW",
name: "Taiwan",
created_at: "2015-04-24T01:46:50.391969",
updated_at: "2015-04-24T01:46:50.391978",
uri: "http://api.lobbyfacts.eu/api/1/country/217",
id: 217
}, {
code: "SY",
name: "Syria",
created_at: "2015-04-24T01:46:50.389120",
updated_at: "2015-04-24T01:46:50.389124",
uri: "http://api.lobbyfacts.eu/api/1/country/216",
id: 216
}, {
code: "CH",
name: "Switzerland",
created_at: "2015-04-24T01:46:50.386939",
updated_at: "2015-04-24T01:46:50.386943",
uri: "http://api.lobbyfacts.eu/api/1/country/215",
id: 215
}, {
code: "SE",
name: "Sweden",
created_at: "2015-04-24T01:46:50.385345",
updated_at: "2015-04-24T01:46:50.385349",
uri: "http://api.lobbyfacts.eu/api/1/country/214",
id: 214
}, {
code: "SZ",
name: "Swaziland",
created_at: "2015-04-24T01:46:50.383834",
updated_at: "2015-04-24T01:46:50.383838",
uri: "http://api.lobbyfacts.eu/api/1/country/213",
id: 213
}, {
code: "SR",
name: "Suriname",
created_at: "2015-04-24T01:46:50.382073",
updated_at: "2015-04-24T01:46:50.382078",
uri: "http://api.lobbyfacts.eu/api/1/country/212",
id: 212
}, {
code: "SD",
name: "Sudan",
created_at: "2015-04-24T01:46:50.380114",
updated_at: "2015-04-24T01:46:50.380119",
uri: "http://api.lobbyfacts.eu/api/1/country/211",
id: 211
}, {
code: "LK",
name: "Sri Lanka",
created_at: "2015-04-24T01:46:50.378189",
updated_at: "2015-04-24T01:46:50.378195",
uri: "http://api.lobbyfacts.eu/api/1/country/210",
id: 210
}, {
code: "ES",
name: "Spain",
created_at: "2015-04-24T01:46:50.376105",
updated_at: "2015-04-24T01:46:50.376109",
uri: "http://api.lobbyfacts.eu/api/1/country/209",
id: 209
}, {
code: "SS",
name: "South Sudan",
created_at: "2015-04-24T01:46:50.373942",
updated_at: "2015-04-24T01:46:50.373946",
uri: "http://api.lobbyfacts.eu/api/1/country/208",
id: 208
}, {
code: "KR",
name: "South Korea",
created_at: "2015-04-24T01:46:50.371790",
updated_at: "2015-04-24T01:46:50.371794",
uri: "http://api.lobbyfacts.eu/api/1/country/207",
id: 207
}, {
code: "GS",
name: "South Georgia & The South Sandwish Islands",
created_at: "2015-04-24T01:46:50.369460",
updated_at: "2015-04-24T01:46:50.369465",
uri: "http://api.lobbyfacts.eu/api/1/country/206",
id: 206
}, {
code: "ZA",
name: "South Africa",
created_at: "2015-04-24T01:46:50.367247",
updated_at: "2015-04-24T01:46:50.367252",
uri: "http://api.lobbyfacts.eu/api/1/country/205",
id: 205
}, {
code: "SO",
name: "Somaliland",
created_at: "2015-04-24T01:46:50.362905",
updated_at: "2016-09-18T18:34:35.724427",
uri: "http://api.lobbyfacts.eu/api/1/country/204",
id: 204
}, {
code: "SB",
name: "Solomon Islands",
created_at: "2015-04-24T01:46:50.360631",
updated_at: "2015-04-24T01:46:50.360635",
uri: "http://api.lobbyfacts.eu/api/1/country/203",
id: 203
}, {
code: "SI",
name: "Slovenia",
created_at: "2015-04-24T01:46:50.358394",
updated_at: "2015-04-24T01:46:50.358399",
uri: "http://api.lobbyfacts.eu/api/1/country/202",
id: 202
}, {
code: "SK",
name: "Slovakia",
created_at: "2015-04-24T01:46:50.356154",
updated_at: "2015-04-24T01:46:50.356158",
uri: "http://api.lobbyfacts.eu/api/1/country/201",
id: 201
}, {
code: "SX",
name: "Sint Maarten",
created_at: "2015-04-24T01:46:50.353807",
updated_at: "2015-04-24T01:46:50.353811",
uri: "http://api.lobbyfacts.eu/api/1/country/200",
id: 200
}, {
code: "SG",
name: "Singapore",
created_at: "2015-04-24T01:46:50.349354",
updated_at: "2015-04-24T01:46:50.349358",
uri: "http://api.lobbyfacts.eu/api/1/country/199",
id: 199
}, {
code: "SL",
name: "Sierra Leone",
created_at: "2015-04-24T01:46:50.347186",
updated_at: "2015-04-24T01:46:50.347190",
uri: "http://api.lobbyfacts.eu/api/1/country/198",
id: 198
}, {
code: "SC",
name: "Seychelles",
created_at: "2015-04-24T01:46:50.344980",
updated_at: "2015-04-24T01:46:50.344984",
uri: "http://api.lobbyfacts.eu/api/1/country/197",
id: 197
}, {
code: "RS",
name: "Serbia",
created_at: "2015-04-24T01:46:50.342496",
updated_at: "2015-04-24T01:46:50.342501",
uri: "http://api.lobbyfacts.eu/api/1/country/196",
id: 196
}];
}
}

View File

@@ -2,6 +2,7 @@
namespace tests\unit\workflow\engine\src\ProcessMaker\Model;
use ProcessMaker\Model\AdditionalTables;
use ProcessMaker\Model\CaseList;
use Tests\TestCase;
@@ -348,4 +349,108 @@ class CaseListTest extends TestCase
//assert file export
$this->assertFileExists($result['filename']);
}
/**
* This test the formattingColumns method.
* @test
* @covers \ProcessMaker\Model\CaseList::formattingColumns()
*/
public function it_should_test_formattingColumns()
{
$additionalTables = factory(\ProcessMaker\Model\AdditionalTables::class)->create();
$fields = factory(\ProcessMaker\Model\Fields::class, 5)->create([
'ADD_TAB_UID' => $additionalTables->ADD_TAB_UID
]);
factory(CaseList::class)->create([
'CAL_TYPE' => 'inbox',
'ADD_TAB_UID' => $additionalTables->ADD_TAB_UID
]);
factory(CaseList::class)->create([
'CAL_TYPE' => 'draft',
'ADD_TAB_UID' => $additionalTables->ADD_TAB_UID
]);
factory(CaseList::class)->create([
'CAL_TYPE' => 'paused',
'ADD_TAB_UID' => $additionalTables->ADD_TAB_UID
]);
factory(CaseList::class)->create([
'CAL_TYPE' => 'unassigned',
'ADD_TAB_UID' => $additionalTables->ADD_TAB_UID
]);
$columns = [
[
"field" => "case_number",
"enableFilter" => false,
"set" => true
],
[
"field" => "case_title",
"enableFilter" => false,
"set" => true
],
];
$result = CaseList::formattingColumns('inbox', $additionalTables->ADD_TAB_UID, $columns);
$this->assertNotEmpty($result);
$this->assertArrayHasKey('field', $result[0]);
$this->assertArrayHasKey('name', $result[0]);
$this->assertArrayHasKey('type', $result[0]);
$this->assertArrayHasKey('source', $result[0]);
$this->assertArrayHasKey('typeSearch', $result[0]);
$this->assertArrayHasKey('enableFilter', $result[0]);
$this->assertArrayHasKey('set', $result[0]);
$result = CaseList::formattingColumns('draft', $additionalTables->ADD_TAB_UID, $columns);
$this->assertNotEmpty($result);
$this->assertArrayHasKey('field', $result[1]);
$this->assertArrayHasKey('name', $result[1]);
$this->assertArrayHasKey('type', $result[1]);
$this->assertArrayHasKey('source', $result[1]);
$this->assertArrayHasKey('typeSearch', $result[1]);
$this->assertArrayHasKey('enableFilter', $result[1]);
$this->assertArrayHasKey('set', $result[1]);
$result = CaseList::formattingColumns('paused', $additionalTables->ADD_TAB_UID, $columns);
$this->assertNotEmpty($result);
$this->assertArrayHasKey('field', $result[2]);
$this->assertArrayHasKey('name', $result[2]);
$this->assertArrayHasKey('type', $result[2]);
$this->assertArrayHasKey('source', $result[2]);
$this->assertArrayHasKey('typeSearch', $result[2]);
$this->assertArrayHasKey('enableFilter', $result[2]);
$this->assertArrayHasKey('set', $result[2]);
$result = CaseList::formattingColumns('unassigned', $additionalTables->ADD_TAB_UID, $columns);
$this->assertNotEmpty($result);
$this->assertArrayHasKey('field', $result[3]);
$this->assertArrayHasKey('name', $result[3]);
$this->assertArrayHasKey('type', $result[3]);
$this->assertArrayHasKey('source', $result[3]);
$this->assertArrayHasKey('typeSearch', $result[3]);
$this->assertArrayHasKey('enableFilter', $result[3]);
$this->assertArrayHasKey('set', $result[3]);
}
/**
* This test the getReportTables method.
* @test
* @covers \ProcessMaker\Model\CaseList::getReportTables()
*/
public function it_should_test_getReportTables()
{
AdditionalTables::truncate();
$additionalTables = factory(AdditionalTables::class, 10)->create();
$search = '';
$result = CaseList::getReportTables($search);
$this->assertNotEmpty($result);
$this->assertCount(10, $result);
$this->assertArrayHasKey('name', $result[0]);
$this->assertArrayHasKey('description', $result[0]);
$this->assertArrayHasKey('fields', $result[0]);
}
}

View File

@@ -2359,6 +2359,12 @@ msgstr "App Uid"
msgid "Are you sure want to claim the task?"
msgstr "Are you sure want to claim the task?"
# TRANSLATION
# LABEL/ID_ARE_YOU_SURE_DELETE_CUSTOM_CASE_LIST
#: LABEL/ID_ARE_YOU_SURE_DELETE_CUSTOM_CASE_LIST
msgid "Are you sure to delete the Case List {CUSTOM_NAME}, please confirm?"
msgstr "Are you sure to delete the Case List {CUSTOM_NAME}, please confirm?"
# TRANSLATION
# LABEL/ID_ARE_YOU_SURE_RESEND
#: LABEL/ID_ARE_YOU_SURE_RESEND
@@ -6149,6 +6155,12 @@ msgstr "Delete Category"
msgid "Delete the connection?"
msgstr "Delete the connection?"
# TRANSLATION
# LABEL/ID_DELETE_CUSTOM_CASE_LIST
#: LABEL/ID_DELETE_CUSTOM_CASE_LIST
msgid "Delete Custom Case List"
msgstr "Delete Custom Case List"
# TRANSLATION
# LABEL/ID_DELETE_DASHLET_INSTANCE
#: LABEL/ID_DELETE_DASHLET_INSTANCE

View File

@@ -57196,6 +57196,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
( 'LABEL','ID_APP_MSG_BODY','en','Body','2014-01-15') ,
( 'LABEL','ID_APP_UID','en','App Uid','2015-09-15') ,
( 'LABEL','ID_ARE_YOU_SURE_CLAIM_TASK','en','Are you sure want to claim the task?','2021-01-26') ,
( 'LABEL','ID_ARE_YOU_SURE_DELETE_CUSTOM_CASE_LIST','en','Are you sure to delete the Case List {CUSTOM_NAME}, please confirm?','2021-08-05') ,
( 'LABEL','ID_ARE_YOU_SURE_RESEND','en','Are you sure that you want to resend this message','2014-01-15') ,
( 'LABEL','ID_ARE_YOU_SURE_TO_DELETE_ATTRIBUTE_PLEASE_CONFIRM','en','Are you sure to delete the matched attribute "{0}", please confirm?','2020-12-10') ,
( 'LABEL','ID_ARE_YOU_SURE_TO_DELETE_CONNECTION_PLEASE_CONFIRM','en','Are you sure to delete the connection "{0}", please confirm?','2020-12-10') ,
@@ -57851,6 +57852,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE ) VALUES
( 'LABEL','ID_DELETE_CONNECTION','en','Delete the connection?','2014-01-15') ,
( 'LABEL','ID_DELETE_CUSTOM_CASE_LIST','en','Delete Custom Case List','2021-08-05') ,
( 'LABEL','ID_DELETE_DASHLET_INSTANCE','en','Delete Dashlet Instance','2014-10-10') ,
( 'LABEL','ID_DELETE_DATABASES','en','Delete database if it exists','2015-02-23') ,
( 'LABEL','ID_DELETE_DATABASE_CONNECTION','en','Delete Database Connection','2015-02-20') ,

View File

@@ -4,6 +4,7 @@ use Eusebiu\JavaScript\Facades\ScriptVariables;
use Illuminate\Support\Facades\View;
use ProcessMaker\Core\System;
use ProcessMaker\Model\Application;
use ProcessMaker\Model\User;
$conf = new Configurations();
@@ -127,7 +128,6 @@ $oHeadPublisher->assign('urlProxy', $urlProxy); //sending the urlProxy to make
$oHeadPublisher->assign("_nodeId", isset($confDefaultOption) ? $confDefaultOption : "PM_USERS"); //User menu permissions
$oHeadPublisher->assign("FORMATS", $conf->getFormats());
$userCanAccess = 1;
global $translation;
@@ -142,4 +142,5 @@ ScriptVariables::add('SYS_URI', SYS_URI);
ScriptVariables::add('SYS_LANG', SYS_LANG);
ScriptVariables::add('TRANSLATIONS', $translation);
ScriptVariables::add('FORMATS', $conf->getFormats());
ScriptVariables::add('userId', User::getId($_SESSION['USER_LOGGED']));
echo View::make('Views::home.home', compact("userCanAccess"))->render();

View File

@@ -34,6 +34,19 @@ if (isset($_GET['BROWSER_TIME_ZONE_OFFSET'])) {
$caseFields = $case->loadCase($applicationUid, $delIndex);
// Updating case variables with system constants
$systemConstants = G::getSystemConstants();
$caseFields['APP_DATA']['USER_LOGGED'] = $systemConstants['USER_LOGGED'];
$caseFields['APP_DATA']['USR_USERNAME'] = $systemConstants['USR_USERNAME'];
$caseFields['APP_DATA']['SYS_LANG'] = $systemConstants['SYS_LANG'];
$caseFields['APP_DATA']['SYS_SKIN'] = $systemConstants['SYS_SKIN'];
$caseFields['APP_DATA']['SYS_SYS'] = $systemConstants['SYS_SYS'];
$caseFields['APP_DATA']['APPLICATION'] = $caseFields['APP_UID'];
$caseFields['APP_DATA']['PROCESS'] = $caseFields['PRO_UID'];
$caseFields['APP_DATA']['TASK'] = $caseFields['TASK'];
$caseFields['APP_DATA']['INDEX'] = $caseFields['INDEX'];
$case->updateCase($applicationUid, $caseFields);
$criteria = new Criteria();
$criteria->addSelectColumn(DynaformPeer::DYN_CONTENT);
$criteria->addSelectColumn(DynaformPeer::PRO_UID);

View File

@@ -4,6 +4,7 @@ namespace ProcessMaker\Model;
use Exception;
use G;
use ProcessMaker\BusinessModel\Table;
use ProcessMaker\Core\System;
use ProcessMaker\Model\AdditionalTables;
use ProcessMaker\Model\User;
@@ -62,10 +63,17 @@ class CaseList extends Model
'USR_FIRSTNAME' => 'userFirstname',
'USR_LASTNAME' => 'userLastname',
'USR_EMAIL' => 'userEmail',
'USR_POSITION' => 'userPosition',
'ADD_TAB_NAME' => 'tableName',
'PRO_TITLE' => 'process'
];
/**
* Represents the columns exclude from report table.
* @var array
*/
public static $excludeColumns = ['APP_UID', 'APP_NUMBER', 'APP_STATUS'];
/**
* Get column name from alias.
* @param array $array
@@ -187,7 +195,7 @@ class CaseList extends Model
'CASE_LIST.*',
'PROCESS.PRO_TITLE',
'ADDITIONAL_TABLES.ADD_TAB_NAME',
'USERS.USR_UID', 'USERS.USR_USERNAME', 'USERS.USR_FIRSTNAME', 'USERS.USR_LASTNAME', 'USERS.USR_EMAIL'
'USERS.USR_UID', 'USERS.USR_USERNAME', 'USERS.USR_FIRSTNAME', 'USERS.USR_LASTNAME', 'USERS.USR_EMAIL', 'USERS.USR_POSITION'
])
->where(function ($query) use ($search) {
$query
@@ -211,7 +219,10 @@ class CaseList extends Model
$result = CaseList::getAliasFromColumnName($item->toArray());
$result['columns'] = json_decode($result['columns']);
$columns = json_decode($result['columns']);
$columns = CaseList::formattingColumns($result['type'], $result['tableUid'], $columns);
$result['columns'] = $columns;
$result['userAvatar'] = System::getServerMainPath() . '/users/users_ViewPhotoGrid?pUID=' . $result['USR_UID'] . '&h=' . microtime(true);
unset($result['USR_UID']);
@@ -285,4 +296,190 @@ class CaseList extends Model
throw new Exception($e->getMessage());
}
}
/**
* Formatting columns from minimal stored columns configuration in custom cases list.
* @param string $type
* @param string $tableUid
* @param array $storedColumns
* @return array
*/
public static function formattingColumns(string $type = 'inbox', string $tableUid = '', array $storedColumns = [])
{
$default = [
[
'list' => ['inbox', 'draft', 'paused', 'unassigned'],
'field' => 'case_number',
'name' => G::LoadTranslation('ID_MYCASE_NUMBER'),
'type' => 'integer',
'source' => 'APPLICATION',
'typeSearch' => 'integer range',
'enableFilter' => false,
'set' => true
], [
'list' => ['inbox', 'draft', 'paused', 'unassigned'],
'field' => 'case_title',
'name' => G::LoadTranslation('ID_CASE_TITLE'),
'type' => 'string',
'source' => 'APPLICATION',
'typeSearch' => 'search text',
'enableFilter' => false,
'set' => true
], [
'list' => ['inbox', 'draft', 'paused', 'unassigned'],
'field' => 'process_name',
'name' => G::LoadTranslation('ID_PROCESS_NAME'),
'type' => 'string',
'source' => 'APPLICATION',
'typeSearch' => 'search text',
'enableFilter' => false,
'set' => true
], [
'list' => ['inbox', 'draft', 'paused', 'unassigned'],
'field' => 'task',
'name' => G::LoadTranslation('ID_TASK'),
'type' => 'string',
'source' => 'APPLICATION',
'typeSearch' => 'search text',
'enableFilter' => false,
'set' => true
], [
'list' => ['inbox', 'draft', 'paused', 'unassigned'],
'field' => 'send_by',
'name' => G::LoadTranslation('ID_SEND_BY'),
'type' => 'string',
'source' => 'APPLICATION',
'typeSearch' => 'search text',
'enableFilter' => false,
'set' => true
], [
'list' => ['inbox', 'paused', 'unassigned'],
'field' => 'due_date',
'name' => G::LoadTranslation('ID_DUE_DATE'),
'type' => 'date',
'source' => 'APPLICATION',
'typeSearch' => 'date range',
'enableFilter' => false,
'set' => true
], [
'list' => ['inbox', 'paused', 'unassigned'],
'field' => 'delegation_date',
'name' => G::LoadTranslation('ID_DELEGATION_DATE'),
'type' => 'date',
'source' => 'APPLICATION',
'typeSearch' => 'date range',
'enableFilter' => false,
'set' => true
], [
'list' => ['inbox', 'draft', 'paused', 'unassigned'],
'field' => 'priority',
'name' => G::LoadTranslation('ID_PRIORITY'),
'type' => 'string',
'source' => 'APPLICATION',
'typeSearch' => 'option',
'enableFilter' => false,
'set' => true
],
];
//filter by type
$result = [];
foreach ($default as &$column) {
if (in_array($type, $column['list'])) {
unset($column['list']);
$result[] = $column;
}
}
$default = $result;
//get additional tables
$additionalTables = AdditionalTables::where('ADD_TAB_UID', '=', $tableUid)
->where('PRO_UID', '<>', '')
->whereNotNull('PRO_UID')
->get();
$additionalTables->transform(function ($object) {
$table = new Table();
return $table->getTable($object->ADD_TAB_UID, $object->PRO_UID, true, false);
});
$result = $additionalTables->toArray();
if (!empty($result)) {
$result = $result[0];
if (isset($result['fields'])) {
foreach ($result['fields'] as $column) {
if (in_array($column['fld_name'], self::$excludeColumns)) {
continue;
}
$default[] = [
'field' => $column['fld_name'],
'name' => $column['fld_name'],
'type' => $column['fld_type'],
'source' => $result['rep_tab_name'],
'typeSearch' => 'search text',
'enableFilter' => false,
'set' => false
];
}
}
}
//merge with stored information
$result = [];
foreach ($default as &$column) {
foreach ($storedColumns as $storedColumn) {
if (!is_array($storedColumn) || !isset($storedColumn['field'])) {
continue;
}
if ($storedColumn['field'] === $column['field']) {
$column['enableFilter'] = $storedColumn['enableFilter'];
$column['set'] = $storedColumn['set'];
break;
}
}
$result[] = $column;
}
return $result;
}
/**
* Get the report tables, this can filter the results by the search parameter.
* @param string $search
* @return array
*/
public static function getReportTables(string $search = '')
{
$additionalTables = AdditionalTables::where('ADD_TAB_NAME', 'LIKE', "%{$search}%")
->where('PRO_UID', '<>', '')
->whereNotNull('PRO_UID')
->get();
$additionalTables->transform(function ($object) {
$table = new Table();
$result = $table->getTable($object->ADD_TAB_UID, $object->PRO_UID, true, false);
$fields = [];
if (isset($result['fields'])) {
foreach ($result['fields'] as $column) {
if (in_array($column['fld_name'], self::$excludeColumns)) {
continue;
}
$fields[] = [
'field' => $column['fld_name'],
'name' => $column['fld_name'],
'type' => $column['fld_type'],
'source' => $result['rep_tab_name'],
'typeSearch' => 'search text',
'enableFilter' => false,
'set' => false
];
}
}
return [
'name' => $result['rep_tab_name'],
'description' => $result['rep_tab_description'],
'fields' => $fields
];
});
$result = $additionalTables->toArray();
return $result;
}
}

View File

@@ -183,4 +183,40 @@ class CaseList extends Api
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
}
}
/**
* Get default columns associate to custom cases list.
* @url GET /:type/default-columns
* @param string $type
* @access protected
* @class AccessControl {@permission PM_CASES}
* @throws RestException
* @return array
*/
public function doGetDefaultColumns(string $type)
{
try {
return CaseListBusinessModel::formattingColumns($type, '', []);
} catch (Exception $e) {
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
}
}
/**
* Get report tables.
* @url GET /report-tables
* @param string $search
* @access protected
* @class AccessControl {@permission PM_CASES}
* @throws RestException
* @return array
*/
public function doGetReportTables(string $search = '')
{
try {
return CaseListBusinessModel::getReportTables($search);
} catch (Exception $e) {
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
}
}
}

View File

@@ -221,6 +221,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListToDo(
$start = 0,
@@ -265,6 +266,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListToDoPaged(
$start = 0,
@@ -309,6 +311,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListDraft(
$start = 0,
@@ -353,6 +356,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListDraftPaged(
$start = 0,
@@ -397,6 +401,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListParticipated(
$start = 0,
@@ -441,6 +446,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListParticipatedPaged(
$start = 0,
@@ -485,6 +491,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListUnassigned(
$start = 0,
@@ -529,6 +536,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListUnassignedPaged(
$start = 0,
@@ -573,6 +581,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListPaused(
$start = 0,
@@ -617,6 +626,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListPausedPaged(
$start = 0,
@@ -665,6 +675,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListAdvancedSearch(
$start = 0,
@@ -723,6 +734,7 @@ class Cases extends Api
*
* @return array
* @throws Exception
* @deprecated Method deprecated in Release 3.6.x
*/
public function doGetCasesListAdvancedSearchPaged(
$start = 0,

View File

@@ -31,7 +31,7 @@ class Metrics extends Api
/**
* Get total cases per process
*
* @url /process-total-cases
* @url GET /total-cases-by-process
*
* @param string $caseList
* @param int $category
@@ -112,7 +112,7 @@ class Metrics extends Api
/**
* Get total of cases per list
*
* @url /list-total-cases
* @url GET /list-total-cases
*
* @return array
*